summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/cnss/icnss.txt2
-rw-r--r--Documentation/devicetree/bindings/input/touchscreen/gt9xx/gt9xx.txt79
-rw-r--r--Documentation/devicetree/bindings/vendor-prefixes.txt1
-rw-r--r--arch/arm/boot/dts/qcom/msmcobalt-coresight.dtsi10
-rw-r--r--arch/arm/boot/dts/qcom/msmcobalt.dtsi5
-rw-r--r--arch/arm/boot/dts/qcom/msmfalcon-coresight.dtsi194
-rw-r--r--arch/arm/boot/dts/qcom/msmfalcon.dtsi1
-rw-r--r--drivers/char/diag/diagchar_core.c10
-rw-r--r--drivers/char/diag/diagfwd_bridge.c2
-rw-r--r--drivers/clk/msm/clock-gcc-cobalt.c16
-rw-r--r--drivers/clk/msm/clock-mmss-cobalt.c31
-rw-r--r--drivers/clk/msm/vdd-level-cobalt.h18
-rw-r--r--drivers/clk/qcom/gcc-msm8996.c560
-rw-r--r--drivers/crypto/msm/qce50.c38
-rw-r--r--drivers/gpu/msm/kgsl_pool.c14
-rw-r--r--drivers/hwtracing/coresight/coresight-tpda.c6
-rw-r--r--drivers/input/touchscreen/Kconfig12
-rw-r--r--drivers/input/touchscreen/Makefile1
-rw-r--r--drivers/input/touchscreen/gt9xx/gt9xx.c547
-rw-r--r--drivers/input/touchscreen/gt9xx/gt9xx.h25
-rw-r--r--drivers/misc/qcom/qdsp6v2/audio_utils.c15
-rw-r--r--drivers/phy/phy-qcom-ufs-i.h5
-rw-r--r--drivers/phy/phy-qcom-ufs-qmp-v3.c17
-rw-r--r--drivers/phy/phy-qcom-ufs-qmp-v3.h16
-rw-r--r--drivers/phy/phy-qcom-ufs.c18
-rw-r--r--drivers/power/qcom-charger/qpnp-smb2.c6
-rw-r--r--drivers/power/qcom-charger/smb-lib.c35
-rw-r--r--drivers/power/qcom-charger/smb-lib.h5
-rw-r--r--drivers/scsi/ufs/ufs-qcom.c51
-rw-r--r--drivers/scsi/ufs/ufs-qcom.h1
-rw-r--r--drivers/scsi/ufs/ufshcd.c12
-rw-r--r--drivers/slimbus/slim-msm-ngd.c16
-rw-r--r--drivers/soc/qcom/icnss.c805
-rw-r--r--drivers/soc/qcom/memshare/msm_memshare.c2
-rw-r--r--drivers/usb/core/devio.c9
-rw-r--r--drivers/video/fbdev/msm/mdss.h1
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp.c1
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_hwio.h1
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_intf_writeback.c8
-rw-r--r--fs/ext4/crypto.c47
-rw-r--r--fs/ext4/ext4.h6
-rw-r--r--fs/ext4/page-io.c14
-rw-r--r--fs/ext4/readpage.c2
-rw-r--r--include/dt-bindings/clock/msm-clocks-cobalt.h1
-rw-r--r--include/dt-bindings/clock/qcom,gcc-msm8996.h23
-rw-r--r--include/linux/phy/phy-qcom-ufs.h1
-rw-r--r--include/net/rmnet_config.h27
-rw-r--r--include/soc/qcom/icnss.h10
-rw-r--r--include/sound/q6asm-v2.h2
-rw-r--r--net/rmnet_data/rmnet_data_config.c47
-rw-r--r--net/rmnet_data/rmnet_data_config.h6
-rw-r--r--net/rmnet_data/rmnet_data_handlers.c19
-rw-r--r--net/rmnet_data/rmnet_data_stats.c15
-rw-r--r--net/rmnet_data/rmnet_map.h9
-rw-r--r--net/rmnet_data/rmnet_map_command.c7
-rw-r--r--net/rmnet_data/rmnet_map_data.c9
-rw-r--r--sound/soc/codecs/wcd9335.c21
-rw-r--r--sound/soc/msm/qdsp6v2/q6asm.c4
58 files changed, 2319 insertions, 547 deletions
diff --git a/Documentation/devicetree/bindings/cnss/icnss.txt b/Documentation/devicetree/bindings/cnss/icnss.txt
index da5159006a98..505966fb9226 100644
--- a/Documentation/devicetree/bindings/cnss/icnss.txt
+++ b/Documentation/devicetree/bindings/cnss/icnss.txt
@@ -25,6 +25,8 @@ Required properties:
uS.
Optional properties:
+ - qcom,icnss-vadc: VADC handle for vph_pwr read APIs.
+ - qcom,icnss-adc_tm: VADC handle for vph_pwr notification APIs.
Example:
diff --git a/Documentation/devicetree/bindings/input/touchscreen/gt9xx/gt9xx.txt b/Documentation/devicetree/bindings/input/touchscreen/gt9xx/gt9xx.txt
new file mode 100644
index 000000000000..af09840bb053
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/touchscreen/gt9xx/gt9xx.txt
@@ -0,0 +1,79 @@
+Goodix GT9xx series touch controller
+
+The Goodix GT9xx series touch controller is connected to the host processor via
+I2C. The controller generates interrupts when the user touches the panel. The
+host controller is expected to read the touch coordinates over I2C and pass
+the coordinates to the rest of the system.
+
+Required properties:
+
+ - compatible : Should be "goodix,gt9xx"
+ - reg : I2C slave address of the device.
+ - interrupt-parent : Parent of interrupt.
+ - interrupts : Configuration of touch panel controller interrupt
+ GPIO.
+ - goodix,family-id : Family identification of the controller.
+ - interrupt-gpios : Interrupt gpio which is to provide interrupts to
+ host, same as "interrupts" node.
+ - reset-gpios : Reset gpio to control the reset of chip.
+ - goodix,display-coords : Display coordinates in pixels. It is a four
+ tuple consisting of min x, min y, max x and
+ max y values.
+
+Optional properties:
+
+ - avdd-supply : Power supply needed to power up the device, this is
+ for fixed voltage external regulator.
+ - vdd-supply : Power supply needed to power up the device, when use
+ external regulator, do not add this property.
+ - vcc-i2c-supply : Power source required to power up i2c bus.
+ GT9xx series can provide 1.8V from internal
+ LDO, add this properties base on hardware
+ design.
+ - goodix,panel-coords : Panel coordinates for the chip in pixels.
+ It is a four tuple consisting of min x,
+ min y, max x and max y values.
+ - goodix,i2c-pull-up : To specify pull up is required.
+ - goodix,no-force-update : To specify force update is allowed.
+ - goodix,button-map : Button map of key codes. The number of key codes
+ depend on panel.
+ - goodix,cfg-data : Touchpanel controller configuration data, ask vendor
+ to provide that. Default configuration will be
+ used if this property is not present.
+
+Example:
+i2c@f9927000 {
+ goodix@5d {
+ compatible = "goodix,gt9xx";
+ reg = <0x5d>;
+ interrupt-parent = <&msmgpio>;
+ interrupts = <17 0x2008>;
+ reset-gpios = <&msmgpio 16 0x00>;
+ interrupt-gpios = <&msmgpio 17 0x00>;
+ avdd-supply = <&tp_power>;
+ goodix,panel-coords = <0 0 720 1200>;
+ goodix,display-coords = <0 0 720 1080>;
+ goodix,button-map= <158 102 139>;
+ goodix,family-id = <0x0>;
+ goodix,cfg-data = [
+ 41 D0 02 00 05 0A 05 01 01 08
+ 12 58 50 41 03 05 00 00 00 00
+ 00 00 00 00 00 00 00 8C 2E 0E
+ 28 24 73 13 00 00 00 83 03 1D
+ 40 02 00 00 00 03 64 32 00 00
+ 00 1A 38 94 C0 02 00 00 00 04
+ 9E 1C 00 8D 20 00 7A 26 00 6D
+ 2C 00 60 34 00 60 10 38 68 00
+ F0 50 35 FF FF 27 00 00 00 00
+ 00 01 1B 14 0C 14 00 00 01 00
+ 00 00 00 00 00 00 00 00 00 00
+ 00 00 02 04 06 08 0A 0C 0E 10
+ 12 14 16 18 1A 1C FF FF FF FF
+ FF FF FF FF FF FF FF FF FF FF
+ FF FF 00 02 04 06 08 0A 0C 0F
+ 10 12 13 14 16 18 1C 1D 1E 1F
+ 20 21 22 24 26 28 29 2A FF FF
+ FF FF FF FF FF FF FF 22 22 22
+ 22 22 22 FF 07 01];
+ };
+};
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index aca2dd3e4ccb..1d7e54f68ee4 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -87,6 +87,7 @@ firefly Firefly
focaltech FocalTech Systems Co.,Ltd
fsl Freescale Semiconductor
GEFanuc GE Fanuc Intelligent Platforms Embedded Systems, Inc.
+goodix Goodix. Ltd.
gef GE Fanuc Intelligent Platforms Embedded Systems, Inc.
geniatech Geniatech, Inc.
giantplus Giantplus Technology Co., Ltd.
diff --git a/arch/arm/boot/dts/qcom/msmcobalt-coresight.dtsi b/arch/arm/boot/dts/qcom/msmcobalt-coresight.dtsi
index 4afaa3aa51be..aeb6bf6141d8 100644
--- a/arch/arm/boot/dts/qcom/msmcobalt-coresight.dtsi
+++ b/arch/arm/boot/dts/qcom/msmcobalt-coresight.dtsi
@@ -39,10 +39,18 @@
};
replicator: replicator@6046000 {
- compatible = "arm,coresight-replicator";
+ compatible = "arm,primecell";
+ arm,primecell-periphid = <0x0003b909>;
+
+ reg = <0x6046000 0x1000>;
+ reg-names = "replicator-base";
coresight-name = "coresight-replicator";
+ clocks = <&clock_gcc clk_qdss_clk>,
+ <&clock_gcc clk_qdss_a_clk>;
+ clock-names = "apb_pclk", "core_a_clk";
+
ports{
#address-cells = <1>;
#size-cells = <0>;
diff --git a/arch/arm/boot/dts/qcom/msmcobalt.dtsi b/arch/arm/boot/dts/qcom/msmcobalt.dtsi
index 0a3eb6f70644..cd01d5158fc4 100644
--- a/arch/arm/boot/dts/qcom/msmcobalt.dtsi
+++ b/arch/arm/boot/dts/qcom/msmcobalt.dtsi
@@ -745,6 +745,7 @@
reg = <0xc8c0000 0x40000>;
reg-names = "cc_base";
vdd_dig-supply = <&pmcobalt_s1_level>;
+ vdd_mmsscc_mx-supply = <&pmcobalt_s9_level>;
clock-names = "xo", "gpll0", "gpll0_div",
"pclk0_src", "pclk1_src",
"byte0_src", "byte1_src",
@@ -1731,7 +1732,7 @@
"rx_lane0_sync_clk";
clocks =
<&clock_gcc clk_gcc_ufs_axi_hw_ctl_clk>,
- <&clock_gcc clk_gcc_aggre1_ufs_axi_clk>,
+ <&clock_gcc clk_gcc_aggre1_ufs_axi_hw_ctl_clk>,
<&clock_gcc clk_gcc_ufs_ahb_clk>,
<&clock_gcc clk_gcc_ufs_unipro_core_hw_ctl_clk>,
<&clock_gcc clk_gcc_ufs_ice_core_hw_ctl_clk>,
@@ -2866,6 +2867,8 @@
qcom,msm-bus,num-paths = <1>;
qcom,msm-bus,vectors-KBps = <81 10065 0 0>,
<81 10065 0 16000>;
+ qcom,icnss-vadc = <&pmcobalt_vadc>;
+ qcom,icnss-adc_tm = <&pmcobalt_adc_tm>;
};
wil6210: qcom,wil6210 {
diff --git a/arch/arm/boot/dts/qcom/msmfalcon-coresight.dtsi b/arch/arm/boot/dts/qcom/msmfalcon-coresight.dtsi
new file mode 100644
index 000000000000..352856965373
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/msmfalcon-coresight.dtsi
@@ -0,0 +1,194 @@
+/* Copyright (c) 2016, 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 <dt-bindings/clock/qcom,gcc-msmfalcon.h>
+#include <dt-bindings/clock/qcom,gpu-msmfalcon.h>
+#include <dt-bindings/clock/qcom,mmcc-msmfalcon.h>
+
+&soc {
+ tmc_etr: tmc@6048000 {
+ compatible = "arm,primecell";
+ arm,primecell-periphid = <0x0003b961>;
+
+ reg = <0x6048000 0x1000>,
+ <0x6064000 0x15000>;
+ reg-names = "tmc-base", "bam-base";
+
+ arm,buffer-size = <0x400000>;
+ arm,sg-enable;
+
+ coresight-name = "coresight-tmc-etr";
+
+ clocks = <&clock_gcc RPM_QDSS_CLK>,
+ <&clock_gcc RPM_QDSS_A_CLK>;
+ clock-names = "apb_pclk", "core_a_clk";
+
+ port{
+ tmc_etr_in_replicator: endpoint {
+ slave-mode;
+ remote-endpoint = <&replicator_out_tmc_etr>;
+ };
+ };
+ };
+
+ replicator: replicator@6046000 {
+ compatible = "arm,coresight-replicator";
+
+ coresight-name = "coresight-replicator";
+
+ ports{
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ replicator_out_tmc_etr:endpoint {
+ remote-endpoint =
+ <&tmc_etr_in_replicator>;
+ };
+ };
+ port@1 {
+ reg = <0>;
+ replicator_in_tmc_etf:endpoint {
+ slave-mode;
+ remote-endpoint =
+ <&tmc_etf_out_replicator>;
+ };
+ };
+ };
+ };
+
+ tmc_etf: tmc@6047000 {
+ compatible = "arm,primecell";
+ arm,primecell-periphid = <0x0003b961>;
+
+ reg = <0x6047000 0x1000>;
+ reg-names = "tmc-base";
+
+ coresight-name = "coresight-tmc-etf";
+
+ clocks = <&clock_gcc RPM_QDSS_CLK>,
+ <&clock_gcc RPM_QDSS_A_CLK>;
+ clock-names = "apb_pclk", "core_a_clk";
+
+ ports{
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ tmc_etf_out_replicator:endpoint {
+ remote-endpoint =
+ <&replicator_in_tmc_etf>;
+ };
+ };
+ port@1 {
+ reg = <0>;
+ tmc_etf_in_funnel_merg:endpoint {
+ slave-mode;
+ remote-endpoint =
+ <&funnel_merg_out_tmc_etf>;
+ };
+ };
+ };
+ };
+
+ funnel_merg: funnel@6045000 {
+ compatible = "arm,primecell";
+ arm,primecell-periphid = <0x0003b908>;
+
+ reg = <0x6045000 0x1000>;
+ reg-names = "funnel-base";
+
+ coresight-name = "coresight-funnel-merg";
+
+ clocks = <&clock_gcc RPM_QDSS_CLK>,
+ <&clock_gcc RPM_QDSS_A_CLK>;
+ clock-names = "apb_pclk", "core_a_clk";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ funnel_merg_out_tmc_etf:endpoint {
+ remote-endpoint =
+ <&tmc_etf_in_funnel_merg>;
+ };
+ };
+ port@1 {
+ reg = <0>;
+ funnel_merg_in_funnel_in0:endpoint {
+ slave-mode;
+ remote-endpoint =
+ <&funnel_in0_out_funnel_merg>;
+ };
+ };
+ };
+ };
+
+ funnel_in0: funnel@6041000 {
+ compatible = "arm,primecell";
+ arm,primecell-periphid = <0x0003b908>;
+
+ reg = <0x6041000 0x1000>;
+ reg-names = "funnel-base";
+
+ coresight-name = "coresight-funnel-in0";
+
+ clocks = <&clock_gcc RPM_QDSS_CLK>,
+ <&clock_gcc RPM_QDSS_A_CLK>;
+ clock-names = "apb_pclk", "core_a_clk";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ funnel_in0_out_funnel_merg: endpoint {
+ remote-endpoint =
+ <&funnel_merg_in_funnel_in0>;
+ };
+ };
+ port@4 {
+ reg = <7>;
+ funnel_in0_in_stm: endpoint {
+ slave-mode;
+ remote-endpoint = <&stm_out_funnel_in0>;
+ };
+ };
+ };
+ };
+
+ stm: stm@6002000 {
+ compatible = "arm,primecell";
+ arm,primecell-periphid = <0x0003b962>;
+
+ reg = <0x6002000 0x1000>,
+ <0x16280000 0x180000>;
+ reg-names = "stm-base", "stm-data-base";
+
+ coresight-name = "coresight-stm";
+
+ clocks = <&clock_gcc RPM_QDSS_CLK>,
+ <&clock_gcc RPM_QDSS_A_CLK>;
+ clock-names = "apb_pclk", "core_a_clk";
+
+ port{
+ stm_out_funnel_in0: endpoint {
+ remote-endpoint = <&funnel_in0_in_stm>;
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/qcom/msmfalcon.dtsi b/arch/arm/boot/dts/qcom/msmfalcon.dtsi
index 7c4e7f0ee55a..fb97074f35a3 100644
--- a/arch/arm/boot/dts/qcom/msmfalcon.dtsi
+++ b/arch/arm/boot/dts/qcom/msmfalcon.dtsi
@@ -201,6 +201,7 @@
};
#include "msmfalcon-smp2p.dtsi"
+#include "msmfalcon-coresight.dtsi"
&soc {
#address-cells = <1>;
#size-cells = <1>;
diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c
index 9ed43cdc3845..39be6ef3735e 100644
--- a/drivers/char/diag/diagchar_core.c
+++ b/drivers/char/diag/diagchar_core.c
@@ -999,7 +999,7 @@ static int diag_send_raw_data_remote(int proc, void *buf, int len,
(void *)driver->hdlc_encode_buf);
send_data:
- err = diagfwd_bridge_write(proc, driver->hdlc_encode_buf,
+ err = diagfwd_bridge_write(bridge_index, driver->hdlc_encode_buf,
driver->hdlc_encode_buf_len);
if (err) {
pr_err_ratelimited("diag: Error writing Callback packet to proc: %d, err: %d\n",
@@ -2570,7 +2570,7 @@ static int diag_user_process_raw_data(const char __user *buf, int len)
}
}
if (remote_proc) {
- ret = diag_send_raw_data_remote(remote_proc - 1,
+ ret = diag_send_raw_data_remote(remote_proc,
(void *)(user_space_data + token_offset),
len, USER_SPACE_RAW_DATA);
if (ret) {
@@ -3424,13 +3424,13 @@ static int __init diagchar_init(void)
ret = diag_masks_init();
if (ret)
goto fail;
- ret = diag_mux_init();
+ ret = diag_remote_init();
if (ret)
goto fail;
- ret = diagfwd_init();
+ ret = diag_mux_init();
if (ret)
goto fail;
- ret = diag_remote_init();
+ ret = diagfwd_init();
if (ret)
goto fail;
ret = diagfwd_bridge_init();
diff --git a/drivers/char/diag/diagfwd_bridge.c b/drivers/char/diag/diagfwd_bridge.c
index 701677b30a71..0462a64614f3 100644
--- a/drivers/char/diag/diagfwd_bridge.c
+++ b/drivers/char/diag/diagfwd_bridge.c
@@ -107,7 +107,7 @@ static int diagfwd_bridge_mux_write_done(unsigned char *buf, int len,
if (id < 0 || id >= NUM_REMOTE_DEV)
return -EINVAL;
- ch = &bridge_info[id];
+ ch = &bridge_info[buf_ctx];
if (ch->dev_ops && ch->dev_ops->fwd_complete)
ch->dev_ops->fwd_complete(ch->ctxt, buf, len, 0);
return 0;
diff --git a/drivers/clk/msm/clock-gcc-cobalt.c b/drivers/clk/msm/clock-gcc-cobalt.c
index 71c5541d0c0d..05272118af16 100644
--- a/drivers/clk/msm/clock-gcc-cobalt.c
+++ b/drivers/clk/msm/clock-gcc-cobalt.c
@@ -241,8 +241,8 @@ DEFINE_EXT_CLK(gpll4_out_main, &gpll4.c);
static struct clk_freq_tbl ftbl_hmss_ahb_clk_src[] = {
F( 19200000, cxo_clk_src_ao, 1, 0, 0),
- F( 37500000, gpll0_out_main, 16, 0, 0),
- F( 75000000, gpll0_out_main, 8, 0, 0),
+ F( 50000000, gpll0_out_main, 12, 0, 0),
+ F( 100000000, gpll0_out_main, 6, 0, 0),
F_END
};
@@ -1200,6 +1200,17 @@ static struct branch_clk gcc_aggre1_ufs_axi_clk = {
},
};
+static struct hw_ctl_clk gcc_aggre1_ufs_axi_hw_ctl_clk = {
+ .cbcr_reg = GCC_AGGRE1_UFS_AXI_CBCR,
+ .base = &virt_base,
+ .c = {
+ .dbg_name = "gcc_aggre1_ufs_axi_hw_ctl_clk",
+ .parent = &gcc_aggre1_ufs_axi_clk.c,
+ .ops = &clk_ops_branch_hw_ctl,
+ CLK_INIT(gcc_aggre1_ufs_axi_hw_ctl_clk.c),
+ },
+};
+
static struct branch_clk gcc_aggre1_usb3_axi_clk = {
.cbcr_reg = GCC_AGGRE1_USB3_AXI_CBCR,
.has_sibling = 1,
@@ -2597,6 +2608,7 @@ static struct clk_lookup msm_clocks_gcc_cobalt[] = {
CLK_LIST(gcc_qusb2phy_sec_reset),
CLK_LIST(gpll0_out_msscc),
CLK_LIST(gcc_aggre1_ufs_axi_clk),
+ CLK_LIST(gcc_aggre1_ufs_axi_hw_ctl_clk),
CLK_LIST(gcc_aggre1_usb3_axi_clk),
CLK_LIST(gcc_bimc_mss_q6_axi_clk),
CLK_LIST(gcc_blsp1_ahb_clk),
diff --git a/drivers/clk/msm/clock-mmss-cobalt.c b/drivers/clk/msm/clock-mmss-cobalt.c
index fbd83a02aa02..220a8ba377ba 100644
--- a/drivers/clk/msm/clock-mmss-cobalt.c
+++ b/drivers/clk/msm/clock-mmss-cobalt.c
@@ -83,6 +83,7 @@ DEFINE_EXT_CLK(ext_dp_phy_pll_vco, NULL);
DEFINE_EXT_CLK(ext_dp_phy_pll_link, NULL);
static DEFINE_VDD_REGULATORS(vdd_dig, VDD_DIG_NUM, 1, vdd_corner, NULL);
+static DEFINE_VDD_REGULATORS(vdd_mmsscc_mx, VDD_DIG_NUM, 1, vdd_corner, NULL);
static struct alpha_pll_masks pll_masks_p = {
.lock_mask = BIT(31),
@@ -102,7 +103,7 @@ static struct pll_vote_clk mmpll0_pll = {
.parent = &mmsscc_xo.c,
.dbg_name = "mmpll0",
.ops = &clk_ops_pll_vote,
- VDD_DIG_FMAX_MAP2(LOWER, 404000000, NOMINAL, 808000000),
+ VDD_MM_PLL_FMAX_MAP2(LOWER, 404000000, NOMINAL, 808000000),
CLK_INIT(mmpll0_pll.c),
},
};
@@ -119,7 +120,7 @@ static struct pll_vote_clk mmpll1_pll = {
.parent = &mmsscc_xo.c,
.dbg_name = "mmpll1_pll",
.ops = &clk_ops_pll_vote,
- VDD_DIG_FMAX_MAP2(LOWER, 406000000, NOMINAL, 812000000),
+ VDD_MM_PLL_FMAX_MAP2(LOWER, 406000000, NOMINAL, 812000000),
CLK_INIT(mmpll1_pll.c),
},
};
@@ -136,7 +137,7 @@ static struct alpha_pll_clk mmpll3_pll = {
.parent = &mmsscc_xo.c,
.dbg_name = "mmpll3_pll",
.ops = &clk_ops_fixed_fabia_alpha_pll,
- VDD_DIG_FMAX_MAP2(LOWER, 465000000, LOW, 930000000),
+ VDD_MM_PLL_FMAX_MAP2(LOWER, 465000000, LOW, 930000000),
CLK_INIT(mmpll3_pll.c),
},
};
@@ -153,7 +154,7 @@ static struct alpha_pll_clk mmpll4_pll = {
.parent = &mmsscc_xo.c,
.dbg_name = "mmpll4_pll",
.ops = &clk_ops_fixed_fabia_alpha_pll,
- VDD_DIG_FMAX_MAP2(LOWER, 384000000, LOW, 768000000),
+ VDD_MM_PLL_FMAX_MAP2(LOWER, 384000000, LOW, 768000000),
CLK_INIT(mmpll4_pll.c),
},
};
@@ -170,7 +171,7 @@ static struct alpha_pll_clk mmpll5_pll = {
.parent = &mmsscc_xo.c,
.dbg_name = "mmpll5_pll",
.ops = &clk_ops_fixed_fabia_alpha_pll,
- VDD_DIG_FMAX_MAP2(LOWER, 412500000, LOW, 825000000),
+ VDD_MM_PLL_FMAX_MAP2(LOWER, 412500000, LOW, 825000000),
CLK_INIT(mmpll5_pll.c),
},
};
@@ -187,7 +188,7 @@ static struct alpha_pll_clk mmpll6_pll = {
.parent = &mmsscc_xo.c,
.dbg_name = "mmpll6_pll",
.ops = &clk_ops_fixed_fabia_alpha_pll,
- VDD_DIG_FMAX_MAP2(LOWER, 360000000, NOMINAL, 720000000),
+ VDD_MM_PLL_FMAX_MAP2(LOWER, 360000000, NOMINAL, 720000000),
CLK_INIT(mmpll6_pll.c),
},
};
@@ -204,7 +205,7 @@ static struct alpha_pll_clk mmpll7_pll = {
.parent = &mmsscc_xo.c,
.dbg_name = "mmpll7_pll",
.ops = &clk_ops_fixed_fabia_alpha_pll,
- VDD_DIG_FMAX_MAP2(LOWER, 480000000, NOMINAL, 960000000),
+ VDD_MM_PLL_FMAX_MAP1(LOW, 960000000),
CLK_INIT(mmpll7_pll.c),
},
};
@@ -221,7 +222,7 @@ static struct alpha_pll_clk mmpll10_pll = {
.parent = &mmsscc_xo.c,
.dbg_name = "mmpll10_pll",
.ops = &clk_ops_fixed_fabia_alpha_pll,
- VDD_DIG_FMAX_MAP2(LOWER, 288000000, NOMINAL, 576000000),
+ VDD_MM_PLL_FMAX_MAP2(LOWER, 288000000, NOMINAL, 576000000),
CLK_INIT(mmpll10_pll.c),
},
};
@@ -2626,7 +2627,6 @@ static struct clk_lookup msm_clocks_mmss_cobalt[] = {
CLK_LIST(mmss_misc_ahb_clk),
CLK_LIST(mmss_misc_cxo_clk),
CLK_LIST(mmss_mnoc_ahb_clk),
- CLK_LIST(mmss_mnoc_maxi_clk),
CLK_LIST(mmss_video_subcore0_clk),
CLK_LIST(mmss_video_subcore1_clk),
CLK_LIST(mmss_video_ahb_clk),
@@ -2635,6 +2635,7 @@ static struct clk_lookup msm_clocks_mmss_cobalt[] = {
CLK_LIST(mmss_video_maxi_clk),
CLK_LIST(mmss_vmem_ahb_clk),
CLK_LIST(mmss_vmem_maxi_clk),
+ CLK_LIST(mmss_mnoc_maxi_clk),
CLK_LIST(mmss_debug_mux),
};
@@ -2745,10 +2746,6 @@ static void msm_mmsscc_v2_fixup(void)
csiphy_clk_src.c.fmax[VDD_DIG_LOW] = 256000000;
dp_pixel_clk_src.c.fmax[VDD_DIG_LOWER] = 148380000;
-
- video_subcore0_clk_src.c.fmax[VDD_DIG_LOW_L1] = 355200000;
- video_subcore1_clk_src.c.fmax[VDD_DIG_LOW_L1] = 355200000;
- video_core_clk_src.c.fmax[VDD_DIG_LOW_L1] = 355200000;
}
int msm_mmsscc_cobalt_probe(struct platform_device *pdev)
@@ -2783,6 +2780,14 @@ int msm_mmsscc_cobalt_probe(struct platform_device *pdev)
return PTR_ERR(reg);
}
+ reg = vdd_mmsscc_mx.regulator[0] = devm_regulator_get(&pdev->dev,
+ "vdd_mmsscc_mx");
+ if (IS_ERR(reg)) {
+ if (PTR_ERR(reg) != -EPROBE_DEFER)
+ dev_err(&pdev->dev, "Unable to get vdd_mmsscc_mx regulator!");
+ return PTR_ERR(reg);
+ }
+
tmp = mmsscc_xo.c.parent = devm_clk_get(&pdev->dev, "xo");
if (IS_ERR(tmp)) {
if (PTR_ERR(tmp) != -EPROBE_DEFER)
diff --git a/drivers/clk/msm/vdd-level-cobalt.h b/drivers/clk/msm/vdd-level-cobalt.h
index f847a4104d4d..c1897b7da7f7 100644
--- a/drivers/clk/msm/vdd-level-cobalt.h
+++ b/drivers/clk/msm/vdd-level-cobalt.h
@@ -24,6 +24,7 @@
[VDD_DIG_##l1] = (f1), \
}, \
.num_fmax = VDD_DIG_NUM
+
#define VDD_DIG_FMAX_MAP2(l1, f1, l2, f2) \
.vdd_class = &vdd_dig, \
.fmax = (unsigned long[VDD_DIG_NUM]) { \
@@ -40,6 +41,7 @@
[VDD_DIG_##l3] = (f3), \
}, \
.num_fmax = VDD_DIG_NUM
+
#define VDD_DIG_FMAX_MAP4(l1, f1, l2, f2, l3, f3, l4, f4) \
.vdd_class = &vdd_dig, \
.fmax = (unsigned long[VDD_DIG_NUM]) { \
@@ -66,6 +68,22 @@
}, \
.num_fmax = VDD_DIG_NUM
+#define VDD_MM_PLL_FMAX_MAP1(l1, f1) \
+ .vdd_class = &vdd_mmsscc_mx, \
+ .fmax = (unsigned long[VDD_DIG_NUM]) { \
+ [VDD_DIG_##l1] = (f1), \
+ }, \
+ .num_fmax = VDD_DIG_NUM
+
+#define VDD_MM_PLL_FMAX_MAP2(l1, f1, l2, f2) \
+ .vdd_class = &vdd_mmsscc_mx, \
+ .fmax = (unsigned long[VDD_DIG_NUM]) { \
+ [VDD_DIG_##l1] = (f1), \
+ [VDD_DIG_##l2] = (f2), \
+ }, \
+ .num_fmax = VDD_DIG_NUM
+
+
#define VDD_GPU_PLL_FMAX_MAP1(l1, f1) \
.vdd_class = &vdd_gpucc_mx, \
.fmax = (unsigned long[VDD_DIG_NUM]) { \
diff --git a/drivers/clk/qcom/gcc-msm8996.c b/drivers/clk/qcom/gcc-msm8996.c
index a63680290219..a7b8ac07e73a 100644
--- a/drivers/clk/qcom/gcc-msm8996.c
+++ b/drivers/clk/qcom/gcc-msm8996.c
@@ -21,6 +21,7 @@
#include <linux/clk-provider.h>
#include <linux/regmap.h>
#include <linux/reset-controller.h>
+#include <linux/clk.h>
#include <dt-bindings/clock/qcom,gcc-msm8996.h>
@@ -30,7 +31,6 @@
#include "clk-rcg.h"
#include "clk-branch.h"
#include "reset.h"
-#include "gdsc.h"
#define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) }
@@ -48,14 +48,6 @@ enum {
P_GPLL1_EARLY_DIV
};
-static const struct parent_map gcc_sleep_clk_map[] = {
- { P_SLEEP_CLK, 5 }
-};
-
-static const char * const gcc_sleep_clk[] = {
- "sleep_clk"
-};
-
static const struct parent_map gcc_xo_gpll0_map[] = {
{ P_XO, 0 },
{ P_GPLL0, 1 }
@@ -284,71 +276,6 @@ static struct clk_alpha_pll_postdiv gpll4 = {
},
};
-static const struct freq_tbl ftbl_system_noc_clk_src[] = {
- F(19200000, P_XO, 1, 0, 0),
- F(50000000, P_GPLL0_EARLY_DIV, 6, 0, 0),
- F(100000000, P_GPLL0, 6, 0, 0),
- F(150000000, P_GPLL0, 4, 0, 0),
- F(200000000, P_GPLL0, 3, 0, 0),
- F(240000000, P_GPLL0, 2.5, 0, 0),
- { }
-};
-
-static struct clk_rcg2 system_noc_clk_src = {
- .cmd_rcgr = 0x0401c,
- .hid_width = 5,
- .parent_map = gcc_xo_gpll0_gpll2_gpll3_gpll1_gpll2_early_gpll0_early_div_map,
- .freq_tbl = ftbl_system_noc_clk_src,
- .clkr.hw.init = &(struct clk_init_data){
- .name = "system_noc_clk_src",
- .parent_names = gcc_xo_gpll0_gpll2_gpll3_gpll1_gpll2_early_gpll0_early_div,
- .num_parents = 7,
- .ops = &clk_rcg2_ops,
- },
-};
-
-static const struct freq_tbl ftbl_config_noc_clk_src[] = {
- F(19200000, P_XO, 1, 0, 0),
- F(37500000, P_GPLL0, 16, 0, 0),
- F(75000000, P_GPLL0, 8, 0, 0),
- { }
-};
-
-static struct clk_rcg2 config_noc_clk_src = {
- .cmd_rcgr = 0x0500c,
- .hid_width = 5,
- .parent_map = gcc_xo_gpll0_map,
- .freq_tbl = ftbl_config_noc_clk_src,
- .clkr.hw.init = &(struct clk_init_data){
- .name = "config_noc_clk_src",
- .parent_names = gcc_xo_gpll0,
- .num_parents = 2,
- .ops = &clk_rcg2_ops,
- },
-};
-
-static const struct freq_tbl ftbl_periph_noc_clk_src[] = {
- F(19200000, P_XO, 1, 0, 0),
- F(37500000, P_GPLL0, 16, 0, 0),
- F(50000000, P_GPLL0, 12, 0, 0),
- F(75000000, P_GPLL0, 8, 0, 0),
- F(100000000, P_GPLL0, 6, 0, 0),
- { }
-};
-
-static struct clk_rcg2 periph_noc_clk_src = {
- .cmd_rcgr = 0x06014,
- .hid_width = 5,
- .parent_map = gcc_xo_gpll0_map,
- .freq_tbl = ftbl_periph_noc_clk_src,
- .clkr.hw.init = &(struct clk_init_data){
- .name = "periph_noc_clk_src",
- .parent_names = gcc_xo_gpll0,
- .num_parents = 2,
- .ops = &clk_rcg2_ops,
- },
-};
-
static const struct freq_tbl ftbl_usb30_master_clk_src[] = {
F(19200000, P_XO, 1, 0, 0),
F(120000000, P_GPLL0, 5, 0, 0),
@@ -464,10 +391,18 @@ static struct clk_rcg2 sdcc1_apps_clk_src = {
},
};
+static struct freq_tbl ftbl_sdcc1_ice_core_clk_src[] = {
+ F(19200000, P_XO, 1, 0, 0),
+ F(150000000, P_GPLL0, 4, 0, 0),
+ F(300000000, P_GPLL0, 2, 0, 0),
+ { }
+};
+
static struct clk_rcg2 sdcc1_ice_core_clk_src = {
.cmd_rcgr = 0x13024,
.hid_width = 5,
.parent_map = gcc_xo_gpll0_gpll4_gpll0_early_div_map,
+ .freq_tbl = ftbl_sdcc1_ice_core_clk_src,
.clkr.hw.init = &(struct clk_init_data){
.name = "sdcc1_ice_core_clk_src",
.parent_names = gcc_xo_gpll0_gpll4_gpll0_early_div,
@@ -1104,18 +1039,6 @@ static struct clk_rcg2 tsif_ref_clk_src = {
},
};
-static struct clk_rcg2 gcc_sleep_clk_src = {
- .cmd_rcgr = 0x43014,
- .hid_width = 5,
- .parent_map = gcc_sleep_clk_map,
- .clkr.hw.init = &(struct clk_init_data){
- .name = "gcc_sleep_clk_src",
- .parent_names = gcc_sleep_clk,
- .num_parents = 1,
- .ops = &clk_rcg2_ops,
- },
-};
-
static struct clk_rcg2 hmss_rbcpr_clk_src = {
.cmd_rcgr = 0x48040,
.hid_width = 5,
@@ -1230,10 +1153,18 @@ static struct clk_rcg2 ufs_axi_clk_src = {
},
};
+static const struct freq_tbl ftbl_ufs_ice_core_clk_src[] = {
+ F(19200000, P_XO, 1, 0, 0),
+ F(150000000, P_GPLL0, 4, 0, 0),
+ F(300000000, P_GPLL0, 2, 0, 0),
+ { }
+};
+
static struct clk_rcg2 ufs_ice_core_clk_src = {
.cmd_rcgr = 0x76014,
.hid_width = 5,
.parent_map = gcc_xo_gpll0_map,
+ .freq_tbl = ftbl_ufs_ice_core_clk_src,
.clkr.hw.init = &(struct clk_init_data){
.name = "ufs_ice_core_clk_src",
.parent_names = gcc_xo_gpll0,
@@ -1242,10 +1173,19 @@ static struct clk_rcg2 ufs_ice_core_clk_src = {
},
};
+static const struct freq_tbl ftbl_qspi_ser_clk_src[] = {
+ F(75000000, P_GPLL0, 8, 0, 0),
+ F(150000000, P_GPLL0, 4, 0, 0),
+ F(256000000, P_GPLL4, 1.5, 0, 0),
+ F(300000000, P_GPLL0, 2, 0, 0),
+ { }
+};
+
static struct clk_rcg2 qspi_ser_clk_src = {
.cmd_rcgr = 0x8b00c,
.hid_width = 5,
.parent_map = gcc_xo_gpll0_gpll1_early_div_gpll1_gpll4_gpll0_early_div_map,
+ .freq_tbl = ftbl_qspi_ser_clk_src,
.clkr.hw.init = &(struct clk_init_data){
.name = "qspi_ser_clk_src",
.parent_names = gcc_xo_gpll0_gpll1_early_div_gpll1_gpll4_gpll0_early_div,
@@ -1306,9 +1246,6 @@ static struct clk_branch gcc_mmss_noc_cfg_ahb_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_mmss_noc_cfg_ahb_clk",
- .parent_names = (const char *[]){ "config_noc_clk_src" },
- .num_parents = 1,
- .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
.ops = &clk_branch2_ops,
},
},
@@ -1316,12 +1253,12 @@ static struct clk_branch gcc_mmss_noc_cfg_ahb_clk = {
static struct clk_branch gcc_mmss_bimc_gfx_clk = {
.halt_reg = 0x9010,
+ .halt_check = BRANCH_HALT_NO_CHECK_ON_DISABLE,
.clkr = {
.enable_reg = 0x9010,
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_mmss_bimc_gfx_clk",
- .flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops,
},
},
@@ -1349,9 +1286,6 @@ static struct clk_branch gcc_usb30_sleep_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_usb30_sleep_clk",
- .parent_names = (const char *[]){ "gcc_sleep_clk_src" },
- .num_parents = 1,
- .flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops,
},
},
@@ -1387,17 +1321,26 @@ static struct clk_branch gcc_usb3_phy_aux_clk = {
},
};
-static struct clk_branch gcc_usb3_phy_pipe_clk = {
- .halt_reg = 0x50004,
+static struct clk_gate2 gcc_usb3_phy_pipe_clk = {
+ .udelay = 50,
.clkr = {
.enable_reg = 0x50004,
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_usb3_phy_pipe_clk",
- .parent_names = (const char *[]){ "usb3_phy_pipe_clk_src" },
- .num_parents = 1,
- .flags = CLK_SET_RATE_PARENT,
- .ops = &clk_branch2_ops,
+ .ops = &clk_gate2_ops,
+ },
+ },
+};
+
+static struct clk_gate2 gpll0_out_msscc = {
+ .udelay = 1,
+ .clkr = {
+ .enable_reg = 0x5200c,
+ .enable_mask = BIT(2),
+ .hw.init = &(struct clk_init_data){
+ .name = "gpll0_out_msscc",
+ .ops = &clk_gate2_ops,
},
},
};
@@ -1424,9 +1367,6 @@ static struct clk_branch gcc_usb20_sleep_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_usb20_sleep_clk",
- .parent_names = (const char *[]){ "gcc_sleep_clk_src" },
- .num_parents = 1,
- .flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops,
},
},
@@ -1454,9 +1394,6 @@ static struct clk_branch gcc_usb_phy_cfg_ahb2phy_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_usb_phy_cfg_ahb2phy_clk",
- .parent_names = (const char *[]){ "periph_noc_clk_src" },
- .num_parents = 1,
- .flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops,
},
},
@@ -1484,9 +1421,6 @@ static struct clk_branch gcc_sdcc1_ahb_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_sdcc1_ahb_clk",
- .parent_names = (const char *[]){ "periph_noc_clk_src" },
- .num_parents = 1,
- .flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops,
},
},
@@ -1529,9 +1463,6 @@ static struct clk_branch gcc_sdcc2_ahb_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_sdcc2_ahb_clk",
- .parent_names = (const char *[]){ "periph_noc_clk_src" },
- .num_parents = 1,
- .flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops,
},
},
@@ -1559,9 +1490,6 @@ static struct clk_branch gcc_sdcc3_ahb_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_sdcc3_ahb_clk",
- .parent_names = (const char *[]){ "periph_noc_clk_src" },
- .num_parents = 1,
- .flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops,
},
},
@@ -1589,9 +1517,6 @@ static struct clk_branch gcc_sdcc4_ahb_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_sdcc4_ahb_clk",
- .parent_names = (const char *[]){ "periph_noc_clk_src" },
- .num_parents = 1,
- .flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops,
},
},
@@ -1605,9 +1530,6 @@ static struct clk_branch gcc_blsp1_ahb_clk = {
.enable_mask = BIT(17),
.hw.init = &(struct clk_init_data){
.name = "gcc_blsp1_ahb_clk",
- .parent_names = (const char *[]){ "periph_noc_clk_src" },
- .num_parents = 1,
- .flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops,
},
},
@@ -1621,9 +1543,6 @@ static struct clk_branch gcc_blsp1_sleep_clk = {
.enable_mask = BIT(16),
.hw.init = &(struct clk_init_data){
.name = "gcc_blsp1_sleep_clk",
- .parent_names = (const char *[]){ "gcc_sleep_clk_src" },
- .num_parents = 1,
- .flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops,
},
},
@@ -1907,9 +1826,6 @@ static struct clk_branch gcc_blsp2_ahb_clk = {
.enable_mask = BIT(15),
.hw.init = &(struct clk_init_data){
.name = "gcc_blsp2_ahb_clk",
- .parent_names = (const char *[]){ "periph_noc_clk_src" },
- .num_parents = 1,
- .flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops,
},
},
@@ -1923,9 +1839,6 @@ static struct clk_branch gcc_blsp2_sleep_clk = {
.enable_mask = BIT(14),
.hw.init = &(struct clk_init_data){
.name = "gcc_blsp2_sleep_clk",
- .parent_names = (const char *[]){ "gcc_sleep_clk_src" },
- .num_parents = 1,
- .flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops,
},
},
@@ -2208,9 +2121,6 @@ static struct clk_branch gcc_pdm_ahb_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_pdm_ahb_clk",
- .parent_names = (const char *[]){ "periph_noc_clk_src" },
- .num_parents = 1,
- .flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops,
},
},
@@ -2239,9 +2149,6 @@ static struct clk_branch gcc_prng_ahb_clk = {
.enable_mask = BIT(13),
.hw.init = &(struct clk_init_data){
.name = "gcc_prng_ahb_clk",
- .parent_names = (const char *[]){ "config_noc_clk_src" },
- .num_parents = 1,
- .flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops,
},
},
@@ -2254,9 +2161,6 @@ static struct clk_branch gcc_tsif_ahb_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_tsif_ahb_clk",
- .parent_names = (const char *[]){ "periph_noc_clk_src" },
- .num_parents = 1,
- .flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops,
},
},
@@ -2277,21 +2181,6 @@ static struct clk_branch gcc_tsif_ref_clk = {
},
};
-static struct clk_branch gcc_tsif_inactivity_timers_clk = {
- .halt_reg = 0x3600c,
- .clkr = {
- .enable_reg = 0x3600c,
- .enable_mask = BIT(0),
- .hw.init = &(struct clk_init_data){
- .name = "gcc_tsif_inactivity_timers_clk",
- .parent_names = (const char *[]){ "gcc_sleep_clk_src" },
- .num_parents = 1,
- .flags = CLK_SET_RATE_PARENT,
- .ops = &clk_branch2_ops,
- },
- },
-};
-
static struct clk_branch gcc_boot_rom_ahb_clk = {
.halt_reg = 0x38004,
.halt_check = BRANCH_HALT_VOTED,
@@ -2300,9 +2189,6 @@ static struct clk_branch gcc_boot_rom_ahb_clk = {
.enable_mask = BIT(10),
.hw.init = &(struct clk_init_data){
.name = "gcc_boot_rom_ahb_clk",
- .parent_names = (const char *[]){ "config_noc_clk_src" },
- .num_parents = 1,
- .flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops,
},
},
@@ -2315,7 +2201,6 @@ static struct clk_branch gcc_bimc_gfx_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_bimc_gfx_clk",
- .flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops,
},
},
@@ -2388,9 +2273,6 @@ static struct clk_branch gcc_pcie_0_slv_axi_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_pcie_0_slv_axi_clk",
- .parent_names = (const char *[]){ "system_noc_clk_src" },
- .num_parents = 1,
- .flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops,
},
},
@@ -2403,9 +2285,6 @@ static struct clk_branch gcc_pcie_0_mstr_axi_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_pcie_0_mstr_axi_clk",
- .parent_names = (const char *[]){ "system_noc_clk_src" },
- .num_parents = 1,
- .flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops,
},
},
@@ -2418,9 +2297,6 @@ static struct clk_branch gcc_pcie_0_cfg_ahb_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_pcie_0_cfg_ahb_clk",
- .parent_names = (const char *[]){ "config_noc_clk_src" },
- .num_parents = 1,
- .flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops,
},
},
@@ -2441,17 +2317,14 @@ static struct clk_branch gcc_pcie_0_aux_clk = {
},
};
-static struct clk_branch gcc_pcie_0_pipe_clk = {
- .halt_reg = 0x6b018,
+static struct clk_gate2 gcc_pcie_0_pipe_clk = {
+ .udelay = 500,
.clkr = {
.enable_reg = 0x6b018,
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_pcie_0_pipe_clk",
- .parent_names = (const char *[]){ "pcie_0_pipe_clk_src" },
- .num_parents = 1,
- .flags = CLK_SET_RATE_PARENT,
- .ops = &clk_branch2_ops,
+ .ops = &clk_gate2_ops,
},
},
};
@@ -2463,9 +2336,6 @@ static struct clk_branch gcc_pcie_1_slv_axi_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_pcie_1_slv_axi_clk",
- .parent_names = (const char *[]){ "system_noc_clk_src" },
- .num_parents = 1,
- .flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops,
},
},
@@ -2478,9 +2348,6 @@ static struct clk_branch gcc_pcie_1_mstr_axi_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_pcie_1_mstr_axi_clk",
- .parent_names = (const char *[]){ "system_noc_clk_src" },
- .num_parents = 1,
- .flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops,
},
},
@@ -2493,9 +2360,6 @@ static struct clk_branch gcc_pcie_1_cfg_ahb_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_pcie_1_cfg_ahb_clk",
- .parent_names = (const char *[]){ "config_noc_clk_src" },
- .num_parents = 1,
- .flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops,
},
},
@@ -2516,17 +2380,14 @@ static struct clk_branch gcc_pcie_1_aux_clk = {
},
};
-static struct clk_branch gcc_pcie_1_pipe_clk = {
- .halt_reg = 0x6d018,
+static struct clk_gate2 gcc_pcie_1_pipe_clk = {
+ .udelay = 500,
.clkr = {
.enable_reg = 0x6d018,
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_pcie_1_pipe_clk",
- .parent_names = (const char *[]){ "pcie_1_pipe_clk_src" },
- .num_parents = 1,
- .flags = CLK_SET_RATE_PARENT,
- .ops = &clk_branch2_ops,
+ .ops = &clk_gate2_ops,
},
},
};
@@ -2538,9 +2399,6 @@ static struct clk_branch gcc_pcie_2_slv_axi_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_pcie_2_slv_axi_clk",
- .parent_names = (const char *[]){ "system_noc_clk_src" },
- .num_parents = 1,
- .flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops,
},
},
@@ -2553,9 +2411,6 @@ static struct clk_branch gcc_pcie_2_mstr_axi_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_pcie_2_mstr_axi_clk",
- .parent_names = (const char *[]){ "system_noc_clk_src" },
- .num_parents = 1,
- .flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops,
},
},
@@ -2568,9 +2423,6 @@ static struct clk_branch gcc_pcie_2_cfg_ahb_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_pcie_2_cfg_ahb_clk",
- .parent_names = (const char *[]){ "config_noc_clk_src" },
- .num_parents = 1,
- .flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops,
},
},
@@ -2591,17 +2443,14 @@ static struct clk_branch gcc_pcie_2_aux_clk = {
},
};
-static struct clk_branch gcc_pcie_2_pipe_clk = {
- .halt_reg = 0x6e108,
+static struct clk_gate2 gcc_pcie_2_pipe_clk = {
+ .udelay = 500,
.clkr = {
- .enable_reg = 0x6e108,
+ .enable_reg = 0x6e018,
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_pcie_2_pipe_clk",
- .parent_names = (const char *[]){ "pcie_2_pipe_clk_src" },
- .num_parents = 1,
- .flags = CLK_SET_RATE_PARENT,
- .ops = &clk_branch2_ops,
+ .ops = &clk_gate2_ops,
},
},
};
@@ -2613,9 +2462,6 @@ static struct clk_branch gcc_pcie_phy_cfg_ahb_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_pcie_phy_cfg_ahb_clk",
- .parent_names = (const char *[]){ "config_noc_clk_src" },
- .num_parents = 1,
- .flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops,
},
},
@@ -2658,9 +2504,6 @@ static struct clk_branch gcc_ufs_ahb_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_ufs_ahb_clk",
- .parent_names = (const char *[]){ "config_noc_clk_src" },
- .num_parents = 1,
- .flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops,
},
},
@@ -2720,47 +2563,39 @@ static struct clk_branch gcc_ufs_rx_cfg_clk = {
},
};
-static struct clk_branch gcc_ufs_tx_symbol_0_clk = {
- .halt_reg = 0x75018,
+static struct clk_gate2 gcc_ufs_tx_symbol_0_clk = {
+ .udelay = 500,
.clkr = {
.enable_reg = 0x75018,
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_ufs_tx_symbol_0_clk",
- .parent_names = (const char *[]){ "ufs_tx_symbol_0_clk_src" },
- .num_parents = 1,
- .flags = CLK_SET_RATE_PARENT,
- .ops = &clk_branch2_ops,
+ .ops = &clk_gate2_ops,
},
},
};
-static struct clk_branch gcc_ufs_rx_symbol_0_clk = {
- .halt_reg = 0x7501c,
+static struct clk_gate2 gcc_ufs_rx_symbol_0_clk = {
+ .udelay = 500,
.clkr = {
.enable_reg = 0x7501c,
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_ufs_rx_symbol_0_clk",
- .parent_names = (const char *[]){ "ufs_rx_symbol_0_clk_src" },
- .num_parents = 1,
- .flags = CLK_SET_RATE_PARENT,
- .ops = &clk_branch2_ops,
+ .ops = &clk_gate2_ops,
},
},
};
-static struct clk_branch gcc_ufs_rx_symbol_1_clk = {
- .halt_reg = 0x75020,
+static struct clk_gate2 gcc_ufs_rx_symbol_1_clk = {
+ .udelay = 500,
.clkr = {
.enable_reg = 0x75020,
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_ufs_rx_symbol_1_clk",
- .parent_names = (const char *[]){ "ufs_rx_symbol_1_clk_src" },
- .num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
- .ops = &clk_branch2_ops,
+ .ops = &clk_gate2_ops,
},
},
};
@@ -2807,26 +2642,26 @@ static struct clk_branch gcc_ufs_ice_core_clk = {
},
};
-static struct clk_branch gcc_ufs_sys_clk_core_clk = {
- .halt_check = BRANCH_HALT_DELAY,
+static struct clk_gate2 gcc_ufs_sys_clk_core_clk = {
+ .udelay = 500,
.clkr = {
.enable_reg = 0x76030,
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_ufs_sys_clk_core_clk",
- .ops = &clk_branch2_ops,
+ .ops = &clk_gate2_ops,
},
},
};
-static struct clk_branch gcc_ufs_tx_symbol_clk_core_clk = {
- .halt_check = BRANCH_HALT_DELAY,
+static struct clk_gate2 gcc_ufs_tx_symbol_clk_core_clk = {
+ .udelay = 500,
.clkr = {
.enable_reg = 0x76034,
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_ufs_tx_symbol_clk_core_clk",
- .ops = &clk_branch2_ops,
+ .ops = &clk_gate2_ops,
},
},
};
@@ -2838,9 +2673,6 @@ static struct clk_branch gcc_aggre0_snoc_axi_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_aggre0_snoc_axi_clk",
- .parent_names = (const char *[]){ "system_noc_clk_src" },
- .num_parents = 1,
- .flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops,
},
},
@@ -2853,9 +2685,6 @@ static struct clk_branch gcc_aggre0_cnoc_ahb_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_aggre0_cnoc_ahb_clk",
- .parent_names = (const char *[]){ "config_noc_clk_src" },
- .num_parents = 1,
- .flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops,
},
},
@@ -2863,29 +2692,37 @@ static struct clk_branch gcc_aggre0_cnoc_ahb_clk = {
static struct clk_branch gcc_smmu_aggre0_axi_clk = {
.halt_reg = 0x81014,
+ .halt_check = BRANCH_HALT_NO_CHECK_ON_DISABLE,
.clkr = {
.enable_reg = 0x81014,
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_smmu_aggre0_axi_clk",
- .parent_names = (const char *[]){ "system_noc_clk_src" },
- .num_parents = 1,
- .flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops,
},
},
};
+static struct clk_gate2 gcc_aggre0_noc_qosgen_extref_clk = {
+ .udelay = 500,
+ .clkr = {
+ .enable_reg = 0x8101c,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_aggre0_noc_qosgen_extref_clk",
+ .ops = &clk_gate2_ops,
+ },
+ },
+};
+
static struct clk_branch gcc_smmu_aggre0_ahb_clk = {
.halt_reg = 0x81018,
+ .halt_check = BRANCH_HALT_NO_CHECK_ON_DISABLE,
.clkr = {
.enable_reg = 0x81018,
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_smmu_aggre0_ahb_clk",
- .parent_names = (const char *[]){ "config_noc_clk_src" },
- .num_parents = 1,
- .flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops,
},
},
@@ -2898,9 +2735,6 @@ static struct clk_branch gcc_aggre1_pnoc_ahb_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_aggre1_pnoc_ahb_clk",
- .parent_names = (const char *[]){ "periph_noc_clk_src" },
- .num_parents = 1,
- .flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops,
},
},
@@ -2943,9 +2777,6 @@ static struct clk_branch gcc_qspi_ahb_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_qspi_ahb_clk",
- .parent_names = (const char *[]){ "periph_noc_clk_src" },
- .num_parents = 1,
- .flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops,
},
},
@@ -2973,8 +2804,6 @@ static struct clk_branch gcc_usb3_clkref_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_usb3_clkref_clk",
- .parent_names = (const char *[]){ "xo" },
- .num_parents = 1,
.ops = &clk_branch2_ops,
},
},
@@ -2987,8 +2816,6 @@ static struct clk_branch gcc_hdmi_clkref_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_hdmi_clkref_clk",
- .parent_names = (const char *[]){ "xo" },
- .num_parents = 1,
.ops = &clk_branch2_ops,
},
},
@@ -3001,8 +2828,6 @@ static struct clk_branch gcc_ufs_clkref_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_ufs_clkref_clk",
- .parent_names = (const char *[]){ "xo" },
- .num_parents = 1,
.ops = &clk_branch2_ops,
},
},
@@ -3015,8 +2840,6 @@ static struct clk_branch gcc_pcie_clkref_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_pcie_clkref_clk",
- .parent_names = (const char *[]){ "xo" },
- .num_parents = 1,
.ops = &clk_branch2_ops,
},
},
@@ -3029,8 +2852,6 @@ static struct clk_branch gcc_rx2_usb2_clkref_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_rx2_usb2_clkref_clk",
- .parent_names = (const char *[]){ "xo" },
- .num_parents = 1,
.ops = &clk_branch2_ops,
},
},
@@ -3043,96 +2864,142 @@ static struct clk_branch gcc_rx1_usb2_clkref_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_rx1_usb2_clkref_clk",
- .parent_names = (const char *[]){ "xo" },
- .num_parents = 1,
.ops = &clk_branch2_ops,
},
},
};
-static struct clk_hw *gcc_msm8996_hws[] = {
- &xo.hw,
- &gpll0_early_div.hw,
- &ufs_tx_cfg_clk_src.hw,
- &ufs_rx_cfg_clk_src.hw,
- &ufs_ice_core_postdiv_clk_src.hw,
+static struct clk_branch hlos1_vote_lpass_core_smmu_clk = {
+ .halt_reg = 0x7d010,
+ .halt_check = BRANCH_HALT_NO_CHECK_ON_DISABLE,
+ .clkr = {
+ .enable_reg = 0x7d010,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "hlos1_vote_lpass_core_smmu_clk",
+ .ops = &clk_branch2_ops,
+ },
+ },
};
-static struct gdsc aggre0_noc_gdsc = {
- .gdscr = 0x81004,
- .gds_hw_ctrl = 0x81028,
- .pd = {
- .name = "aggre0_noc",
+static struct clk_branch hlos1_vote_lpass_adsp_smmu_clk = {
+ .halt_reg = 0x7d014,
+ .halt_check = BRANCH_HALT_NO_CHECK_ON_DISABLE,
+ .clkr = {
+ .enable_reg = 0x7d014,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "hlos1_vote_lpass_adsp_smmu_clk",
+ .ops = &clk_branch2_ops,
+ },
},
- .pwrsts = PWRSTS_OFF_ON,
- .flags = VOTABLE,
};
-static struct gdsc hlos1_vote_aggre0_noc_gdsc = {
- .gdscr = 0x7d024,
- .pd = {
- .name = "hlos1_vote_aggre0_noc",
+static struct clk_branch gcc_edp_clkref_clk = {
+ .halt_reg = 0x88004,
+ .clkr = {
+ .enable_reg = 0x88004,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_edp_clkref_clk",
+ .ops = &clk_branch2_ops,
+ },
},
- .pwrsts = PWRSTS_OFF_ON,
- .flags = VOTABLE,
};
-static struct gdsc hlos1_vote_lpass_adsp_gdsc = {
- .gdscr = 0x7d034,
- .pd = {
- .name = "hlos1_vote_lpass_adsp",
+static struct clk_branch gcc_mss_cfg_ahb_clk = {
+ .halt_reg = 0x8a000,
+ .clkr = {
+ .enable_reg = 0x8a000,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_mss_cfg_ahb_clk",
+ .ops = &clk_branch2_ops,
+ },
},
- .pwrsts = PWRSTS_OFF_ON,
- .flags = VOTABLE,
};
-static struct gdsc hlos1_vote_lpass_core_gdsc = {
- .gdscr = 0x7d038,
- .pd = {
- .name = "hlos1_vote_lpass_core",
+static struct clk_branch gcc_mss_q6_bimc_axi_clk = {
+ .halt_reg = 0x8a028,
+ .clkr = {
+ .enable_reg = 0x8a028,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_mss_q6_bimc_axi_clk",
+ .ops = &clk_branch2_ops,
+ },
},
- .pwrsts = PWRSTS_OFF_ON,
- .flags = VOTABLE,
};
-static struct gdsc usb30_gdsc = {
- .gdscr = 0xf004,
- .pd = {
- .name = "usb30",
+static struct clk_branch gcc_mss_snoc_axi_clk = {
+ .halt_reg = 0x8a024,
+ .clkr = {
+ .enable_reg = 0x8a024,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_mss_snoc_axi_clk",
+ .ops = &clk_branch2_ops,
+ },
},
- .pwrsts = PWRSTS_OFF_ON,
};
-static struct gdsc pcie0_gdsc = {
- .gdscr = 0x6b004,
- .pd = {
- .name = "pcie0",
+static struct clk_branch gcc_mss_mnoc_bimc_axi_clk = {
+ .halt_reg = 0x8a004,
+ .clkr = {
+ .enable_reg = 0x8a004,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_mss_mnoc_bimc_axi_clk",
+ .ops = &clk_branch2_ops,
+ },
},
- .pwrsts = PWRSTS_OFF_ON,
};
-static struct gdsc pcie1_gdsc = {
- .gdscr = 0x6d004,
- .pd = {
- .name = "pcie1",
+static struct clk_branch gcc_dcc_ahb_clk = {
+ .halt_reg = 0x84004,
+ .clkr = {
+ .enable_reg = 0x84004,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_dcc_ahb_clk",
+ .ops = &clk_branch2_ops,
+ },
},
- .pwrsts = PWRSTS_OFF_ON,
};
-static struct gdsc pcie2_gdsc = {
- .gdscr = 0x6e004,
- .pd = {
- .name = "pcie2",
+static struct clk_branch gcc_aggre0_noc_mpu_cfg_ahb_clk = {
+ .halt_reg = 0x85000,
+ .clkr = {
+ .enable_reg = 0x85000,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_aggre0_noc_mpu_cfg_ahb_clk",
+ .ops = &clk_branch2_ops,
+ },
},
- .pwrsts = PWRSTS_OFF_ON,
};
-static struct gdsc ufs_gdsc = {
- .gdscr = 0x75004,
- .pd = {
- .name = "ufs",
+static struct clk_branch gcc_mmss_gpll0_div_clk = {
+ .halt_check = BRANCH_HALT_DELAY,
+ .clkr = {
+ .enable_reg = 0x5200c,
+ .enable_mask = BIT(0),
+ .hw.init = &(struct clk_init_data){
+ .name = "gcc_mmss_gpll0_div_clk",
+ .parent_names = (const char *[]){ "gpll0" },
+ .num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
+ .ops = &clk_branch2_ops,
+ },
},
- .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct clk_hw *gcc_msm8996_hws[] = {
+ &xo.hw,
+ &gpll0_early_div.hw,
+ &ufs_tx_cfg_clk_src.hw,
+ &ufs_rx_cfg_clk_src.hw,
+ &ufs_ice_core_postdiv_clk_src.hw,
};
static struct clk_regmap *gcc_msm8996_clocks[] = {
@@ -3140,9 +3007,6 @@ static struct clk_regmap *gcc_msm8996_clocks[] = {
[GPLL0] = &gpll0.clkr,
[GPLL4_EARLY] = &gpll4_early.clkr,
[GPLL4] = &gpll4.clkr,
- [SYSTEM_NOC_CLK_SRC] = &system_noc_clk_src.clkr,
- [CONFIG_NOC_CLK_SRC] = &config_noc_clk_src.clkr,
- [PERIPH_NOC_CLK_SRC] = &periph_noc_clk_src.clkr,
[USB30_MASTER_CLK_SRC] = &usb30_master_clk_src.clkr,
[USB30_MOCK_UTMI_CLK_SRC] = &usb30_mock_utmi_clk_src.clkr,
[USB3_PHY_AUX_CLK_SRC] = &usb3_phy_aux_clk_src.clkr,
@@ -3191,7 +3055,6 @@ static struct clk_regmap *gcc_msm8996_clocks[] = {
[BLSP2_UART6_APPS_CLK_SRC] = &blsp2_uart6_apps_clk_src.clkr,
[PDM2_CLK_SRC] = &pdm2_clk_src.clkr,
[TSIF_REF_CLK_SRC] = &tsif_ref_clk_src.clkr,
- [GCC_SLEEP_CLK_SRC] = &gcc_sleep_clk_src.clkr,
[HMSS_RBCPR_CLK_SRC] = &hmss_rbcpr_clk_src.clkr,
[HMSS_GPLL0_CLK_SRC] = &hmss_gpll0_clk_src.clkr,
[GP1_CLK_SRC] = &gp1_clk_src.clkr,
@@ -3269,7 +3132,6 @@ static struct clk_regmap *gcc_msm8996_clocks[] = {
[GCC_PRNG_AHB_CLK] = &gcc_prng_ahb_clk.clkr,
[GCC_TSIF_AHB_CLK] = &gcc_tsif_ahb_clk.clkr,
[GCC_TSIF_REF_CLK] = &gcc_tsif_ref_clk.clkr,
- [GCC_TSIF_INACTIVITY_TIMERS_CLK] = &gcc_tsif_inactivity_timers_clk.clkr,
[GCC_BOOT_ROM_AHB_CLK] = &gcc_boot_rom_ahb_clk.clkr,
[GCC_BIMC_GFX_CLK] = &gcc_bimc_gfx_clk.clkr,
[GCC_HMSS_RBCPR_CLK] = &gcc_hmss_rbcpr_clk.clkr,
@@ -3319,18 +3181,21 @@ static struct clk_regmap *gcc_msm8996_clocks[] = {
[GCC_PCIE_CLKREF_CLK] = &gcc_pcie_clkref_clk.clkr,
[GCC_RX2_USB2_CLKREF_CLK] = &gcc_rx2_usb2_clkref_clk.clkr,
[GCC_RX1_USB2_CLKREF_CLK] = &gcc_rx1_usb2_clkref_clk.clkr,
-};
-
-static struct gdsc *gcc_msm8996_gdscs[] = {
- [AGGRE0_NOC_GDSC] = &aggre0_noc_gdsc,
- [HLOS1_VOTE_AGGRE0_NOC_GDSC] = &hlos1_vote_aggre0_noc_gdsc,
- [HLOS1_VOTE_LPASS_ADSP_GDSC] = &hlos1_vote_lpass_adsp_gdsc,
- [HLOS1_VOTE_LPASS_CORE_GDSC] = &hlos1_vote_lpass_core_gdsc,
- [USB30_GDSC] = &usb30_gdsc,
- [PCIE0_GDSC] = &pcie0_gdsc,
- [PCIE1_GDSC] = &pcie1_gdsc,
- [PCIE2_GDSC] = &pcie2_gdsc,
- [UFS_GDSC] = &ufs_gdsc,
+ [GCC_AGGRE0_NOC_QOSGEN_EXTREF_CLK] =
+ &gcc_aggre0_noc_qosgen_extref_clk.clkr,
+ [GCC_HLOS1_VOTE_LPASS_CORE_SMMU_CLK] =
+ &hlos1_vote_lpass_core_smmu_clk.clkr,
+ [GCC_HLOS1_VOTE_LPASS_ADSP_SMMU_CLK] =
+ &hlos1_vote_lpass_adsp_smmu_clk.clkr,
+ [GCC_EDP_CLKREF_CLK] = &gcc_edp_clkref_clk.clkr,
+ [GCC_MSS_CFG_AHB_CLK] = &gcc_mss_cfg_ahb_clk.clkr,
+ [GCC_MSS_Q6_BIMC_AXI_CLK] = &gcc_mss_q6_bimc_axi_clk.clkr,
+ [GCC_MSS_SNOC_AXI_CLK] = &gcc_mss_snoc_axi_clk.clkr,
+ [GCC_MSS_MNOC_BIMC_AXI_CLK] = &gcc_mss_mnoc_bimc_axi_clk.clkr,
+ [GCC_DCC_AHB_ALK] = &gcc_dcc_ahb_clk.clkr,
+ [GCC_AGGRE0_NOC_MPU_CFG_AHB_CLK] = &gcc_aggre0_noc_mpu_cfg_ahb_clk.clkr,
+ [GCC_MMSS_GPLL0_DIV_CLK] = &gcc_mmss_gpll0_div_clk.clkr,
+ [GPLL0_OUT_MSSCC] = &gpll0_out_msscc.clkr,
};
static const struct qcom_reset_map gcc_msm8996_resets[] = {
@@ -3455,8 +3320,6 @@ static const struct qcom_cc_desc gcc_msm8996_desc = {
.num_clks = ARRAY_SIZE(gcc_msm8996_clocks),
.resets = gcc_msm8996_resets,
.num_resets = ARRAY_SIZE(gcc_msm8996_resets),
- .gdscs = gcc_msm8996_gdscs,
- .num_gdscs = ARRAY_SIZE(gcc_msm8996_gdscs),
};
static const struct of_device_id gcc_msm8996_match_table[] = {
@@ -3469,18 +3332,15 @@ static int gcc_msm8996_probe(struct platform_device *pdev)
{
struct clk *clk;
struct device *dev = &pdev->dev;
- int i;
+ int i, ret = 0;
struct regmap *regmap;
regmap = qcom_cc_map(pdev, &gcc_msm8996_desc);
if (IS_ERR(regmap))
return PTR_ERR(regmap);
- /*
- * Set the HMSS_AHB_CLK_SLEEP_ENA bit to allow the hmss_ahb_clk to be
- * turned off by hardware during certain apps low power modes.
- */
- regmap_update_bits(regmap, 0x52008, BIT(21), BIT(21));
+ /* Set the HMSS_AHB_CLK_ENA bit to enable the hmss_ahb_clk */
+ regmap_update_bits(regmap, 0x52004, BIT(21), BIT(21));
for (i = 0; i < ARRAY_SIZE(gcc_msm8996_hws); i++) {
clk = devm_clk_register(dev, gcc_msm8996_hws[i]);
@@ -3488,7 +3348,19 @@ static int gcc_msm8996_probe(struct platform_device *pdev)
return PTR_ERR(clk);
}
- return qcom_cc_really_probe(pdev, &gcc_msm8996_desc, regmap);
+ ret = qcom_cc_really_probe(pdev, &gcc_msm8996_desc, regmap);
+
+ if (ret) {
+ dev_err(&pdev->dev, "Failed to register GCC clocks\n");
+ return ret;
+ }
+
+ /* This clock is used for all MMSS register access */
+ clk_prepare_enable(gcc_mmss_noc_cfg_ahb_clk.clkr.hw.clk);
+
+ dev_info(&pdev->dev, "Registered GCC clocks\n");
+
+ return ret;
}
static struct platform_driver gcc_msm8996_driver = {
diff --git a/drivers/crypto/msm/qce50.c b/drivers/crypto/msm/qce50.c
index 61f99370863d..9b42e5ae129a 100644
--- a/drivers/crypto/msm/qce50.c
+++ b/drivers/crypto/msm/qce50.c
@@ -84,6 +84,8 @@ static LIST_HEAD(qce50_bam_list);
/* Index to point the dummy request */
#define DUMMY_REQ_INDEX MAX_QCE_BAM_REQ
+#define TOTAL_IOVEC_SPACE_PER_PIPE (QCE_MAX_NUM_DSCR * sizeof(struct sps_iovec))
+
enum qce_owner {
QCE_OWNER_NONE = 0,
QCE_OWNER_CLIENT = 1,
@@ -110,6 +112,8 @@ struct qce_device {
unsigned char *coh_vmem; /* Allocated coherent virtual memory */
dma_addr_t coh_pmem; /* Allocated coherent physical memory */
int memsize; /* Memory allocated */
+ unsigned char *iovec_vmem; /* Allocate iovec virtual memory */
+ int iovec_memsize; /* Memory allocated */
uint32_t bam_mem; /* bam physical address, from DT */
uint32_t bam_mem_size; /* bam io size, from DT */
int is_shared; /* CE HW is shared */
@@ -4299,24 +4303,30 @@ static int qce_setup_ce_sps_data(struct qce_device *pce_dev)
{
unsigned char *vaddr;
int i;
+ unsigned char *iovec_vaddr;
+ int iovec_memsize;
vaddr = pce_dev->coh_vmem;
vaddr = (unsigned char *)ALIGN(((uintptr_t)vaddr),
pce_dev->ce_bam_info.ce_burst_size);
+ iovec_vaddr = pce_dev->iovec_vmem;
+ iovec_memsize = pce_dev->iovec_memsize;
for (i = 0; i < MAX_QCE_ALLOC_BAM_REQ; i++) {
/* Allow for 256 descriptor (cmd and data) entries per pipe */
pce_dev->ce_request_info[i].ce_sps.in_transfer.iovec =
- (struct sps_iovec *)vaddr;
+ (struct sps_iovec *)iovec_vaddr;
pce_dev->ce_request_info[i].ce_sps.in_transfer.iovec_phys =
- (uintptr_t)GET_PHYS_ADDR(vaddr);
- vaddr += QCE_MAX_NUM_DSCR * sizeof(struct sps_iovec);
-
+ virt_to_phys(pce_dev->ce_request_info[i].
+ ce_sps.in_transfer.iovec);
+ iovec_vaddr += TOTAL_IOVEC_SPACE_PER_PIPE;
+ iovec_memsize -= TOTAL_IOVEC_SPACE_PER_PIPE;
pce_dev->ce_request_info[i].ce_sps.out_transfer.iovec =
- (struct sps_iovec *)vaddr;
+ (struct sps_iovec *)iovec_vaddr;
pce_dev->ce_request_info[i].ce_sps.out_transfer.iovec_phys =
- (uintptr_t)GET_PHYS_ADDR(vaddr);
- vaddr += QCE_MAX_NUM_DSCR * sizeof(struct sps_iovec);
-
+ virt_to_phys(pce_dev->ce_request_info[i].
+ ce_sps.out_transfer.iovec);
+ iovec_vaddr += TOTAL_IOVEC_SPACE_PER_PIPE;
+ iovec_memsize -= TOTAL_IOVEC_SPACE_PER_PIPE;
if (pce_dev->support_cmd_dscr)
qce_setup_cmdlistptrs(pce_dev, i, &vaddr);
vaddr = (unsigned char *)ALIGN(((uintptr_t)vaddr),
@@ -4343,7 +4353,8 @@ static int qce_setup_ce_sps_data(struct qce_device *pce_dev)
}
pce_dev->dummyreq.in_buf = (uint8_t *)vaddr;
vaddr += DUMMY_REQ_DATA_LEN;
- if ((vaddr - pce_dev->coh_vmem) > pce_dev->memsize)
+ if ((vaddr - pce_dev->coh_vmem) > pce_dev->memsize ||
+ iovec_memsize < 0)
panic("qce50: Not enough coherent memory. Allocate %x , need %lx\n",
pce_dev->memsize, (uintptr_t)vaddr -
(uintptr_t)pce_dev->coh_vmem);
@@ -5933,12 +5944,19 @@ void *qce_open(struct platform_device *pdev, int *rc)
pce_dev->memsize = 10 * PAGE_SIZE * MAX_QCE_ALLOC_BAM_REQ;
pce_dev->coh_vmem = dma_alloc_coherent(pce_dev->pdev,
pce_dev->memsize, &pce_dev->coh_pmem, GFP_KERNEL);
+
if (pce_dev->coh_vmem == NULL) {
*rc = -ENOMEM;
pr_err("Can not allocate coherent memory for sps data\n");
goto err_iobase;
}
+ pce_dev->iovec_memsize = TOTAL_IOVEC_SPACE_PER_PIPE *
+ MAX_QCE_ALLOC_BAM_REQ * 2;
+ pce_dev->iovec_vmem = kzalloc(pce_dev->iovec_memsize, GFP_KERNEL);
+ if (pce_dev->iovec_vmem == NULL)
+ goto err_mem;
+
*rc = __qce_init_clk(pce_dev);
if (*rc)
goto err_mem;
@@ -5978,6 +5996,7 @@ err_enable_clk:
__qce_deinit_clk(pce_dev);
err_mem:
+ kfree(pce_dev->iovec_vmem);
if (pce_dev->coh_vmem)
dma_free_coherent(pce_dev->pdev, pce_dev->memsize,
pce_dev->coh_vmem, pce_dev->coh_pmem);
@@ -6008,6 +6027,7 @@ int qce_close(void *handle)
if (pce_dev->coh_vmem)
dma_free_coherent(pce_dev->pdev, pce_dev->memsize,
pce_dev->coh_vmem, pce_dev->coh_pmem);
+ kfree(pce_dev->iovec_vmem);
qce_disable_clk(pce_dev);
__qce_deinit_clk(pce_dev);
diff --git a/drivers/gpu/msm/kgsl_pool.c b/drivers/gpu/msm/kgsl_pool.c
index 7967b19779db..f5402fdc7e57 100644
--- a/drivers/gpu/msm/kgsl_pool.c
+++ b/drivers/gpu/msm/kgsl_pool.c
@@ -197,7 +197,7 @@ _kgsl_pool_shrink(struct kgsl_page_pool *pool, int num_pages)
* starting from higher order pool.
*/
static unsigned long
-kgsl_pool_reduce(unsigned int target_pages)
+kgsl_pool_reduce(unsigned int target_pages, bool exit)
{
int total_pages = 0;
int i;
@@ -210,6 +210,14 @@ kgsl_pool_reduce(unsigned int target_pages)
for (i = (KGSL_NUM_POOLS - 1); i >= 0; i--) {
pool = &kgsl_pools[i];
+ /*
+ * Only reduce the pool sizes for pools which are allowed to
+ * allocate memory unless we are at close, in which case the
+ * reserved memory for all pools needs to be freed
+ */
+ if (!pool->allocation_allowed && !exit)
+ continue;
+
total_pages -= pcount;
nr_removed = total_pages - target_pages;
@@ -418,7 +426,7 @@ kgsl_pool_shrink_scan_objects(struct shrinker *shrinker,
int target_pages = (nr > total_pages) ? 0 : (total_pages - nr);
/* Reduce pool size to target_pages */
- return kgsl_pool_reduce(target_pages);
+ return kgsl_pool_reduce(target_pages, false);
}
static unsigned long
@@ -449,7 +457,7 @@ void kgsl_init_page_pools(void)
void kgsl_exit_page_pools(void)
{
/* Release all pages in pools, if any.*/
- kgsl_pool_reduce(0);
+ kgsl_pool_reduce(0, true);
/* Unregister shrinker */
unregister_shrinker(&kgsl_pool_shrinker);
diff --git a/drivers/hwtracing/coresight/coresight-tpda.c b/drivers/hwtracing/coresight/coresight-tpda.c
index e4e188fc67fc..c43d8596a203 100644
--- a/drivers/hwtracing/coresight/coresight-tpda.c
+++ b/drivers/hwtracing/coresight/coresight-tpda.c
@@ -94,6 +94,10 @@ static void __tpda_enable_pre_port(struct tpda_drvdata *drvdata)
val = val | BIT(2);
else
val = val & ~BIT(2);
+
+ /* Force ASYNC-VERSION-FREQTS sequence */
+ val = val | BIT(21);
+
tpda_writel(drvdata, val, TPDA_CR);
/*
@@ -154,8 +158,6 @@ static void __tpda_enable_post_port(struct tpda_drvdata *drvdata)
if (drvdata->freq_req_val)
tpda_writel(drvdata, drvdata->freq_req_val, TPDA_FREQREQ_VAL);
- else
- tpda_writel(drvdata, 0x0, TPDA_FREQREQ_VAL);
val = tpda_readl(drvdata, TPDA_CR);
if (drvdata->freq_req)
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index b02abfc58aea..b9956170b909 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -1205,4 +1205,16 @@ config FT_SECURE_TOUCH
If unsure, say N.
+config TOUCHSCREEN_IT7260_I2C
+ tristate "IT7260 Touchscreen Driver"
+ depends on I2C
+ help
+ Say Y here if you have a IT7260 Touchscreen Driver
+ connected to your system.
+
+ If unsure, say N.
+
+ To compile this driver as a module, choose M here: the
+ module will be called it7258_ts_i2c.
+
endif
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
index e1777f11d77b..f448df5b234c 100644
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
@@ -45,6 +45,7 @@ obj-$(CONFIG_TOUCHSCREEN_ILI210X) += ili210x.o
obj-$(CONFIG_TOUCHSCREEN_IMX6UL_TSC) += imx6ul_tsc.o
obj-$(CONFIG_TOUCHSCREEN_INEXIO) += inexio.o
obj-$(CONFIG_TOUCHSCREEN_INTEL_MID) += intel-mid-touch.o
+obj-$(CONFIG_TOUCHSCREEN_IT7260_I2C) += it7258_ts_i2c.o
obj-$(CONFIG_TOUCHSCREEN_IPROC) += bcm_iproc_tsc.o
obj-$(CONFIG_TOUCHSCREEN_LPC32XX) += lpc32xx_ts.o
obj-$(CONFIG_TOUCHSCREEN_MAX11801) += max11801_ts.o
diff --git a/drivers/input/touchscreen/gt9xx/gt9xx.c b/drivers/input/touchscreen/gt9xx/gt9xx.c
index 6615c3a039a0..ebb9ce7ba6a4 100644
--- a/drivers/input/touchscreen/gt9xx/gt9xx.c
+++ b/drivers/input/touchscreen/gt9xx/gt9xx.c
@@ -40,8 +40,11 @@
* By Meta, 2013/06/08
*/
+#include <linux/regulator/consumer.h>
#include "gt9xx.h"
+#include <linux/of_gpio.h>
+
#if GTP_ICS_SLOT_REPORT
#include <linux/input/mt.h>
#endif
@@ -55,6 +58,15 @@
#define GTP_I2C_ADDRESS_HIGH 0x14
#define GTP_I2C_ADDRESS_LOW 0x5D
+#define GOODIX_VTG_MIN_UV 2600000
+#define GOODIX_VTG_MAX_UV 3300000
+#define GOODIX_I2C_VTG_MIN_UV 1800000
+#define GOODIX_I2C_VTG_MAX_UV 1800000
+#define GOODIX_VDD_LOAD_MIN_UA 0
+#define GOODIX_VDD_LOAD_MAX_UA 10000
+#define GOODIX_VIO_LOAD_MIN_UA 0
+#define GOODIX_VIO_LOAD_MAX_UA 10000
+
#define RESET_DELAY_T3_US 200 /* T3: > 100us */
#define RESET_DELAY_T4 20 /* T4: > 5ms */
@@ -80,7 +92,10 @@ static void gtp_reset_guitar(struct goodix_ts_data *ts, int ms);
static void gtp_int_sync(struct goodix_ts_data *ts, int ms);
static int gtp_i2c_test(struct i2c_client *client);
-#ifdef CONFIG_HAS_EARLYSUSPEND
+#if defined(CONFIG_FB)
+static int fb_notifier_callback(struct notifier_block *self,
+ unsigned long event, void *data);
+#elif defined(CONFIG_HAS_EARLYSUSPEND)
static void goodix_ts_early_suspend(struct early_suspend *h);
static void goodix_ts_late_resume(struct early_suspend *h);
#endif
@@ -755,7 +770,7 @@ static void gtp_reset_guitar(struct goodix_ts_data *ts, int ms)
#endif
}
-#ifdef CONFIG_HAS_EARLYSUSPEND
+#if defined(CONFIG_HAS_EARLYSUSPEND) || defined(CONFIG_FB)
#if GTP_SLIDE_WAKEUP
/*******************************************************
Function:
@@ -860,16 +875,12 @@ static s8 gtp_wakeup_sleep(struct goodix_ts_data *ts)
GTP_DEBUG_FUNC();
#if GTP_POWER_CTRL_SLEEP
- while (retry++ < 5) {
- gtp_reset_guitar(ts, 20);
+ gtp_reset_guitar(ts, 20);
- ret = gtp_send_cfg(ts);
- if (ret > 0) {
- dev_dbg(&ts->client->dev,
- "Wakeup sleep send config success.");
- continue;
- }
- dev_dbg(&ts->client->dev, "GTP Wakeup!");
+ ret = gtp_send_cfg(ts);
+ if (ret > 0) {
+ dev_dbg(&ts->client->dev,
+ "Wakeup sleep send config success.");
return 1;
}
#else
@@ -910,7 +921,7 @@ static s8 gtp_wakeup_sleep(struct goodix_ts_data *ts)
dev_err(&ts->client->dev, "GTP wakeup sleep failed.\n");
return ret;
}
-#endif /* !CONFIG_HAS_EARLYSUSPEND */
+#endif /* !CONFIG_HAS_EARLYSUSPEND && !CONFIG_FB*/
/*******************************************************
Function:
@@ -1014,21 +1025,27 @@ static int gtp_init_panel(struct goodix_ts_data *ts)
return -EINVAL;
}
- config_data = devm_kzalloc(&client->dev,
+ if (ts->pdata->gtp_cfg_len) {
+ config_data = ts->pdata->config_data;
+ ts->config_data = ts->pdata->config_data;
+ ts->gtp_cfg_len = ts->pdata->gtp_cfg_len;
+ } else {
+ config_data = devm_kzalloc(&client->dev,
GTP_CONFIG_MAX_LENGTH + GTP_ADDR_LENGTH,
- GFP_KERNEL);
- if (!config_data) {
- dev_err(&client->dev,
- "Not enough memory for panel config data\n");
- return -ENOMEM;
- }
+ GFP_KERNEL);
+ if (!config_data) {
+ dev_err(&client->dev,
+ "Not enough memory for panel config data\n");
+ return -ENOMEM;
+ }
- ts->config_data = config_data;
- config_data[0] = GTP_REG_CONFIG_DATA >> 8;
- config_data[1] = GTP_REG_CONFIG_DATA & 0xff;
- memset(&config_data[GTP_ADDR_LENGTH], 0, GTP_CONFIG_MAX_LENGTH);
- memcpy(&config_data[GTP_ADDR_LENGTH], send_cfg_buf[sensor_id],
- ts->gtp_cfg_len);
+ ts->config_data = config_data;
+ config_data[0] = GTP_REG_CONFIG_DATA >> 8;
+ config_data[1] = GTP_REG_CONFIG_DATA & 0xff;
+ memset(&config_data[GTP_ADDR_LENGTH], 0, GTP_CONFIG_MAX_LENGTH);
+ memcpy(&config_data[GTP_ADDR_LENGTH], send_cfg_buf[sensor_id],
+ ts->gtp_cfg_len);
+ }
#if GTP_CUSTOM_CFG
config_data[RESOLUTION_LOC] =
@@ -1345,6 +1362,318 @@ exit_free_inputdev:
return ret;
}
+static int reg_set_optimum_mode_check(struct regulator *reg, int load_uA)
+{
+ return (regulator_count_voltages(reg) > 0) ?
+ regulator_set_optimum_mode(reg, load_uA) : 0;
+}
+
+/**
+ * goodix_power_on - Turn device power ON
+ * @ts: driver private data
+ *
+ * Returns zero on success, else an error.
+ */
+static int goodix_power_on(struct goodix_ts_data *ts)
+{
+ int ret;
+
+ if (!IS_ERR(ts->avdd)) {
+ ret = reg_set_optimum_mode_check(ts->avdd,
+ GOODIX_VDD_LOAD_MAX_UA);
+ if (ret < 0) {
+ dev_err(&ts->client->dev,
+ "Regulator avdd set_opt failed rc=%d\n", ret);
+ goto err_set_opt_avdd;
+ }
+ ret = regulator_enable(ts->avdd);
+ if (ret) {
+ dev_err(&ts->client->dev,
+ "Regulator avdd enable failed ret=%d\n", ret);
+ goto err_enable_avdd;
+ }
+ }
+
+ if (!IS_ERR(ts->vdd)) {
+ ret = regulator_set_voltage(ts->vdd, GOODIX_VTG_MIN_UV,
+ GOODIX_VTG_MAX_UV);
+ if (ret) {
+ dev_err(&ts->client->dev,
+ "Regulator set_vtg failed vdd ret=%d\n", ret);
+ goto err_set_vtg_vdd;
+ }
+ ret = reg_set_optimum_mode_check(ts->vdd,
+ GOODIX_VDD_LOAD_MAX_UA);
+ if (ret < 0) {
+ dev_err(&ts->client->dev,
+ "Regulator vdd set_opt failed rc=%d\n", ret);
+ goto err_set_opt_vdd;
+ }
+ ret = regulator_enable(ts->vdd);
+ if (ret) {
+ dev_err(&ts->client->dev,
+ "Regulator vdd enable failed ret=%d\n", ret);
+ goto err_enable_vdd;
+ }
+ }
+
+ if (!IS_ERR(ts->vcc_i2c)) {
+ ret = regulator_set_voltage(ts->vcc_i2c, GOODIX_I2C_VTG_MIN_UV,
+ GOODIX_I2C_VTG_MAX_UV);
+ if (ret) {
+ dev_err(&ts->client->dev,
+ "Regulator set_vtg failed vcc_i2c ret=%d\n",
+ ret);
+ goto err_set_vtg_vcc_i2c;
+ }
+ ret = reg_set_optimum_mode_check(ts->vcc_i2c,
+ GOODIX_VIO_LOAD_MAX_UA);
+ if (ret < 0) {
+ dev_err(&ts->client->dev,
+ "Regulator vcc_i2c set_opt failed rc=%d\n",
+ ret);
+ goto err_set_opt_vcc_i2c;
+ }
+ ret = regulator_enable(ts->vcc_i2c);
+ if (ret) {
+ dev_err(&ts->client->dev,
+ "Regulator vcc_i2c enable failed ret=%d\n",
+ ret);
+ regulator_disable(ts->vdd);
+ goto err_enable_vcc_i2c;
+ }
+ }
+
+ return 0;
+
+err_enable_vcc_i2c:
+err_set_opt_vcc_i2c:
+ if (!IS_ERR(ts->vcc_i2c))
+ regulator_set_voltage(ts->vcc_i2c, 0, GOODIX_I2C_VTG_MAX_UV);
+err_set_vtg_vcc_i2c:
+ if (!IS_ERR(ts->vdd))
+ regulator_disable(ts->vdd);
+err_enable_vdd:
+err_set_opt_vdd:
+ if (!IS_ERR(ts->vdd))
+ regulator_set_voltage(ts->vdd, 0, GOODIX_VTG_MAX_UV);
+err_set_vtg_vdd:
+ if (!IS_ERR(ts->avdd))
+ regulator_disable(ts->avdd);
+err_enable_avdd:
+err_set_opt_avdd:
+ return ret;
+}
+
+/**
+ * goodix_power_off - Turn device power OFF
+ * @ts: driver private data
+ *
+ * Returns zero on success, else an error.
+ */
+static int goodix_power_off(struct goodix_ts_data *ts)
+{
+ int ret;
+
+ if (!IS_ERR(ts->vcc_i2c)) {
+ ret = regulator_set_voltage(ts->vcc_i2c, 0,
+ GOODIX_I2C_VTG_MAX_UV);
+ if (ret < 0)
+ dev_err(&ts->client->dev,
+ "Regulator vcc_i2c set_vtg failed ret=%d\n",
+ ret);
+ ret = regulator_disable(ts->vcc_i2c);
+ if (ret)
+ dev_err(&ts->client->dev,
+ "Regulator vcc_i2c disable failed ret=%d\n",
+ ret);
+ }
+
+ if (!IS_ERR(ts->vdd)) {
+ ret = regulator_set_voltage(ts->vdd, 0, GOODIX_VTG_MAX_UV);
+ if (ret < 0)
+ dev_err(&ts->client->dev,
+ "Regulator vdd set_vtg failed ret=%d\n", ret);
+ ret = regulator_disable(ts->vdd);
+ if (ret)
+ dev_err(&ts->client->dev,
+ "Regulator vdd disable failed ret=%d\n", ret);
+ }
+
+ if (!IS_ERR(ts->avdd)) {
+ ret = regulator_disable(ts->avdd);
+ if (ret)
+ dev_err(&ts->client->dev,
+ "Regulator avdd disable failed ret=%d\n", ret);
+ }
+
+ return 0;
+}
+
+/**
+ * goodix_power_init - Initialize device power
+ * @ts: driver private data
+ *
+ * Returns zero on success, else an error.
+ */
+static int goodix_power_init(struct goodix_ts_data *ts)
+{
+ int ret;
+
+ ts->avdd = regulator_get(&ts->client->dev, "avdd");
+ if (IS_ERR(ts->avdd)) {
+ ret = PTR_ERR(ts->avdd);
+ dev_info(&ts->client->dev,
+ "Regulator get failed avdd ret=%d\n", ret);
+ }
+
+ ts->vdd = regulator_get(&ts->client->dev, "vdd");
+ if (IS_ERR(ts->vdd)) {
+ ret = PTR_ERR(ts->vdd);
+ dev_info(&ts->client->dev,
+ "Regulator get failed vdd ret=%d\n", ret);
+ }
+
+ ts->vcc_i2c = regulator_get(&ts->client->dev, "vcc-i2c");
+ if (IS_ERR(ts->vcc_i2c)) {
+ ret = PTR_ERR(ts->vcc_i2c);
+ dev_info(&ts->client->dev,
+ "Regulator get failed vcc_i2c ret=%d\n", ret);
+ }
+
+ return 0;
+}
+
+/**
+ * goodix_power_deinit - Deinitialize device power
+ * @ts: driver private data
+ *
+ * Returns zero on success, else an error.
+ */
+static int goodix_power_deinit(struct goodix_ts_data *ts)
+{
+ regulator_put(ts->vdd);
+ regulator_put(ts->vcc_i2c);
+ regulator_put(ts->avdd);
+
+ return 0;
+}
+
+static int goodix_ts_get_dt_coords(struct device *dev, char *name,
+ struct goodix_ts_platform_data *pdata)
+{
+ struct property *prop;
+ struct device_node *np = dev->of_node;
+ int rc;
+ u32 coords[GOODIX_COORDS_ARR_SIZE];
+
+ prop = of_find_property(np, name, NULL);
+ if (!prop)
+ return -EINVAL;
+ if (!prop->value)
+ return -ENODATA;
+
+ rc = of_property_read_u32_array(np, name, coords,
+ GOODIX_COORDS_ARR_SIZE);
+ if (rc && (rc != -EINVAL)) {
+ dev_err(dev, "Unable to read %s\n", name);
+ return rc;
+ }
+
+ if (!strcmp(name, "goodix,panel-coords")) {
+ pdata->panel_minx = coords[0];
+ pdata->panel_miny = coords[1];
+ pdata->panel_maxx = coords[2];
+ pdata->panel_maxy = coords[3];
+ } else if (!strcmp(name, "goodix,display-coords")) {
+ pdata->x_min = coords[0];
+ pdata->y_min = coords[1];
+ pdata->x_max = coords[2];
+ pdata->y_max = coords[3];
+ } else {
+ dev_err(dev, "unsupported property %s\n", name);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int goodix_parse_dt(struct device *dev,
+ struct goodix_ts_platform_data *pdata)
+{
+ int rc;
+ struct device_node *np = dev->of_node;
+ struct property *prop;
+ u32 temp_val, num_buttons;
+ u32 button_map[MAX_BUTTONS];
+
+ rc = goodix_ts_get_dt_coords(dev, "goodix,panel-coords", pdata);
+ if (rc && (rc != -EINVAL))
+ return rc;
+
+ rc = goodix_ts_get_dt_coords(dev, "goodix,display-coords", pdata);
+ if (rc)
+ return rc;
+
+ pdata->i2c_pull_up = of_property_read_bool(np,
+ "goodix,i2c-pull-up");
+
+ pdata->no_force_update = of_property_read_bool(np,
+ "goodix,no-force-update");
+ /* reset, irq gpio info */
+ pdata->reset_gpio = of_get_named_gpio_flags(np, "reset-gpios",
+ 0, &pdata->reset_gpio_flags);
+ if (pdata->reset_gpio < 0)
+ return pdata->reset_gpio;
+
+ pdata->irq_gpio = of_get_named_gpio_flags(np, "interrupt-gpios",
+ 0, &pdata->irq_gpio_flags);
+ if (pdata->irq_gpio < 0)
+ return pdata->irq_gpio;
+
+ rc = of_property_read_u32(np, "goodix,family-id", &temp_val);
+ if (!rc)
+ pdata->family_id = temp_val;
+ else
+ return rc;
+
+ prop = of_find_property(np, "goodix,button-map", NULL);
+ if (prop) {
+ num_buttons = prop->length / sizeof(temp_val);
+ if (num_buttons > MAX_BUTTONS)
+ return -EINVAL;
+
+ rc = of_property_read_u32_array(np,
+ "goodix,button-map", button_map,
+ num_buttons);
+ if (rc) {
+ dev_err(dev, "Unable to read key codes\n");
+ return rc;
+ }
+ }
+
+ prop = of_find_property(np, "goodix,cfg-data", &pdata->gtp_cfg_len);
+ if (prop && prop->value) {
+ pdata->config_data = devm_kzalloc(dev,
+ GTP_CONFIG_MAX_LENGTH + GTP_ADDR_LENGTH, GFP_KERNEL);
+ if (!pdata->config_data)
+ return -ENOMEM;
+
+ pdata->config_data[0] = GTP_REG_CONFIG_DATA >> 8;
+ pdata->config_data[1] = GTP_REG_CONFIG_DATA & 0xff;
+ memset(&pdata->config_data[GTP_ADDR_LENGTH], 0,
+ GTP_CONFIG_MAX_LENGTH);
+ memcpy(&pdata->config_data[GTP_ADDR_LENGTH],
+ prop->value, pdata->gtp_cfg_len);
+ } else {
+ dev_err(dev,
+ "Unable to get configure data, default will be used.\n");
+ pdata->gtp_cfg_len = 0;
+ }
+
+ return 0;
+}
+
/*******************************************************
Function:
I2c probe.
@@ -1359,15 +1688,34 @@ Output:
static int goodix_ts_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
+ struct goodix_ts_platform_data *pdata;
struct goodix_ts_data *ts;
u16 version_info;
int ret;
dev_dbg(&client->dev, "GTP I2C Address: 0x%02x\n", client->addr);
+ if (client->dev.of_node) {
+ pdata = devm_kzalloc(&client->dev,
+ sizeof(struct goodix_ts_platform_data), GFP_KERNEL);
+ if (!pdata)
+ return -ENOMEM;
+
+ ret = goodix_parse_dt(&client->dev, pdata);
+ if (ret)
+ return ret;
+ } else {
+ pdata = client->dev.platform_data;
+ }
+
+ if (!pdata) {
+ dev_err(&client->dev, "GTP invalid pdata\n");
+ return -EINVAL;
+ }
#if GTP_ESD_PROTECT
i2c_connect_client = client;
#endif
+
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
dev_err(&client->dev, "GTP I2C not supported\n");
return -ENODEV;
@@ -1379,14 +1727,26 @@ static int goodix_ts_probe(struct i2c_client *client,
memset(ts, 0, sizeof(*ts));
ts->client = client;
- /* For kernel 2.6.39 later we spin_lock_init(&ts->irq_lock)
+ ts->pdata = pdata;
+ /* For 2.6.39 & later use spin_lock_init(&ts->irq_lock)
* For 2.6.39 & before, use ts->irq_lock = SPIN_LOCK_UNLOCKED
*/
spin_lock_init(&ts->irq_lock);
i2c_set_clientdata(client, ts);
-
ts->gtp_rawdiff_mode = 0;
+ ret = goodix_power_init(ts);
+ if (ret) {
+ dev_err(&client->dev, "GTP power init failed\n");
+ goto exit_free_client_data;
+ }
+
+ ret = goodix_power_on(ts);
+ if (ret) {
+ dev_err(&client->dev, "GTP power on failed\n");
+ goto exit_deinit_power;
+ }
+
ret = gtp_request_io_port(ts);
if (ret) {
dev_err(&client->dev, "GTP request IO port failed.\n");
@@ -1424,6 +1784,20 @@ static int goodix_ts_probe(struct i2c_client *client,
goto exit_free_inputdev;
}
+#if defined(CONFIG_FB)
+ ts->fb_notif.notifier_call = fb_notifier_callback;
+ ret = fb_register_client(&ts->fb_notif);
+ if (ret)
+ dev_err(&ts->client->dev,
+ "Unable to register fb_notifier: %d\n",
+ ret);
+#elif defined(CONFIG_HAS_EARLYSUSPEND)
+ ts->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
+ ts->early_suspend.suspend = goodix_ts_early_suspend;
+ ts->early_suspend.resume = goodix_ts_late_resume;
+ register_early_suspend(&ts->early_suspend);
+#endif
+
ts->goodix_wq = create_singlethread_workqueue("goodix_wq");
INIT_WORK(&ts->work, goodix_ts_work_func);
@@ -1451,6 +1825,13 @@ static int goodix_ts_probe(struct i2c_client *client,
init_done = true;
return 0;
exit_free_irq:
+#if defined(CONFIG_FB)
+ if (fb_unregister_client(&ts->fb_notif))
+ dev_err(&client->dev,
+ "Error occurred while unregistering fb_notifier.\n");
+#elif defined(CONFIG_HAS_EARLYSUSPEND)
+ unregister_early_suspend(&ts->early_suspend);
+#endif
if (ts->use_irq)
free_irq(client->irq, ts);
else
@@ -1467,7 +1848,15 @@ exit_free_irq:
exit_free_inputdev:
kfree(ts->config_data);
exit_free_io_port:
+ if (gpio_is_valid(pdata->reset_gpio))
+ gpio_free(pdata->reset_gpio);
+ if (gpio_is_valid(pdata->irq_gpio))
+ gpio_free(pdata->irq_gpio);
exit_power_off:
+ goodix_power_off(ts);
+exit_deinit_power:
+ goodix_power_deinit(ts);
+exit_free_client_data:
i2c_set_clientdata(client, NULL);
kfree(ts);
return ret;
@@ -1486,7 +1875,11 @@ static int goodix_ts_remove(struct i2c_client *client)
struct goodix_ts_data *ts = i2c_get_clientdata(client);
GTP_DEBUG_FUNC();
-#ifdef CONFIG_HAS_EARLYSUSPEND
+#if defined(CONFIG_FB)
+ if (fb_unregister_client(&ts->fb_notif))
+ dev_err(&client->dev,
+ "Error occurred while unregistering fb_notifier.\n");
+#elif defined(CONFIG_HAS_EARLYSUSPEND)
unregister_early_suspend(&ts->early_suspend);
#endif
@@ -1522,6 +1915,8 @@ static int goodix_ts_remove(struct i2c_client *client)
if (gpio_is_valid(ts->pdata->irq_gpio))
gpio_free(ts->pdata->irq_gpio);
+ goodix_power_off(ts);
+ goodix_power_deinit(ts);
i2c_set_clientdata(client, NULL);
kfree(ts);
}
@@ -1529,7 +1924,7 @@ static int goodix_ts_remove(struct i2c_client *client)
return 0;
}
-#ifdef CONFIG_HAS_EARLYSUSPEND
+#if defined(CONFIG_HAS_EARLYSUSPEND) || defined(CONFIG_FB)
/*******************************************************
Function:
Early suspend function.
@@ -1538,12 +1933,9 @@ Input:
Output:
None.
*******************************************************/
-static void goodix_ts_early_suspend(struct early_suspend *h)
+static void goodix_ts_suspend(struct goodix_ts_data *ts)
{
- struct goodix_ts_data *ts;
- s8 ret = -1;
-
- ts = container_of(h, struct goodix_ts_data, early_suspend);
+ int ret = -1;
GTP_DEBUG_FUNC();
@@ -1577,12 +1969,9 @@ Input:
Output:
None.
*******************************************************/
-static void goodix_ts_late_resume(struct early_suspend *h)
+static void goodix_ts_resume(struct goodix_ts_data *ts)
{
- struct goodix_ts_data *ts;
- s8 ret = -1;
-
- ts = container_of(h, struct goodix_ts_data, early_suspend);
+ int ret = -1;
GTP_DEBUG_FUNC();
@@ -1593,7 +1982,7 @@ static void goodix_ts_late_resume(struct early_suspend *h)
#endif
if (ret < 0)
- dev_err(&ts->client->dev, "GTP later resume failed.\n");
+ dev_err(&ts->client->dev, "GTP resume failed.\n");
if (ts->use_irq)
gtp_irq_enable(ts);
@@ -1606,18 +1995,72 @@ static void goodix_ts_late_resume(struct early_suspend *h)
gtp_esd_switch(ts->client, SWITCH_ON);
#endif
}
+
+#if defined(CONFIG_FB)
+static int fb_notifier_callback(struct notifier_block *self,
+ unsigned long event, void *data)
+{
+ struct fb_event *evdata = data;
+ int *blank;
+ struct goodix_ts_data *ts =
+ container_of(self, struct goodix_ts_data, fb_notif);
+
+ if (evdata && evdata->data && event == FB_EVENT_BLANK &&
+ ts && ts->client) {
+ blank = evdata->data;
+ if (*blank == FB_BLANK_UNBLANK)
+ goodix_ts_resume(ts);
+ else if (*blank == FB_BLANK_POWERDOWN)
+ goodix_ts_suspend(ts);
+ }
+
+ return 0;
+}
+#elif defined(CONFIG_HAS_EARLYSUSPEND)
+/*
+ * Function:
+ * Early suspend function.
+ * Input:
+ * h: early_suspend struct.
+ * Output:
+ * None.
+ */
+static void goodix_ts_early_suspend(struct early_suspend *h)
+{
+ struct goodix_ts_data *ts;
+
+ ts = container_of(h, struct goodix_ts_data, early_suspend);
+ goodix_ts_suspend(ts);
+}
+
+/*
+ * Function:
+ * Late resume function.
+ * Input:
+ * h: early_suspend struct.
+ * Output:
+ * None.
+ */
+static void goodix_ts_late_resume(struct early_suspend *h)
+{
+ struct goodix_ts_data *ts;
+
+ ts = container_of(h, struct goodix_ts_data, early_suspend);
+ goodix_ts_late_resume(ts);
+}
#endif
+#endif /* !CONFIG_HAS_EARLYSUSPEND && !CONFIG_FB*/
#if GTP_ESD_PROTECT
-/*******************************************************
-Function:
- switch on & off esd delayed work
-Input:
- client: i2c device
- on: SWITCH_ON / SWITCH_OFF
-Output:
- void
-*********************************************************/
+/*
+ * Function:
+ * switch on & off esd delayed work
+ * Input:
+ * client: i2c device
+ * on: SWITCH_ON / SWITCH_OFF
+ * Output:
+ * void
+ */
void gtp_esd_switch(struct i2c_client *client, int on)
{
struct goodix_ts_data *ts;
@@ -1749,6 +2192,11 @@ static const struct i2c_device_id goodix_ts_id[] = {
{ }
};
+static const struct of_device_id goodix_match_table[] = {
+ { .compatible = "goodix,gt9xx", },
+ { },
+};
+
static struct i2c_driver goodix_ts_driver = {
.probe = goodix_ts_probe,
.remove = goodix_ts_remove,
@@ -1760,6 +2208,7 @@ static struct i2c_driver goodix_ts_driver = {
.driver = {
.name = GTP_I2C_NAME,
.owner = THIS_MODULE,
+ .of_match_table = goodix_match_table,
},
};
diff --git a/drivers/input/touchscreen/gt9xx/gt9xx.h b/drivers/input/touchscreen/gt9xx/gt9xx.h
index 48fa2ad2faca..185927c6d2b5 100644
--- a/drivers/input/touchscreen/gt9xx/gt9xx.h
+++ b/drivers/input/touchscreen/gt9xx/gt9xx.h
@@ -33,7 +33,11 @@
#include <linux/regulator/consumer.h>
#include <linux/firmware.h>
#include <linux/debugfs.h>
-#if defined(CONFIG_HAS_EARLYSUSPEND)
+
+#if defined(CONFIG_FB)
+#include <linux/notifier.h>
+#include <linux/fb.h>
+#elif defined(CONFIG_HAS_EARLYSUSPEND)
#include <linux/earlysuspend.h>
#define GOODIX_SUSPEND_LEVEL 1
#endif
@@ -43,8 +47,6 @@ struct goodix_ts_platform_data {
u32 irq_gpio_flags;
int reset_gpio;
u32 reset_gpio_flags;
- int ldo_en_gpio;
- u32 ldo_en_gpio_flags;
u32 family_id;
u32 x_max;
u32 y_max;
@@ -56,6 +58,8 @@ struct goodix_ts_platform_data {
u32 panel_maxy;
bool no_force_update;
bool i2c_pull_up;
+ int gtp_cfg_len;
+ u8 *config_data;
};
struct goodix_ts_data {
spinlock_t irq_lock;
@@ -65,9 +69,6 @@ struct goodix_ts_data {
struct hrtimer timer;
struct workqueue_struct *goodix_wq;
struct work_struct work;
-#if defined(CONFIG_HAS_EARLYSUSPEND)
- struct early_suspend early_suspend;
-#endif
s32 irq_is_disabled;
s32 use_irq;
u16 abs_x_max;
@@ -84,6 +85,14 @@ struct goodix_ts_data {
u8 fixed_cfg;
u8 esd_running;
u8 fw_error;
+ struct regulator *avdd;
+ struct regulator *vdd;
+ struct regulator *vcc_i2c;
+#if defined(CONFIG_FB)
+ struct notifier_block fb_notif;
+#elif defined(CONFIG_HAS_EARLYSUSPEND)
+ struct early_suspend early_suspend;
+#endif
};
extern u16 show_len;
@@ -94,8 +103,8 @@ extern u16 total_len;
#define GTP_CHANGE_X2Y 0
#define GTP_DRIVER_SEND_CFG 1
#define GTP_HAVE_TOUCH_KEY 1
-#define GTP_POWER_CTRL_SLEEP 1
-#define GTP_ICS_SLOT_REPORT 0
+#define GTP_POWER_CTRL_SLEEP 0
+#define GTP_ICS_SLOT_REPORT 1
/* auto updated by .bin file as default */
#define GTP_AUTO_UPDATE 0
diff --git a/drivers/misc/qcom/qdsp6v2/audio_utils.c b/drivers/misc/qcom/qdsp6v2/audio_utils.c
index cad0220a4960..065b426ca6d0 100644
--- a/drivers/misc/qcom/qdsp6v2/audio_utils.c
+++ b/drivers/misc/qcom/qdsp6v2/audio_utils.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2010-2016, 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
@@ -24,6 +24,15 @@
#include <asm/ioctls.h>
#include "audio_utils.h"
+/*
+ * Define maximum buffer size. Below values are chosen considering the higher
+ * values used among all native drivers.
+ */
+#define MAX_FRAME_SIZE 1536
+#define MAX_FRAMES 5
+#define META_SIZE (sizeof(struct meta_out_dsp))
+#define MAX_BUFFER_SIZE (1 + ((MAX_FRAME_SIZE + META_SIZE) * MAX_FRAMES))
+
static int audio_in_pause(struct q6audio_in *audio)
{
int rc;
@@ -329,6 +338,10 @@ long audio_in_ioctl(struct file *file,
rc = -EINVAL;
break;
}
+ if (cfg.buffer_size > MAX_BUFFER_SIZE) {
+ rc = -EINVAL;
+ break;
+ }
audio->str_cfg.buffer_size = cfg.buffer_size;
audio->str_cfg.buffer_count = cfg.buffer_count;
if (audio->opened) {
diff --git a/drivers/phy/phy-qcom-ufs-i.h b/drivers/phy/phy-qcom-ufs-i.h
index 35179c8be471..7acef104d5b7 100644
--- a/drivers/phy/phy-qcom-ufs-i.h
+++ b/drivers/phy/phy-qcom-ufs-i.h
@@ -152,6 +152,7 @@ struct ufs_qcom_phy {
* and writes to QSERDES_RX_SIGDET_CNTRL attribute
* @configure_lpm: pointer to a function that configures the phy
* for low power mode.
+ * @dbg_register_dump: pointer to a function that dumps phy registers for debug.
*/
struct ufs_qcom_phy_specific_ops {
int (*calibrate_phy)(struct ufs_qcom_phy *phy, bool is_rate_B);
@@ -161,6 +162,7 @@ struct ufs_qcom_phy_specific_ops {
void (*ctrl_rx_linecfg)(struct ufs_qcom_phy *phy, bool ctrl);
void (*power_control)(struct ufs_qcom_phy *phy, bool val);
int (*configure_lpm)(struct ufs_qcom_phy *phy, bool enable);
+ void (*dbg_register_dump)(struct ufs_qcom_phy *phy);
};
struct ufs_qcom_phy *get_ufs_qcom_phy(struct phy *generic_phy);
@@ -184,5 +186,6 @@ int ufs_qcom_phy_calibrate(struct ufs_qcom_phy *ufs_qcom_phy,
void ufs_qcom_phy_write_tbl(struct ufs_qcom_phy *ufs_qcom_phy,
struct ufs_qcom_phy_calibration *tbl,
int tbl_size);
-
+void ufs_qcom_phy_dump_regs(struct ufs_qcom_phy *phy,
+ int offset, int len, char *prefix);
#endif
diff --git a/drivers/phy/phy-qcom-ufs-qmp-v3.c b/drivers/phy/phy-qcom-ufs-qmp-v3.c
index 57c23f70eb63..a9ad3a6f87cc 100644
--- a/drivers/phy/phy-qcom-ufs-qmp-v3.c
+++ b/drivers/phy/phy-qcom-ufs-qmp-v3.c
@@ -194,6 +194,22 @@ out:
return err;
}
+static void ufs_qcom_phy_qmp_v3_dbg_register_dump(struct ufs_qcom_phy *phy)
+{
+ ufs_qcom_phy_dump_regs(phy, COM_BASE, COM_SIZE,
+ "PHY QSERDES COM Registers ");
+ ufs_qcom_phy_dump_regs(phy, PHY_BASE, PHY_SIZE,
+ "PHY Registers ");
+ ufs_qcom_phy_dump_regs(phy, RX_BASE(0), RX_SIZE,
+ "PHY RX0 Registers ");
+ ufs_qcom_phy_dump_regs(phy, TX_BASE(0), TX_SIZE,
+ "PHY TX0 Registers ");
+ ufs_qcom_phy_dump_regs(phy, RX_BASE(1), RX_SIZE,
+ "PHY RX1 Registers ");
+ ufs_qcom_phy_dump_regs(phy, TX_BASE(1), TX_SIZE,
+ "PHY TX1 Registers ");
+}
+
struct phy_ops ufs_qcom_phy_qmp_v3_phy_ops = {
.init = ufs_qcom_phy_qmp_v3_init,
.exit = ufs_qcom_phy_exit,
@@ -210,6 +226,7 @@ struct ufs_qcom_phy_specific_ops phy_v3_ops = {
.ctrl_rx_linecfg = ufs_qcom_phy_qmp_v3_ctrl_rx_linecfg,
.power_control = ufs_qcom_phy_qmp_v3_power_control,
.configure_lpm = ufs_qcom_phy_qmp_v3_configure_lpm,
+ .dbg_register_dump = ufs_qcom_phy_qmp_v3_dbg_register_dump,
};
static int ufs_qcom_phy_qmp_v3_probe(struct platform_device *pdev)
diff --git a/drivers/phy/phy-qcom-ufs-qmp-v3.h b/drivers/phy/phy-qcom-ufs-qmp-v3.h
index cda57855acb5..8b1e03eab639 100644
--- a/drivers/phy/phy-qcom-ufs-qmp-v3.h
+++ b/drivers/phy/phy-qcom-ufs-qmp-v3.h
@@ -18,10 +18,18 @@
#include "phy-qcom-ufs-i.h"
/* QCOM UFS PHY control registers */
-#define COM_OFF(x) (0x000 + x)
-#define PHY_OFF(x) (0xC00 + x)
-#define TX_OFF(n, x) (0x400 + (0x400 * n) + x)
-#define RX_OFF(n, x) (0x600 + (0x400 * n) + x)
+#define COM_BASE 0x000
+#define COM_SIZE 0x18C
+#define PHY_BASE 0xC00
+#define PHY_SIZE 0x1DC
+#define TX_BASE(n) (0x400 + (0x400 * n))
+#define TX_SIZE 0x128
+#define RX_BASE(n) (0x600 + (0x400 * n))
+#define RX_SIZE 0x1FC
+#define COM_OFF(x) (COM_BASE + x)
+#define PHY_OFF(x) (PHY_BASE + x)
+#define TX_OFF(n, x) (TX_BASE(n) + x)
+#define RX_OFF(n, x) (RX_BASE(n) + x)
/* UFS PHY QSERDES COM registers */
#define QSERDES_COM_ATB_SEL1 COM_OFF(0x00)
diff --git a/drivers/phy/phy-qcom-ufs.c b/drivers/phy/phy-qcom-ufs.c
index de32b75f4f57..b2c58430785a 100644
--- a/drivers/phy/phy-qcom-ufs.c
+++ b/drivers/phy/phy-qcom-ufs.c
@@ -788,3 +788,21 @@ int ufs_qcom_phy_configure_lpm(struct phy *generic_phy, bool enable)
return ret;
}
EXPORT_SYMBOL(ufs_qcom_phy_configure_lpm);
+
+void ufs_qcom_phy_dump_regs(struct ufs_qcom_phy *phy, int offset,
+ int len, char *prefix)
+{
+ print_hex_dump(KERN_ERR, prefix,
+ len > 4 ? DUMP_PREFIX_OFFSET : DUMP_PREFIX_NONE,
+ 16, 4, phy->mmio + offset, len, false);
+}
+EXPORT_SYMBOL(ufs_qcom_phy_dump_regs);
+
+void ufs_qcom_phy_dbg_register_dump(struct phy *generic_phy)
+{
+ struct ufs_qcom_phy *ufs_qcom_phy = get_ufs_qcom_phy(generic_phy);
+
+ if (ufs_qcom_phy->phy_spec_ops->dbg_register_dump)
+ ufs_qcom_phy->phy_spec_ops->dbg_register_dump(ufs_qcom_phy);
+}
+EXPORT_SYMBOL(ufs_qcom_phy_dbg_register_dump);
diff --git a/drivers/power/qcom-charger/qpnp-smb2.c b/drivers/power/qcom-charger/qpnp-smb2.c
index 0be535194b49..f83b641bcc4f 100644
--- a/drivers/power/qcom-charger/qpnp-smb2.c
+++ b/drivers/power/qcom-charger/qpnp-smb2.c
@@ -588,6 +588,7 @@ static enum power_supply_property smb2_batt_props[] = {
POWER_SUPPLY_PROP_SYSTEM_TEMP_LEVEL,
POWER_SUPPLY_PROP_CHARGER_TEMP,
POWER_SUPPLY_PROP_CHARGER_TEMP_MAX,
+ POWER_SUPPLY_PROP_INPUT_CURRENT_LIMITED,
};
static int smb2_batt_get_prop(struct power_supply *psy,
@@ -625,6 +626,9 @@ static int smb2_batt_get_prop(struct power_supply *psy,
case POWER_SUPPLY_PROP_CHARGER_TEMP_MAX:
rc = smblib_get_prop_charger_temp_max(chg, val);
break;
+ case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMITED:
+ rc = smblib_get_prop_input_current_limited(chg, val);
+ break;
default:
pr_err("batt power supply prop %d not supported\n", psp);
return -EINVAL;
@@ -1121,7 +1125,7 @@ static struct smb2_irq_info smb2_irqs[] = {
{ "wdog-bark", NULL },
{ "aicl-fail", smblib_handle_debug },
{ "aicl-done", smblib_handle_debug },
- { "high-duty-cycle", smblib_handle_debug },
+ { "high-duty-cycle", smblib_handle_high_duty_cycle, true },
{ "input-current-limiting", smblib_handle_debug },
{ "temperature-change", smblib_handle_debug },
{ "switcher-power-ok", smblib_handle_debug },
diff --git a/drivers/power/qcom-charger/smb-lib.c b/drivers/power/qcom-charger/smb-lib.c
index ee4f65430d8b..21b330127369 100644
--- a/drivers/power/qcom-charger/smb-lib.c
+++ b/drivers/power/qcom-charger/smb-lib.c
@@ -988,6 +988,21 @@ int smblib_get_prop_system_temp_level(struct smb_charger *chg,
return 0;
}
+int smblib_get_prop_input_current_limited(struct smb_charger *chg,
+ union power_supply_propval *val)
+{
+ u8 stat;
+ int rc;
+
+ rc = smblib_read(chg, AICL_STATUS_REG, &stat);
+ if (rc < 0) {
+ dev_err(chg->dev, "Couldn't read AICL_STATUS rc=%d\n", rc);
+ return rc;
+ }
+ val->intval = (stat & SOFT_ILIMIT_BIT) || chg->is_hdc;
+ return 0;
+}
+
/***********************
* BATTERY PSY SETTERS *
***********************/
@@ -1965,6 +1980,17 @@ irqreturn_t smblib_handle_usb_typec_change(int irq, void *data)
return IRQ_HANDLED;
}
+irqreturn_t smblib_handle_high_duty_cycle(int irq, void *data)
+{
+ struct smb_irq_data *irq_data = data;
+ struct smb_charger *chg = irq_data->parent_data;
+
+ chg->is_hdc = true;
+ schedule_delayed_work(&chg->clear_hdc_work, msecs_to_jiffies(60));
+
+ return IRQ_HANDLED;
+}
+
/***************
* Work Queues *
***************/
@@ -2054,6 +2080,14 @@ done:
vote(chg->awake_votable, PL_VOTER, false, 0);
}
+static void clear_hdc_work(struct work_struct *work)
+{
+ struct smb_charger *chg = container_of(work, struct smb_charger,
+ clear_hdc_work.work);
+
+ chg->is_hdc = 0;
+}
+
static int smblib_create_votables(struct smb_charger *chg)
{
int rc = 0;
@@ -2194,6 +2228,7 @@ int smblib_init(struct smb_charger *chg)
INIT_DELAYED_WORK(&chg->hvdcp_detect_work, smblib_hvdcp_detect_work);
INIT_DELAYED_WORK(&chg->pl_taper_work, smblib_pl_taper_work);
INIT_DELAYED_WORK(&chg->step_soc_req_work, step_soc_req_work);
+ INIT_DELAYED_WORK(&chg->clear_hdc_work, clear_hdc_work);
chg->fake_capacity = -EINVAL;
switch (chg->mode) {
diff --git a/drivers/power/qcom-charger/smb-lib.h b/drivers/power/qcom-charger/smb-lib.h
index 1b0c221b4764..aeb1eb2c454f 100644
--- a/drivers/power/qcom-charger/smb-lib.h
+++ b/drivers/power/qcom-charger/smb-lib.h
@@ -145,6 +145,7 @@ struct smb_charger {
struct delayed_work ps_change_timeout_work;
struct delayed_work pl_taper_work;
struct delayed_work step_soc_req_work;
+ struct delayed_work clear_hdc_work;
/* cached status */
int voltage_min_uv;
@@ -159,6 +160,7 @@ struct smb_charger {
int fake_capacity;
bool step_chg_enabled;
+ bool is_hdc;
};
int smblib_read(struct smb_charger *chg, u16 addr, u8 *val);
@@ -202,6 +204,7 @@ irqreturn_t smblib_handle_usb_plugin(int irq, void *data);
irqreturn_t smblib_handle_usb_source_change(int irq, void *data);
irqreturn_t smblib_handle_icl_change(int irq, void *data);
irqreturn_t smblib_handle_usb_typec_change(int irq, void *data);
+irqreturn_t smblib_handle_high_duty_cycle(int irq, void *data);
int smblib_get_prop_input_suspend(struct smb_charger *chg,
union power_supply_propval *val);
@@ -217,6 +220,8 @@ int smblib_get_prop_batt_health(struct smb_charger *chg,
union power_supply_propval *val);
int smblib_get_prop_system_temp_level(struct smb_charger *chg,
union power_supply_propval *val);
+int smblib_get_prop_input_current_limited(struct smb_charger *chg,
+ union power_supply_propval *val);
int smblib_set_prop_input_suspend(struct smb_charger *chg,
const union power_supply_propval *val);
diff --git a/drivers/scsi/ufs/ufs-qcom.c b/drivers/scsi/ufs/ufs-qcom.c
index 23c32f2743c3..fde0d408d27e 100644
--- a/drivers/scsi/ufs/ufs-qcom.c
+++ b/drivers/scsi/ufs/ufs-qcom.c
@@ -2405,17 +2405,21 @@ void ufs_qcom_print_hw_debug_reg_all(struct ufs_hba *hba, void *priv,
static void ufs_qcom_enable_test_bus(struct ufs_qcom_host *host)
{
- if (host->dbg_print_en & UFS_QCOM_DBG_PRINT_TEST_BUS_EN)
+ if (host->dbg_print_en & UFS_QCOM_DBG_PRINT_TEST_BUS_EN) {
+ ufshcd_rmwl(host->hba, UFS_REG_TEST_BUS_EN,
+ UFS_REG_TEST_BUS_EN, REG_UFS_CFG1);
ufshcd_rmwl(host->hba, TEST_BUS_EN, TEST_BUS_EN, REG_UFS_CFG1);
- else
+ } else {
+ ufshcd_rmwl(host->hba, UFS_REG_TEST_BUS_EN, 0, REG_UFS_CFG1);
ufshcd_rmwl(host->hba, TEST_BUS_EN, 0, REG_UFS_CFG1);
+ }
}
static void ufs_qcom_get_default_testbus_cfg(struct ufs_qcom_host *host)
{
/* provide a legal default configuration */
- host->testbus.select_major = TSTBUS_UAWM;
- host->testbus.select_minor = 1;
+ host->testbus.select_major = TSTBUS_UNIPRO;
+ host->testbus.select_minor = 37;
}
static bool ufs_qcom_testbus_cfg_is_ok(struct ufs_qcom_host *host)
@@ -2432,7 +2436,7 @@ static bool ufs_qcom_testbus_cfg_is_ok(struct ufs_qcom_host *host)
* mappings of select_minor, since there is no harm in
* configuring a non-existent select_minor
*/
- if (host->testbus.select_minor > 0x1F) {
+ if (host->testbus.select_minor > 0xFF) {
dev_err(host->hba->dev,
"%s: 0x%05X is not a legal testbus option\n",
__func__, host->testbus.select_minor);
@@ -2501,7 +2505,8 @@ int ufs_qcom_testbus_config(struct ufs_qcom_host *host)
break;
case TSTBUS_UNIPRO:
reg = UFS_UNIPRO_CFG;
- offset = 1;
+ offset = 20;
+ mask = 0xFFF;
break;
/*
* No need for a default case, since
@@ -2520,6 +2525,11 @@ int ufs_qcom_testbus_config(struct ufs_qcom_host *host)
(u32)host->testbus.select_minor << offset,
reg);
ufs_qcom_enable_test_bus(host);
+ /*
+ * Make sure the test bus configuration is
+ * committed before returning.
+ */
+ mb();
ufshcd_release(host->hba, false);
pm_runtime_put_sync(host->hba->dev);
@@ -2531,15 +2541,44 @@ static void ufs_qcom_testbus_read(struct ufs_hba *hba)
ufs_qcom_dump_regs(hba, UFS_TEST_BUS, 1, "UFS_TEST_BUS ");
}
+static void ufs_qcom_print_unipro_testbus(struct ufs_hba *hba)
+{
+ struct ufs_qcom_host *host = ufshcd_get_variant(hba);
+ u32 *testbus = NULL;
+ int i, nminor = 256, testbus_len = nminor * sizeof(u32);
+
+ testbus = kmalloc(testbus_len, GFP_KERNEL);
+ if (!testbus)
+ return;
+
+ host->testbus.select_major = TSTBUS_UNIPRO;
+ for (i = 0; i < nminor; i++) {
+ host->testbus.select_minor = i;
+ ufs_qcom_testbus_config(host);
+ testbus[i] = ufshcd_readl(hba, UFS_TEST_BUS);
+ }
+ print_hex_dump(KERN_ERR, "UNIPRO_TEST_BUS ", DUMP_PREFIX_OFFSET,
+ 16, 4, testbus, testbus_len, false);
+ kfree(testbus);
+}
+
static void ufs_qcom_dump_dbg_regs(struct ufs_hba *hba)
{
struct ufs_qcom_host *host = ufshcd_get_variant(hba);
+ struct phy *phy = host->generic_phy;
ufs_qcom_dump_regs(hba, REG_UFS_SYS1CLK_1US, 16,
"HCI Vendor Specific Registers ");
+ /* sleep a bit intermittently as we are dumping too much data */
ufs_qcom_print_hw_debug_reg_all(hba, NULL, ufs_qcom_dump_regs_wrapper);
+ usleep_range(1000, 1100);
ufs_qcom_testbus_read(hba);
+ usleep_range(1000, 1100);
+ ufs_qcom_print_unipro_testbus(hba);
+ usleep_range(1000, 1100);
+ ufs_qcom_phy_dbg_register_dump(phy);
+ usleep_range(1000, 1100);
ufs_qcom_ice_print_regs(host);
}
diff --git a/drivers/scsi/ufs/ufs-qcom.h b/drivers/scsi/ufs/ufs-qcom.h
index ba36d9883a0f..394de8302fd2 100644
--- a/drivers/scsi/ufs/ufs-qcom.h
+++ b/drivers/scsi/ufs/ufs-qcom.h
@@ -100,6 +100,7 @@ enum {
#define QUNIPRO_SEL UFS_BIT(0)
#define TEST_BUS_EN BIT(18)
#define TEST_BUS_SEL GENMASK(22, 19)
+#define UFS_REG_TEST_BUS_EN BIT(30)
/* bit definitions for REG_UFS_CFG2 register */
#define UAWM_HW_CGC_EN (1 << 0)
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index a49b3c7bc4ef..d478767ad3dd 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -3932,8 +3932,12 @@ static int ufshcd_uic_pwr_ctrl(struct ufs_hba *hba, struct uic_command *cmd)
ret = (status != PWR_OK) ? status : -1;
}
out:
- if (ret)
+ if (ret) {
ufsdbg_set_err_state(hba);
+ ufshcd_print_host_state(hba);
+ ufshcd_print_pwr_info(hba);
+ ufshcd_print_host_regs(hba);
+ }
ufshcd_save_tstamp_of_last_dme_cmd(hba);
spin_lock_irqsave(hba->host->host_lock, flags);
@@ -4644,8 +4648,12 @@ link_startup:
ret = ufshcd_make_hba_operational(hba);
out:
- if (ret)
+ if (ret) {
dev_err(hba->dev, "link startup failed %d\n", ret);
+ ufshcd_print_host_state(hba);
+ ufshcd_print_pwr_info(hba);
+ ufshcd_print_host_regs(hba);
+ }
return ret;
}
diff --git a/drivers/slimbus/slim-msm-ngd.c b/drivers/slimbus/slim-msm-ngd.c
index fbde0d318584..9af9ce323bc3 100644
--- a/drivers/slimbus/slim-msm-ngd.c
+++ b/drivers/slimbus/slim-msm-ngd.c
@@ -228,6 +228,16 @@ static int dsp_domr_notify_cb(struct notifier_block *n, unsigned long code,
break;
case LOCATOR_UP:
reg = _cmd;
+ if (!reg || reg->total_domains != 1) {
+ SLIM_WARN(dev, "error locating audio-PD\n");
+ if (reg)
+ SLIM_WARN(dev, "audio-PDs matched:%d\n",
+ reg->total_domains);
+
+ /* Fall back to SSR */
+ ngd_reg_ssr(dev);
+ return NOTIFY_DONE;
+ }
dev->dsp.domr = service_notif_register_notifier(
reg->domain_list->name,
reg->domain_list->instance_id,
@@ -1493,8 +1503,7 @@ static int ngd_slim_rx_msgq_thread(void *data)
int retries = 0;
u8 wbuf[8];
- set_current_state(TASK_INTERRUPTIBLE);
- wait_for_completion(notify);
+ wait_for_completion_interruptible(notify);
txn.dt = SLIM_MSG_DEST_LOGICALADDR;
txn.ec = 0;
@@ -1555,8 +1564,7 @@ static int ngd_notify_slaves(void *data)
}
while (!kthread_should_stop()) {
- set_current_state(TASK_INTERRUPTIBLE);
- wait_for_completion(&dev->qmi.slave_notify);
+ wait_for_completion_interruptible(&dev->qmi.slave_notify);
/* Probe devices for first notification */
if (!i) {
i++;
diff --git a/drivers/soc/qcom/icnss.c b/drivers/soc/qcom/icnss.c
index aaca82f87159..05a9ff4aeb1c 100644
--- a/drivers/soc/qcom/icnss.c
+++ b/drivers/soc/qcom/icnss.c
@@ -34,6 +34,8 @@
#include <linux/qmi_encdec.h>
#include <linux/ipc_logging.h>
#include <linux/msm-bus.h>
+#include <linux/uaccess.h>
+#include <linux/qpnp/qpnp-adc.h>
#include <soc/qcom/memory_dump.h>
#include <soc/qcom/icnss.h>
#include <soc/qcom/msm_qmi_interface.h>
@@ -49,6 +51,7 @@
#define MAX_PROP_SIZE 32
#define NUM_LOG_PAGES 10
#define NUM_REG_LOG_PAGES 4
+#define ICNSS_MAGIC 0x5abc5abc
/*
* Registers: MPM2_PSHOLD
@@ -158,6 +161,10 @@
#define ICNSS_SERVICE_LOCATION_CLIENT_NAME "ICNSS-WLAN"
#define ICNSS_WLAN_SERVICE_NAME "wlan/fw"
+#define ICNSS_THRESHOLD_HIGH 3600000
+#define ICNSS_THRESHOLD_LOW 3450000
+#define ICNSS_THRESHOLD_GUARD 20000
+
#define icnss_ipc_log_string(_x...) do { \
if (icnss_ipc_log_context) \
ipc_log_string(icnss_ipc_log_context, _x); \
@@ -269,6 +276,8 @@ enum icnss_driver_state {
ICNSS_DRIVER_PROBED,
ICNSS_FW_TEST_MODE,
ICNSS_SUSPEND,
+ ICNSS_PM_SUSPEND,
+ ICNSS_PM_SUSPEND_NOIRQ,
ICNSS_SSR_ENABLED,
ICNSS_PDR_ENABLED,
ICNSS_PD_RESTART,
@@ -324,6 +333,15 @@ struct icnss_stats {
uint32_t disable;
} ce_irqs[ICNSS_MAX_IRQ_REGISTRATIONS];
+ uint32_t pm_suspend;
+ uint32_t pm_suspend_err;
+ uint32_t pm_resume;
+ uint32_t pm_resume_err;
+ uint32_t pm_suspend_noirq;
+ uint32_t pm_suspend_noirq_err;
+ uint32_t pm_resume_noirq;
+ uint32_t pm_resume_noirq_err;
+
uint32_t ind_register_req;
uint32_t ind_register_resp;
uint32_t ind_register_err;
@@ -347,9 +365,13 @@ struct icnss_stats {
uint32_t ini_req;
uint32_t ini_resp;
uint32_t ini_req_err;
+ uint32_t vbatt_req;
+ uint32_t vbatt_resp;
+ uint32_t vbatt_req_err;
};
static struct icnss_priv {
+ uint32_t magic;
struct platform_device *pdev;
struct icnss_driver_ops *ops;
struct ce_irq_list ce_irq_list[ICNSS_MAX_IRQ_REGISTRATIONS];
@@ -397,6 +419,14 @@ static struct icnss_priv {
void *modem_notify_handler;
struct notifier_block modem_ssr_nb;
struct wakeup_source ws;
+ uint32_t diag_reg_read_addr;
+ uint32_t diag_reg_read_mem_type;
+ uint32_t diag_reg_read_len;
+ uint8_t *diag_reg_read_buf;
+ struct qpnp_adc_tm_btm_param vph_monitor_params;
+ struct qpnp_adc_tm_chip *adc_tm_dev;
+ struct qpnp_vadc_chip *vadc_dev;
+ uint64_t vph_pwr;
} *penv;
static void icnss_hw_write_reg(void *base, u32 offset, u32 val)
@@ -546,6 +576,189 @@ static int icnss_driver_event_post(enum icnss_driver_event_type type,
return ret;
}
+static int wlfw_vbatt_send_sync_msg(struct icnss_priv *priv,
+ uint64_t voltage_uv)
+{
+ int ret;
+ struct wlfw_vbatt_req_msg_v01 req;
+ struct wlfw_vbatt_resp_msg_v01 resp;
+ struct msg_desc req_desc, resp_desc;
+
+ if (!priv->wlfw_clnt) {
+ ret = -ENODEV;
+ goto out;
+ }
+
+ icnss_pr_dbg("Sending Vbatt message, state: 0x%lx\n",
+ penv->state);
+
+ memset(&req, 0, sizeof(req));
+ memset(&resp, 0, sizeof(resp));
+
+ req.voltage_uv = voltage_uv;
+
+ req_desc.max_msg_len = WLFW_VBATT_REQ_MSG_V01_MAX_MSG_LEN;
+ req_desc.msg_id = QMI_WLFW_VBATT_REQ_V01;
+ req_desc.ei_array = wlfw_vbatt_req_msg_v01_ei;
+
+ resp_desc.max_msg_len = WLFW_VBATT_RESP_MSG_V01_MAX_MSG_LEN;
+ resp_desc.msg_id = QMI_WLFW_VBATT_RESP_V01;
+ resp_desc.ei_array = wlfw_vbatt_resp_msg_v01_ei;
+
+ priv->stats.vbatt_req++;
+
+ ret = qmi_send_req_wait(priv->wlfw_clnt, &req_desc, &req, sizeof(req),
+ &resp_desc, &resp, sizeof(resp), WLFW_TIMEOUT_MS);
+ if (ret < 0) {
+ icnss_pr_err("Send vbatt req failed %d\n", ret);
+ goto out;
+ }
+
+ if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
+ icnss_pr_err("QMI vbatt request failed %d %d\n",
+ resp.resp.result, resp.resp.error);
+ ret = resp.resp.result;
+ goto out;
+ }
+ priv->stats.vbatt_resp++;
+
+out:
+ priv->stats.vbatt_req_err++;
+ return ret;
+}
+
+static int icnss_get_phone_power(struct icnss_priv *priv, uint64_t *result_uv)
+{
+ int ret = 0;
+ struct qpnp_vadc_result adc_result;
+
+ if (!priv->vadc_dev) {
+ icnss_pr_err("VADC dev doesn't exists\n");
+ ret = -EINVAL;
+ goto out;
+ }
+
+ ret = qpnp_vadc_read(penv->vadc_dev, VADC_VPH_PWR, &adc_result);
+ if (ret) {
+ icnss_pr_err("Error reading ADC channel %d, ret = %d\n",
+ VADC_VPH_PWR, ret);
+ goto out;
+ }
+
+ icnss_pr_dbg("Phone power read phy=%lld meas=0x%llx\n",
+ adc_result.physical, adc_result.measurement);
+
+ *result_uv = adc_result.physical;
+out:
+ return ret;
+}
+
+static void icnss_vph_notify(enum qpnp_tm_state state, void *ctx)
+{
+ struct icnss_priv *priv = ctx;
+ uint64_t vph_pwr = 0;
+ uint64_t vph_pwr_prev;
+ int ret = 0;
+ bool update = true;
+
+ if (!priv) {
+ icnss_pr_err("Priv pointer is NULL\n");
+ return;
+ }
+
+ vph_pwr_prev = priv->vph_pwr;
+
+ ret = icnss_get_phone_power(priv, &vph_pwr);
+ if (ret)
+ return;
+
+ if (vph_pwr < ICNSS_THRESHOLD_LOW) {
+ if (vph_pwr_prev < ICNSS_THRESHOLD_LOW)
+ update = false;
+ priv->vph_monitor_params.state_request =
+ ADC_TM_HIGH_THR_ENABLE;
+ priv->vph_monitor_params.high_thr = ICNSS_THRESHOLD_LOW +
+ ICNSS_THRESHOLD_GUARD;
+ priv->vph_monitor_params.low_thr = 0;
+ } else if (vph_pwr > ICNSS_THRESHOLD_HIGH) {
+ if (vph_pwr_prev > ICNSS_THRESHOLD_HIGH)
+ update = false;
+ priv->vph_monitor_params.state_request =
+ ADC_TM_LOW_THR_ENABLE;
+ priv->vph_monitor_params.low_thr = ICNSS_THRESHOLD_HIGH -
+ ICNSS_THRESHOLD_GUARD;
+ priv->vph_monitor_params.high_thr = 0;
+ } else {
+ if (vph_pwr_prev > ICNSS_THRESHOLD_LOW &&
+ vph_pwr_prev < ICNSS_THRESHOLD_HIGH)
+ update = false;
+ priv->vph_monitor_params.state_request =
+ ADC_TM_HIGH_LOW_THR_ENABLE;
+ priv->vph_monitor_params.low_thr = ICNSS_THRESHOLD_LOW;
+ priv->vph_monitor_params.high_thr = ICNSS_THRESHOLD_HIGH;
+ }
+
+ priv->vph_pwr = vph_pwr;
+
+ if (update)
+ wlfw_vbatt_send_sync_msg(priv, vph_pwr);
+
+ icnss_pr_dbg("set low threshold to %d, high threshold to %d\n",
+ priv->vph_monitor_params.low_thr,
+ priv->vph_monitor_params.high_thr);
+ ret = qpnp_adc_tm_channel_measure(priv->adc_tm_dev,
+ &priv->vph_monitor_params);
+ if (ret)
+ icnss_pr_err("TM channel setup failed %d\n", ret);
+}
+
+static int icnss_setup_vph_monitor(struct icnss_priv *priv)
+{
+ int ret = 0;
+
+ if (!priv->adc_tm_dev) {
+ icnss_pr_err("ADC TM handler is NULL\n");
+ ret = -EINVAL;
+ goto out;
+ }
+
+ priv->vph_monitor_params.low_thr = ICNSS_THRESHOLD_LOW;
+ priv->vph_monitor_params.high_thr = ICNSS_THRESHOLD_HIGH;
+ priv->vph_monitor_params.state_request = ADC_TM_HIGH_LOW_THR_ENABLE;
+ priv->vph_monitor_params.channel = VADC_VPH_PWR;
+ priv->vph_monitor_params.btm_ctx = priv;
+ priv->vph_monitor_params.timer_interval = ADC_MEAS1_INTERVAL_1S;
+ priv->vph_monitor_params.threshold_notification = &icnss_vph_notify;
+ icnss_pr_dbg("Set low threshold to %d, high threshold to %d\n",
+ priv->vph_monitor_params.low_thr,
+ priv->vph_monitor_params.high_thr);
+
+ ret = qpnp_adc_tm_channel_measure(priv->adc_tm_dev,
+ &priv->vph_monitor_params);
+ if (ret)
+ icnss_pr_err("TM channel setup failed %d\n", ret);
+out:
+ return ret;
+}
+
+static int icnss_init_vph_monitor(struct icnss_priv *priv)
+{
+ int ret = 0;
+
+ ret = icnss_get_phone_power(priv, &priv->vph_pwr);
+ if (ret)
+ goto out;
+
+ wlfw_vbatt_send_sync_msg(priv, priv->vph_pwr);
+
+ ret = icnss_setup_vph_monitor(priv);
+ if (ret)
+ goto out;
+out:
+ return ret;
+}
+
+
static int icnss_qmi_pin_connect_result_ind(void *msg, unsigned int msg_len)
{
struct msg_desc ind_desc;
@@ -1777,6 +1990,127 @@ out:
return ret;
}
+static int wlfw_athdiag_read_send_sync_msg(struct icnss_priv *priv,
+ uint32_t offset, uint32_t mem_type,
+ uint32_t data_len, uint8_t *data)
+{
+ int ret;
+ struct wlfw_athdiag_read_req_msg_v01 req;
+ struct wlfw_athdiag_read_resp_msg_v01 *resp = NULL;
+ struct msg_desc req_desc, resp_desc;
+
+ if (!priv->wlfw_clnt) {
+ ret = -ENODEV;
+ goto out;
+ }
+
+ icnss_pr_dbg("Diag read: state 0x%lx, offset %x, mem_type %x, data_len %u\n",
+ priv->state, offset, mem_type, data_len);
+
+ resp = kzalloc(sizeof(*resp), GFP_KERNEL);
+ if (!resp) {
+ ret = -ENOMEM;
+ goto out;
+ }
+ memset(&req, 0, sizeof(req));
+
+ req.offset = offset;
+ req.mem_type = mem_type;
+ req.data_len = data_len;
+
+ req_desc.max_msg_len = WLFW_ATHDIAG_READ_REQ_MSG_V01_MAX_MSG_LEN;
+ req_desc.msg_id = QMI_WLFW_ATHDIAG_READ_REQ_V01;
+ req_desc.ei_array = wlfw_athdiag_read_req_msg_v01_ei;
+
+ resp_desc.max_msg_len = WLFW_ATHDIAG_READ_RESP_MSG_V01_MAX_MSG_LEN;
+ resp_desc.msg_id = QMI_WLFW_ATHDIAG_READ_RESP_V01;
+ resp_desc.ei_array = wlfw_athdiag_read_resp_msg_v01_ei;
+
+ ret = qmi_send_req_wait(penv->wlfw_clnt, &req_desc, &req, sizeof(req),
+ &resp_desc, resp, sizeof(*resp),
+ WLFW_TIMEOUT_MS);
+ if (ret < 0) {
+ icnss_pr_err("send athdiag read req failed %d\n", ret);
+ goto out;
+ }
+
+ if (resp->resp.result != QMI_RESULT_SUCCESS_V01) {
+ icnss_pr_err("QMI athdiag read request failed %d %d\n",
+ resp->resp.result, resp->resp.error);
+ ret = resp->resp.result;
+ goto out;
+ }
+
+ if (!resp->data_valid || resp->data_len <= data_len) {
+ icnss_pr_err("Athdiag read data is invalid, data_valid = %u, data_len = %u\n",
+ resp->data_valid, resp->data_len);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ memcpy(data, resp->data, resp->data_len);
+
+out:
+ kfree(resp);
+ return ret;
+}
+
+static int wlfw_athdiag_write_send_sync_msg(struct icnss_priv *priv,
+ uint32_t offset, uint32_t mem_type,
+ uint32_t data_len, uint8_t *data)
+{
+ int ret;
+ struct wlfw_athdiag_write_req_msg_v01 *req = NULL;
+ struct wlfw_athdiag_write_resp_msg_v01 resp;
+ struct msg_desc req_desc, resp_desc;
+
+ if (!priv->wlfw_clnt) {
+ ret = -ENODEV;
+ goto out;
+ }
+
+ icnss_pr_dbg("Diag write: state 0x%lx, offset %x, mem_type %x, data_len %u, data %p\n",
+ priv->state, offset, mem_type, data_len, data);
+
+ req = kzalloc(sizeof(*req), GFP_KERNEL);
+ if (!req) {
+ ret = -ENOMEM;
+ goto out;
+ }
+ memset(&resp, 0, sizeof(resp));
+
+ req->offset = offset;
+ req->mem_type = mem_type;
+ req->data_len = data_len;
+ memcpy(req->data, data, data_len);
+
+ req_desc.max_msg_len = WLFW_ATHDIAG_WRITE_REQ_MSG_V01_MAX_MSG_LEN;
+ req_desc.msg_id = QMI_WLFW_ATHDIAG_WRITE_REQ_V01;
+ req_desc.ei_array = wlfw_athdiag_write_req_msg_v01_ei;
+
+ resp_desc.max_msg_len = WLFW_ATHDIAG_WRITE_RESP_MSG_V01_MAX_MSG_LEN;
+ resp_desc.msg_id = QMI_WLFW_ATHDIAG_WRITE_RESP_V01;
+ resp_desc.ei_array = wlfw_athdiag_write_resp_msg_v01_ei;
+
+ ret = qmi_send_req_wait(penv->wlfw_clnt, &req_desc, req, sizeof(*req),
+ &resp_desc, &resp, sizeof(resp),
+ WLFW_TIMEOUT_MS);
+ if (ret < 0) {
+ icnss_pr_err("send athdiag write req failed %d\n", ret);
+ goto out;
+ }
+
+ if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
+ icnss_pr_err("QMI athdiag write request failed %d %d\n",
+ resp.resp.result, resp.resp.error);
+ ret = resp.resp.result;
+ goto out;
+ }
+out:
+ kfree(req);
+ return ret;
+}
+
static void icnss_qmi_wlfw_clnt_notify_work(struct work_struct *work)
{
int ret;
@@ -1907,6 +2241,8 @@ static int icnss_driver_event_server_arrive(void *data)
if (ret < 0)
goto err_setup_msa;
+ icnss_init_vph_monitor(penv);
+
return ret;
err_setup_msa:
@@ -1928,6 +2264,10 @@ static int icnss_driver_event_server_exit(void *data)
icnss_pr_info("QMI Service Disconnected: 0x%lx\n", penv->state);
+ if (penv->adc_tm_dev)
+ qpnp_adc_tm_disable_chan_meas(penv->adc_tm_dev,
+ &penv->vph_monitor_params);
+
qmi_handle_destroy(penv->wlfw_clnt);
clear_bit(ICNSS_WLFW_QMI_CONNECTED, &penv->state);
@@ -2677,6 +3017,78 @@ int icnss_set_fw_debug_mode(bool enable_fw_log)
}
EXPORT_SYMBOL(icnss_set_fw_debug_mode);
+int icnss_athdiag_read(struct device *dev, uint32_t offset,
+ uint32_t mem_type, uint32_t data_len,
+ uint8_t *output)
+{
+ int ret = 0;
+ struct icnss_priv *priv = dev_get_drvdata(dev);
+
+ if (priv->magic != ICNSS_MAGIC) {
+ icnss_pr_err("Invalid drvdata for diag read: dev %p, data %p, magic 0x%x\n",
+ dev, priv, priv->magic);
+ return -EINVAL;
+ }
+
+ if (!output || data_len == 0
+ || data_len > QMI_WLFW_MAX_DATA_SIZE_V01) {
+ icnss_pr_err("Invalid parameters for diag read: output %p, data_len %u\n",
+ output, data_len);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ if (!test_bit(ICNSS_FW_READY, &priv->state) ||
+ !test_bit(ICNSS_POWER_ON, &priv->state)) {
+ icnss_pr_err("Invalid state for diag read: 0x%lx\n",
+ priv->state);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ ret = wlfw_athdiag_read_send_sync_msg(priv, offset, mem_type,
+ data_len, output);
+out:
+ return ret;
+}
+EXPORT_SYMBOL(icnss_athdiag_read);
+
+int icnss_athdiag_write(struct device *dev, uint32_t offset,
+ uint32_t mem_type, uint32_t data_len,
+ uint8_t *input)
+{
+ int ret = 0;
+ struct icnss_priv *priv = dev_get_drvdata(dev);
+
+ if (priv->magic != ICNSS_MAGIC) {
+ icnss_pr_err("Invalid drvdata for diag write: dev %p, data %p, magic 0x%x\n",
+ dev, priv, priv->magic);
+ return -EINVAL;
+ }
+
+ if (!input || data_len == 0
+ || data_len > QMI_WLFW_MAX_DATA_SIZE_V01) {
+ icnss_pr_err("Invalid parameters for diag write: input %p, data_len %u\n",
+ input, data_len);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ if (!test_bit(ICNSS_FW_READY, &priv->state) ||
+ !test_bit(ICNSS_POWER_ON, &priv->state)) {
+ icnss_pr_err("Invalid state for diag write: 0x%lx\n",
+ priv->state);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ ret = wlfw_athdiag_write_send_sync_msg(priv, offset, mem_type,
+ data_len, input);
+out:
+ return ret;
+}
+EXPORT_SYMBOL(icnss_athdiag_write);
+
int icnss_wlan_enable(struct icnss_wlan_enable_cfg *config,
enum icnss_driver_mode mode,
const char *host_version)
@@ -3302,6 +3714,12 @@ static int icnss_stats_show_state(struct seq_file *s, struct icnss_priv *priv)
case ICNSS_FW_TEST_MODE:
seq_puts(s, "FW TEST MODE");
continue;
+ case ICNSS_PM_SUSPEND:
+ seq_puts(s, "PM SUSPEND");
+ continue;
+ case ICNSS_PM_SUSPEND_NOIRQ:
+ seq_puts(s, "PM SUSPEND_NOIRQ");
+ continue;
case ICNSS_SSR_ENABLED:
seq_puts(s, "SSR ENABLED");
continue;
@@ -3401,6 +3819,19 @@ static int icnss_stats_show(struct seq_file *s, void *data)
ICNSS_STATS_DUMP(s, priv, ini_req);
ICNSS_STATS_DUMP(s, priv, ini_resp);
ICNSS_STATS_DUMP(s, priv, ini_req_err);
+ ICNSS_STATS_DUMP(s, priv, vbatt_req);
+ ICNSS_STATS_DUMP(s, priv, vbatt_resp);
+ ICNSS_STATS_DUMP(s, priv, vbatt_req_err);
+
+ seq_puts(s, "\n<------------------ PM stats ------------------->\n");
+ ICNSS_STATS_DUMP(s, priv, pm_suspend);
+ ICNSS_STATS_DUMP(s, priv, pm_suspend_err);
+ ICNSS_STATS_DUMP(s, priv, pm_resume);
+ ICNSS_STATS_DUMP(s, priv, pm_resume_err);
+ ICNSS_STATS_DUMP(s, priv, pm_suspend_noirq);
+ ICNSS_STATS_DUMP(s, priv, pm_suspend_noirq_err);
+ ICNSS_STATS_DUMP(s, priv, pm_resume_noirq);
+ ICNSS_STATS_DUMP(s, priv, pm_resume_noirq_err);
icnss_stats_show_irqs(s, priv);
@@ -3428,6 +3859,207 @@ static const struct file_operations icnss_stats_fops = {
.llseek = seq_lseek,
};
+static int icnss_regwrite_show(struct seq_file *s, void *data)
+{
+ struct icnss_priv *priv = s->private;
+
+ seq_puts(s, "\nUsage: echo <mem_type> <offset> <reg_val> > <debugfs>/icnss/reg_write\n");
+
+ if (!test_bit(ICNSS_FW_READY, &priv->state))
+ seq_puts(s, "Firmware is not ready yet!, wait for FW READY\n");
+
+ return 0;
+}
+
+static ssize_t icnss_regwrite_write(struct file *fp,
+ const char __user *user_buf,
+ size_t count, loff_t *off)
+{
+ struct icnss_priv *priv =
+ ((struct seq_file *)fp->private_data)->private;
+ char buf[64];
+ char *sptr, *token;
+ unsigned int len = 0;
+ uint32_t reg_offset, mem_type, reg_val;
+ const char *delim = " ";
+ int ret = 0;
+
+ if (!test_bit(ICNSS_FW_READY, &priv->state) ||
+ !test_bit(ICNSS_POWER_ON, &priv->state))
+ return -EINVAL;
+
+ len = min(count, sizeof(buf) - 1);
+ if (copy_from_user(buf, user_buf, len))
+ return -EFAULT;
+
+ buf[len] = '\0';
+ sptr = buf;
+
+ token = strsep(&sptr, delim);
+ if (!token)
+ return -EINVAL;
+
+ if (!sptr)
+ return -EINVAL;
+
+ if (kstrtou32(token, 0, &mem_type))
+ return -EINVAL;
+
+ token = strsep(&sptr, delim);
+ if (!token)
+ return -EINVAL;
+
+ if (!sptr)
+ return -EINVAL;
+
+ if (kstrtou32(token, 0, &reg_offset))
+ return -EINVAL;
+
+ token = strsep(&sptr, delim);
+ if (!token)
+ return -EINVAL;
+
+ if (kstrtou32(token, 0, &reg_val))
+ return -EINVAL;
+
+ ret = wlfw_athdiag_write_send_sync_msg(priv, reg_offset, mem_type,
+ sizeof(uint32_t),
+ (uint8_t *)&reg_val);
+ if (ret)
+ return ret;
+
+ return count;
+}
+
+static int icnss_regwrite_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, icnss_regwrite_show, inode->i_private);
+}
+
+static const struct file_operations icnss_regwrite_fops = {
+ .read = seq_read,
+ .write = icnss_regwrite_write,
+ .open = icnss_regwrite_open,
+ .owner = THIS_MODULE,
+ .llseek = seq_lseek,
+};
+
+static int icnss_regread_show(struct seq_file *s, void *data)
+{
+ struct icnss_priv *priv = s->private;
+
+ if (!priv->diag_reg_read_buf) {
+ seq_puts(s, "Usage: echo <mem_type> <offset> <data_len> > <debugfs>/icnss/reg_read\n");
+
+ if (!test_bit(ICNSS_FW_READY, &priv->state))
+ seq_puts(s, "Firmware is not ready yet!, wait for FW READY\n");
+
+ return 0;
+ }
+
+ seq_printf(s, "REGREAD: Addr 0x%x Type 0x%x Length 0x%x\n",
+ priv->diag_reg_read_addr, priv->diag_reg_read_mem_type,
+ priv->diag_reg_read_len);
+
+ seq_hex_dump(s, "", DUMP_PREFIX_OFFSET, 32, 4, priv->diag_reg_read_buf,
+ priv->diag_reg_read_len, false);
+
+ priv->diag_reg_read_len = 0;
+ kfree(priv->diag_reg_read_buf);
+ priv->diag_reg_read_buf = NULL;
+
+ return 0;
+}
+
+static ssize_t icnss_regread_write(struct file *fp, const char __user *user_buf,
+ size_t count, loff_t *off)
+{
+ struct icnss_priv *priv =
+ ((struct seq_file *)fp->private_data)->private;
+ char buf[64];
+ char *sptr, *token;
+ unsigned int len = 0;
+ uint32_t reg_offset, mem_type;
+ uint32_t data_len = 0;
+ uint8_t *reg_buf = NULL;
+ const char *delim = " ";
+ int ret = 0;
+
+ if (!test_bit(ICNSS_FW_READY, &priv->state) ||
+ !test_bit(ICNSS_POWER_ON, &priv->state))
+ return -EINVAL;
+
+ len = min(count, sizeof(buf) - 1);
+ if (copy_from_user(buf, user_buf, len))
+ return -EFAULT;
+
+ buf[len] = '\0';
+ sptr = buf;
+
+ token = strsep(&sptr, delim);
+ if (!token)
+ return -EINVAL;
+
+ if (!sptr)
+ return -EINVAL;
+
+ if (kstrtou32(token, 0, &mem_type))
+ return -EINVAL;
+
+ token = strsep(&sptr, delim);
+ if (!token)
+ return -EINVAL;
+
+ if (!sptr)
+ return -EINVAL;
+
+ if (kstrtou32(token, 0, &reg_offset))
+ return -EINVAL;
+
+ token = strsep(&sptr, delim);
+ if (!token)
+ return -EINVAL;
+
+ if (kstrtou32(token, 0, &data_len))
+ return -EINVAL;
+
+ if (data_len == 0 ||
+ data_len > QMI_WLFW_MAX_DATA_SIZE_V01)
+ return -EINVAL;
+
+ reg_buf = kzalloc(data_len, GFP_KERNEL);
+ if (!reg_buf)
+ return -ENOMEM;
+
+ ret = wlfw_athdiag_read_send_sync_msg(priv, reg_offset,
+ mem_type, data_len,
+ reg_buf);
+ if (ret) {
+ kfree(reg_buf);
+ return ret;
+ }
+
+ priv->diag_reg_read_addr = reg_offset;
+ priv->diag_reg_read_mem_type = mem_type;
+ priv->diag_reg_read_len = data_len;
+ priv->diag_reg_read_buf = reg_buf;
+
+ return count;
+}
+
+static int icnss_regread_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, icnss_regread_show, inode->i_private);
+}
+
+static const struct file_operations icnss_regread_fops = {
+ .read = seq_read,
+ .write = icnss_regread_write,
+ .open = icnss_regread_open,
+ .owner = THIS_MODULE,
+ .llseek = seq_lseek,
+};
+
static int icnss_debugfs_create(struct icnss_priv *priv)
{
int ret = 0;
@@ -3448,6 +4080,10 @@ static int icnss_debugfs_create(struct icnss_priv *priv)
debugfs_create_file("stats", 0644, root_dentry, priv,
&icnss_stats_fops);
+ debugfs_create_file("reg_read", 0600, root_dentry, priv,
+ &icnss_regread_fops);
+ debugfs_create_file("reg_write", 0644, root_dentry, priv,
+ &icnss_regwrite_fops);
out:
return ret;
@@ -3458,6 +4094,44 @@ static void icnss_debugfs_destroy(struct icnss_priv *priv)
debugfs_remove_recursive(priv->root_dentry);
}
+static int icnss_get_vbatt_info(struct icnss_priv *priv)
+{
+ struct qpnp_adc_tm_chip *adc_tm_dev = NULL;
+ struct qpnp_vadc_chip *vadc_dev = NULL;
+ int ret = 0;
+
+ adc_tm_dev = qpnp_get_adc_tm(&priv->pdev->dev, "icnss");
+ if (PTR_ERR(adc_tm_dev) == -EPROBE_DEFER) {
+ icnss_pr_err("adc_tm_dev probe defer\n");
+ return -EPROBE_DEFER;
+ }
+
+ if (IS_ERR(adc_tm_dev)) {
+ ret = PTR_ERR(adc_tm_dev);
+ icnss_pr_err("Not able to get ADC dev, VBATT monitoring is disabled: %d\n",
+ ret);
+ return ret;
+ }
+
+ vadc_dev = qpnp_get_vadc(&priv->pdev->dev, "icnss");
+ if (PTR_ERR(vadc_dev) == -EPROBE_DEFER) {
+ icnss_pr_err("vadc_dev probe defer\n");
+ return -EPROBE_DEFER;
+ }
+
+ if (IS_ERR(vadc_dev)) {
+ ret = PTR_ERR(vadc_dev);
+ icnss_pr_err("Not able to get VADC dev, VBATT monitoring is disabled: %d\n",
+ ret);
+ return ret;
+ }
+
+ priv->adc_tm_dev = adc_tm_dev;
+ priv->vadc_dev = vadc_dev;
+
+ return 0;
+}
+
static int icnss_probe(struct platform_device *pdev)
{
int ret = 0;
@@ -3477,10 +4151,15 @@ static int icnss_probe(struct platform_device *pdev)
if (!priv)
return -ENOMEM;
+ priv->magic = ICNSS_MAGIC;
dev_set_drvdata(dev, priv);
priv->pdev = pdev;
+ ret = icnss_get_vbatt_info(priv);
+ if (ret == -EPROBE_DEFER)
+ goto out;
+
memcpy(priv->vreg_info, icnss_vreg_info, sizeof(icnss_vreg_info));
for (i = 0; i < ICNSS_VREG_INFO_SIZE; i++) {
ret = icnss_get_vreg_info(dev, &priv->vreg_info[i]);
@@ -3725,6 +4404,131 @@ out:
return ret;
}
+#ifdef CONFIG_PM_SLEEP
+static int icnss_pm_suspend(struct device *dev)
+{
+ struct icnss_priv *priv = dev_get_drvdata(dev);
+ int ret = 0;
+
+ if (priv->magic != ICNSS_MAGIC) {
+ icnss_pr_err("Invalid drvdata for pm suspend: dev %p, data %p, magic 0x%x\n",
+ dev, priv, priv->magic);
+ return -EINVAL;
+ }
+
+ icnss_pr_dbg("PM Suspend, state: 0x%lx\n", priv->state);
+
+ if (!priv->ops || !priv->ops->pm_suspend ||
+ !test_bit(ICNSS_DRIVER_PROBED, &priv->state))
+ goto out;
+
+ ret = priv->ops->pm_suspend(dev);
+
+out:
+ if (ret == 0) {
+ priv->stats.pm_suspend++;
+ set_bit(ICNSS_PM_SUSPEND, &priv->state);
+ } else {
+ priv->stats.pm_suspend_err++;
+ }
+ return ret;
+}
+
+static int icnss_pm_resume(struct device *dev)
+{
+ struct icnss_priv *priv = dev_get_drvdata(dev);
+ int ret = 0;
+
+ if (priv->magic != ICNSS_MAGIC) {
+ icnss_pr_err("Invalid drvdata for pm resume: dev %p, data %p, magic 0x%x\n",
+ dev, priv, priv->magic);
+ return -EINVAL;
+ }
+
+ icnss_pr_dbg("PM resume, state: 0x%lx\n", priv->state);
+
+ if (!priv->ops || !priv->ops->pm_resume ||
+ !test_bit(ICNSS_DRIVER_PROBED, &priv->state))
+ goto out;
+
+ ret = priv->ops->pm_resume(dev);
+
+out:
+ if (ret == 0) {
+ priv->stats.pm_resume++;
+ clear_bit(ICNSS_PM_SUSPEND, &priv->state);
+ } else {
+ priv->stats.pm_resume_err++;
+ }
+ return ret;
+}
+
+static int icnss_pm_suspend_noirq(struct device *dev)
+{
+ struct icnss_priv *priv = dev_get_drvdata(dev);
+ int ret = 0;
+
+ if (priv->magic != ICNSS_MAGIC) {
+ icnss_pr_err("Invalid drvdata for pm suspend_noirq: dev %p, data %p, magic 0x%x\n",
+ dev, priv, priv->magic);
+ return -EINVAL;
+ }
+
+ icnss_pr_dbg("PM suspend_noirq, state: 0x%lx\n", priv->state);
+
+ if (!priv->ops || !priv->ops->suspend_noirq ||
+ !test_bit(ICNSS_DRIVER_PROBED, &priv->state))
+ goto out;
+
+ ret = priv->ops->suspend_noirq(dev);
+
+out:
+ if (ret == 0) {
+ priv->stats.pm_suspend_noirq++;
+ set_bit(ICNSS_PM_SUSPEND_NOIRQ, &priv->state);
+ } else {
+ priv->stats.pm_suspend_noirq_err++;
+ }
+ return ret;
+}
+
+static int icnss_pm_resume_noirq(struct device *dev)
+{
+ struct icnss_priv *priv = dev_get_drvdata(dev);
+ int ret = 0;
+
+ if (priv->magic != ICNSS_MAGIC) {
+ icnss_pr_err("Invalid drvdata for pm resume_noirq: dev %p, data %p, magic 0x%x\n",
+ dev, priv, priv->magic);
+ return -EINVAL;
+ }
+
+ icnss_pr_dbg("PM resume_noirq, state: 0x%lx\n", priv->state);
+
+ if (!priv->ops || !priv->ops->resume_noirq ||
+ !test_bit(ICNSS_DRIVER_PROBED, &priv->state))
+ goto out;
+
+ ret = priv->ops->resume_noirq(dev);
+
+out:
+ if (ret == 0) {
+ priv->stats.pm_resume_noirq++;
+ clear_bit(ICNSS_PM_SUSPEND_NOIRQ, &priv->state);
+ } else {
+ priv->stats.pm_resume_noirq_err++;
+ }
+ return ret;
+}
+#endif
+
+static const struct dev_pm_ops icnss_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(icnss_pm_suspend,
+ icnss_pm_resume)
+ SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(icnss_pm_suspend_noirq,
+ icnss_pm_resume_noirq)
+};
+
static const struct of_device_id icnss_dt_match[] = {
{.compatible = "qcom,icnss"},
{}
@@ -3739,6 +4543,7 @@ static struct platform_driver icnss_driver = {
.resume = icnss_resume,
.driver = {
.name = "icnss",
+ .pm = &icnss_pm_ops,
.owner = THIS_MODULE,
.of_match_table = icnss_dt_match,
},
diff --git a/drivers/soc/qcom/memshare/msm_memshare.c b/drivers/soc/qcom/memshare/msm_memshare.c
index f44f6f97ecdd..e1e91f56526d 100644
--- a/drivers/soc/qcom/memshare/msm_memshare.c
+++ b/drivers/soc/qcom/memshare/msm_memshare.c
@@ -203,6 +203,7 @@ static int modem_notifier_cb(struct notifier_block *this, unsigned long code,
int dest_vmids[1] = {VMID_HLOS};
int dest_perms[1] = {PERM_READ|PERM_WRITE};
+ mutex_lock(&memsh_drv->mem_share);
switch (code) {
case SUBSYS_BEFORE_SHUTDOWN:
@@ -264,6 +265,7 @@ static int modem_notifier_cb(struct notifier_block *this, unsigned long code,
break;
}
+ mutex_unlock(&memsh_drv->mem_share);
return NOTIFY_DONE;
}
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
index 38ae877c46e3..3ffb01ff6549 100644
--- a/drivers/usb/core/devio.c
+++ b/drivers/usb/core/devio.c
@@ -1203,10 +1203,11 @@ static int proc_getdriver(struct usb_dev_state *ps, void __user *arg)
static int proc_connectinfo(struct usb_dev_state *ps, void __user *arg)
{
- struct usbdevfs_connectinfo ci = {
- .devnum = ps->dev->devnum,
- .slow = ps->dev->speed == USB_SPEED_LOW
- };
+ struct usbdevfs_connectinfo ci;
+
+ memset(&ci, 0, sizeof(ci));
+ ci.devnum = ps->dev->devnum;
+ ci.slow = ps->dev->speed == USB_SPEED_LOW;
if (copy_to_user(arg, &ci, sizeof(ci)))
return -EFAULT;
diff --git a/drivers/video/fbdev/msm/mdss.h b/drivers/video/fbdev/msm/mdss.h
index 4724f4378e23..609a7aed4977 100644
--- a/drivers/video/fbdev/msm/mdss.h
+++ b/drivers/video/fbdev/msm/mdss.h
@@ -191,6 +191,7 @@ enum mdss_qos_settings {
MDSS_QOS_TS_PREFILL,
MDSS_QOS_REMAPPER,
MDSS_QOS_IB_NOCR,
+ MDSS_QOS_WB2_WRITE_GATHER_EN,
MDSS_QOS_MAX,
};
diff --git a/drivers/video/fbdev/msm/mdss_mdp.c b/drivers/video/fbdev/msm/mdss_mdp.c
index cd842cecc945..1b5c1b7d51e1 100644
--- a/drivers/video/fbdev/msm/mdss_mdp.c
+++ b/drivers/video/fbdev/msm/mdss_mdp.c
@@ -1984,6 +1984,7 @@ static void mdss_mdp_hw_rev_caps_init(struct mdss_data_type *mdata)
set_bit(MDSS_QOS_SIMPLIFIED_PREFILL, mdata->mdss_qos_map);
set_bit(MDSS_QOS_TS_PREFILL, mdata->mdss_qos_map);
set_bit(MDSS_QOS_IB_NOCR, mdata->mdss_qos_map);
+ set_bit(MDSS_QOS_WB2_WRITE_GATHER_EN, mdata->mdss_qos_map);
set_bit(MDSS_CAPS_YUV_CONFIG, mdata->mdss_caps_map);
set_bit(MDSS_CAPS_SCM_RESTORE_NOT_REQUIRED,
mdata->mdss_caps_map);
diff --git a/drivers/video/fbdev/msm/mdss_mdp_hwio.h b/drivers/video/fbdev/msm/mdss_mdp_hwio.h
index f54cbb575535..5d8c83126b1b 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_hwio.h
+++ b/drivers/video/fbdev/msm/mdss_mdp_hwio.h
@@ -829,6 +829,7 @@ enum mdss_mdp_pingpong_index {
#define MMSS_VBIF_CLKON 0x4
#define MMSS_VBIF_RD_LIM_CONF 0x0B0
#define MMSS_VBIF_WR_LIM_CONF 0x0C0
+#define MDSS_VBIF_WRITE_GATHER_EN 0x0AC
#define MMSS_VBIF_XIN_HALT_CTRL0 0x200
#define MMSS_VBIF_XIN_HALT_CTRL1 0x204
diff --git a/drivers/video/fbdev/msm/mdss_mdp_intf_writeback.c b/drivers/video/fbdev/msm/mdss_mdp_intf_writeback.c
index 9026b99cd87a..40b10e368309 100644
--- a/drivers/video/fbdev/msm/mdss_mdp_intf_writeback.c
+++ b/drivers/video/fbdev/msm/mdss_mdp_intf_writeback.c
@@ -488,6 +488,10 @@ int mdss_mdp_writeback_prepare_cwb(struct mdss_mdp_ctl *ctl,
mdss_mdp_writeback_cwb_overflow, sctl);
}
+ if (test_bit(MDSS_QOS_WB2_WRITE_GATHER_EN, ctl->mdata->mdss_qos_map))
+ MDSS_VBIF_WRITE(ctl->mdata, MDSS_VBIF_WRITE_GATHER_EN,
+ BIT(6), false);
+
if (ctl->mdata->default_ot_wr_limit || ctl->mdata->default_ot_rd_limit)
mdss_mdp_set_ot_limit_wb(ctx, false);
@@ -907,6 +911,10 @@ static int mdss_mdp_writeback_display(struct mdss_mdp_ctl *ctl, void *arg)
return ret;
}
+ if (test_bit(MDSS_QOS_WB2_WRITE_GATHER_EN, ctl->mdata->mdss_qos_map))
+ MDSS_VBIF_WRITE(ctl->mdata, MDSS_VBIF_WRITE_GATHER_EN,
+ BIT(6), false);
+
mdss_mdp_set_intr_callback(ctx->intr_type, ctx->intf_num,
mdss_mdp_writeback_intr_done, ctl);
diff --git a/fs/ext4/crypto.c b/fs/ext4/crypto.c
index 1acac7fd21b2..032d0b9bb324 100644
--- a/fs/ext4/crypto.c
+++ b/fs/ext4/crypto.c
@@ -93,7 +93,8 @@ void ext4_release_crypto_ctx(struct ext4_crypto_ctx *ctx)
* Return: An allocated and initialized encryption context on success; error
* value or NULL otherwise.
*/
-struct ext4_crypto_ctx *ext4_get_crypto_ctx(struct inode *inode)
+struct ext4_crypto_ctx *ext4_get_crypto_ctx(struct inode *inode,
+ gfp_t gfp_flags)
{
struct ext4_crypto_ctx *ctx = NULL;
int res = 0;
@@ -120,7 +121,7 @@ struct ext4_crypto_ctx *ext4_get_crypto_ctx(struct inode *inode)
list_del(&ctx->free_list);
spin_unlock_irqrestore(&ext4_crypto_ctx_lock, flags);
if (!ctx) {
- ctx = kmem_cache_zalloc(ext4_crypto_ctx_cachep, GFP_NOFS);
+ ctx = kmem_cache_zalloc(ext4_crypto_ctx_cachep, gfp_flags);
if (!ctx) {
res = -ENOMEM;
goto out;
@@ -257,7 +258,8 @@ static int ext4_page_crypto(struct inode *inode,
ext4_direction_t rw,
pgoff_t index,
struct page *src_page,
- struct page *dest_page)
+ struct page *dest_page,
+ gfp_t gfp_flags)
{
u8 xts_tweak[EXT4_XTS_TWEAK_SIZE];
@@ -309,9 +311,10 @@ static int ext4_page_crypto(struct inode *inode,
return 0;
}
-static struct page *alloc_bounce_page(struct ext4_crypto_ctx *ctx)
+static struct page *alloc_bounce_page(struct ext4_crypto_ctx *ctx,
+ gfp_t gfp_flags)
{
- ctx->w.bounce_page = mempool_alloc(ext4_bounce_page_pool, GFP_NOWAIT);
+ ctx->w.bounce_page = mempool_alloc(ext4_bounce_page_pool, gfp_flags);
if (ctx->w.bounce_page == NULL)
return ERR_PTR(-ENOMEM);
ctx->flags |= EXT4_WRITE_PATH_FL;
@@ -334,7 +337,8 @@ static struct page *alloc_bounce_page(struct ext4_crypto_ctx *ctx)
* error value or NULL.
*/
struct page *ext4_encrypt(struct inode *inode,
- struct page *plaintext_page)
+ struct page *plaintext_page,
+ gfp_t gfp_flags)
{
struct ext4_crypto_ctx *ctx;
struct page *ciphertext_page = NULL;
@@ -342,17 +346,17 @@ struct page *ext4_encrypt(struct inode *inode,
BUG_ON(!PageLocked(plaintext_page));
- ctx = ext4_get_crypto_ctx(inode);
+ ctx = ext4_get_crypto_ctx(inode, gfp_flags);
if (IS_ERR(ctx))
return (struct page *) ctx;
/* The encryption operation will require a bounce page. */
- ciphertext_page = alloc_bounce_page(ctx);
+ ciphertext_page = alloc_bounce_page(ctx, gfp_flags);
if (IS_ERR(ciphertext_page))
goto errout;
ctx->w.control_page = plaintext_page;
err = ext4_page_crypto(inode, EXT4_ENCRYPT, plaintext_page->index,
- plaintext_page, ciphertext_page);
+ plaintext_page, ciphertext_page, gfp_flags);
if (err) {
ciphertext_page = ERR_PTR(err);
errout:
@@ -380,8 +384,8 @@ int ext4_decrypt(struct page *page)
{
BUG_ON(!PageLocked(page));
- return ext4_page_crypto(page->mapping->host,
- EXT4_DECRYPT, page->index, page, page);
+ return ext4_page_crypto(page->mapping->host, EXT4_DECRYPT,
+ page->index, page, page, GFP_NOFS);
}
int ext4_encrypted_zeroout(struct inode *inode, struct ext4_extent *ex)
@@ -402,11 +406,11 @@ int ext4_encrypted_zeroout(struct inode *inode, struct ext4_extent *ex)
BUG_ON(inode->i_sb->s_blocksize != PAGE_CACHE_SIZE);
- ctx = ext4_get_crypto_ctx(inode);
+ ctx = ext4_get_crypto_ctx(inode, GFP_NOFS);
if (IS_ERR(ctx))
return PTR_ERR(ctx);
- ciphertext_page = alloc_bounce_page(ctx);
+ ciphertext_page = alloc_bounce_page(ctx, GFP_NOWAIT);
if (IS_ERR(ciphertext_page)) {
err = PTR_ERR(ciphertext_page);
goto errout;
@@ -414,11 +418,12 @@ int ext4_encrypted_zeroout(struct inode *inode, struct ext4_extent *ex)
while (len--) {
err = ext4_page_crypto(inode, EXT4_ENCRYPT, lblk,
- ZERO_PAGE(0), ciphertext_page);
+ ZERO_PAGE(0), ciphertext_page,
+ GFP_NOFS);
if (err)
goto errout;
- bio = bio_alloc(GFP_KERNEL, 1);
+ bio = bio_alloc(GFP_NOWAIT, 1);
if (!bio) {
err = -ENOMEM;
goto errout;
@@ -477,13 +482,16 @@ uint32_t ext4_validate_encryption_key_size(uint32_t mode, uint32_t size)
*/
static int ext4_d_revalidate(struct dentry *dentry, unsigned int flags)
{
- struct inode *dir = d_inode(dentry->d_parent);
- struct ext4_crypt_info *ci = EXT4_I(dir)->i_crypt_info;
+ struct dentry *dir;
+ struct ext4_crypt_info *ci;
int dir_has_key, cached_with_key;
- if (!ext4_encrypted_inode(dir))
+ dir = dget_parent(dentry);
+ if (!ext4_encrypted_inode(d_inode(dir))) {
+ dput(dir);
return 0;
-
+ }
+ ci = EXT4_I(d_inode(dir))->i_crypt_info;
if (ci && ci->ci_keyring_key &&
(ci->ci_keyring_key->flags & ((1 << KEY_FLAG_INVALIDATED) |
(1 << KEY_FLAG_REVOKED) |
@@ -493,6 +501,7 @@ static int ext4_d_revalidate(struct dentry *dentry, unsigned int flags)
/* this should eventually be an flag in d_flags */
cached_with_key = dentry->d_fsdata != NULL;
dir_has_key = (ci != NULL);
+ dput(dir);
/*
* If the dentry was cached without the key, and it is a
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index c1b4f6ab2148..785bc29e4f14 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -2251,11 +2251,13 @@ extern struct kmem_cache *ext4_crypt_info_cachep;
bool ext4_valid_contents_enc_mode(uint32_t mode);
uint32_t ext4_validate_encryption_key_size(uint32_t mode, uint32_t size);
extern struct workqueue_struct *ext4_read_workqueue;
-struct ext4_crypto_ctx *ext4_get_crypto_ctx(struct inode *inode);
+struct ext4_crypto_ctx *ext4_get_crypto_ctx(struct inode *inode,
+ gfp_t gfp_flags);
void ext4_release_crypto_ctx(struct ext4_crypto_ctx *ctx);
void ext4_restore_control_page(struct page *data_page);
struct page *ext4_encrypt(struct inode *inode,
- struct page *plaintext_page);
+ struct page *plaintext_page,
+ gfp_t gfp_flags);
int ext4_decrypt(struct page *page);
int ext4_encrypted_zeroout(struct inode *inode, struct ext4_extent *ex);
extern const struct dentry_operations ext4_encrypted_d_ops;
diff --git a/fs/ext4/page-io.c b/fs/ext4/page-io.c
index 17fbe3882b8e..5c72ae5d62a6 100644
--- a/fs/ext4/page-io.c
+++ b/fs/ext4/page-io.c
@@ -23,6 +23,7 @@
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/mm.h>
+#include <linux/backing-dev.h>
#include "ext4_jbd2.h"
#include "xattr.h"
@@ -485,9 +486,20 @@ int ext4_bio_write_page(struct ext4_io_submit *io,
if (ext4_encrypted_inode(inode) && S_ISREG(inode->i_mode) &&
nr_to_submit) {
- data_page = ext4_encrypt(inode, page);
+ gfp_t gfp_flags = GFP_NOFS;
+
+ retry_encrypt:
+ data_page = ext4_encrypt(inode, page, gfp_flags);
if (IS_ERR(data_page)) {
ret = PTR_ERR(data_page);
+ if (ret == ENOMEM && wbc->sync_mode == WB_SYNC_ALL) {
+ if (io->io_bio) {
+ ext4_io_submit(io);
+ congestion_wait(BLK_RW_ASYNC, HZ/50);
+ }
+ gfp_flags |= __GFP_NOFAIL;
+ goto retry_encrypt;
+ }
data_page = NULL;
goto out;
}
diff --git a/fs/ext4/readpage.c b/fs/ext4/readpage.c
index 5dc5e95063de..bc7642f57dc8 100644
--- a/fs/ext4/readpage.c
+++ b/fs/ext4/readpage.c
@@ -279,7 +279,7 @@ int ext4_mpage_readpages(struct address_space *mapping,
if (ext4_encrypted_inode(inode) &&
S_ISREG(inode->i_mode)) {
- ctx = ext4_get_crypto_ctx(inode);
+ ctx = ext4_get_crypto_ctx(inode, GFP_NOFS);
if (IS_ERR(ctx))
goto set_error_page;
}
diff --git a/include/dt-bindings/clock/msm-clocks-cobalt.h b/include/dt-bindings/clock/msm-clocks-cobalt.h
index 31c4537ea964..b80ea0c31597 100644
--- a/include/dt-bindings/clock/msm-clocks-cobalt.h
+++ b/include/dt-bindings/clock/msm-clocks-cobalt.h
@@ -157,6 +157,7 @@
#define clk_gcc_usb3_phy_reset 0x03d559f1
#define clk_gcc_usb3phy_phy_reset 0xb1a4f885
#define clk_gcc_aggre1_ufs_axi_clk 0x873459d8
+#define clk_gcc_aggre1_ufs_axi_hw_ctl_clk 0x117a6f39
#define clk_gcc_aggre1_usb3_axi_clk 0xc5c3fbe8
#define clk_gcc_bimc_mss_q6_axi_clk 0x7437988f
#define clk_gcc_blsp1_ahb_clk 0x8caa5b4f
diff --git a/include/dt-bindings/clock/qcom,gcc-msm8996.h b/include/dt-bindings/clock/qcom,gcc-msm8996.h
index 3819485dead3..f66264a2beb4 100644
--- a/include/dt-bindings/clock/qcom,gcc-msm8996.h
+++ b/include/dt-bindings/clock/qcom,gcc-msm8996.h
@@ -233,6 +233,18 @@
#define GCC_PCIE_CLKREF_CLK 216
#define GCC_RX2_USB2_CLKREF_CLK 217
#define GCC_RX1_USB2_CLKREF_CLK 218
+#define GCC_AGGRE0_NOC_QOSGEN_EXTREF_CLK 219
+#define GCC_HLOS1_VOTE_LPASS_CORE_SMMU_CLK 220
+#define GCC_HLOS1_VOTE_LPASS_ADSP_SMMU_CLK 221
+#define GCC_EDP_CLKREF_CLK 222
+#define GCC_MSS_CFG_AHB_CLK 223
+#define GCC_MSS_Q6_BIMC_AXI_CLK 224
+#define GCC_MSS_SNOC_AXI_CLK 225
+#define GCC_MSS_MNOC_BIMC_AXI_CLK 226
+#define GCC_DCC_AHB_ALK 227
+#define GCC_AGGRE0_NOC_MPU_CFG_AHB_CLK 228
+#define GCC_MMSS_GPLL0_DIV_CLK 229
+#define GPLL0_OUT_MSSCC 230
#define GCC_SYSTEM_NOC_BCR 0
#define GCC_CONFIG_NOC_BCR 1
@@ -340,15 +352,4 @@
#define GCC_PCIE_PHY_NOCSR_COM_PHY_BCR 103
#define GCC_PCIE_PHY_COM_BCR 104
-/* Indexes for GDSCs */
-#define AGGRE0_NOC_GDSC 0
-#define HLOS1_VOTE_AGGRE0_NOC_GDSC 1
-#define HLOS1_VOTE_LPASS_ADSP_GDSC 2
-#define HLOS1_VOTE_LPASS_CORE_GDSC 3
-#define USB30_GDSC 4
-#define PCIE0_GDSC 5
-#define PCIE1_GDSC 6
-#define PCIE2_GDSC 7
-#define UFS_GDSC 8
-
#endif
diff --git a/include/linux/phy/phy-qcom-ufs.h b/include/linux/phy/phy-qcom-ufs.h
index 7945fea14d77..25e7a5f183ec 100644
--- a/include/linux/phy/phy-qcom-ufs.h
+++ b/include/linux/phy/phy-qcom-ufs.h
@@ -58,5 +58,6 @@ void ufs_qcom_phy_save_controller_version(struct phy *phy,
u8 major, u16 minor, u16 step);
const char *ufs_qcom_phy_name(struct phy *phy);
int ufs_qcom_phy_configure_lpm(struct phy *generic_phy, bool enable);
+void ufs_qcom_phy_dbg_register_dump(struct phy *generic_phy);
#endif /* PHY_QCOM_UFS_H_ */
diff --git a/include/net/rmnet_config.h b/include/net/rmnet_config.h
new file mode 100644
index 000000000000..0e6282b05483
--- /dev/null
+++ b/include/net/rmnet_config.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2016, 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.
+ *
+ * RMNET Data config definition
+ *
+ */
+
+#ifndef _RMNET_CONFIG_H_
+#define _RMNET_CONFIG_H_
+
+#include <linux/skbuff.h>
+
+struct rmnet_phys_ep_conf_s {
+ void (*recycle)(struct sk_buff *); /* Destruct function */
+ void *config;
+};
+
+#endif /* _RMNET_CONFIG_H_ */
diff --git a/include/soc/qcom/icnss.h b/include/soc/qcom/icnss.h
index 8b64bf3b8de9..efc5425cf17d 100644
--- a/include/soc/qcom/icnss.h
+++ b/include/soc/qcom/icnss.h
@@ -26,6 +26,10 @@ struct icnss_driver_ops {
void (*crash_shutdown)(void *pdev);
int (*suspend)(struct device *dev, pm_message_t state);
int (*resume)(struct device *dev);
+ int (*pm_suspend)(struct device *dev);
+ int (*pm_resume)(struct device *dev);
+ int (*suspend_noirq)(struct device *dev);
+ int (*resume_noirq)(struct device *dev);
};
@@ -103,6 +107,12 @@ extern int icnss_ce_request_irq(unsigned int ce_id,
unsigned long flags, const char *name, void *ctx);
extern int icnss_get_ce_id(int irq);
extern int icnss_set_fw_debug_mode(bool enable_fw_log);
+extern int icnss_athdiag_read(struct device *dev, uint32_t offset,
+ uint32_t mem_type, uint32_t data_len,
+ uint8_t *output);
+extern int icnss_athdiag_write(struct device *dev, uint32_t offset,
+ uint32_t mem_type, uint32_t data_len,
+ uint8_t *input);
extern int icnss_get_irq(int ce_id);
extern int icnss_power_on(struct device *dev);
extern int icnss_power_off(struct device *dev);
diff --git a/include/sound/q6asm-v2.h b/include/sound/q6asm-v2.h
index dadc2f7a4eae..8525f2e7f738 100644
--- a/include/sound/q6asm-v2.h
+++ b/include/sound/q6asm-v2.h
@@ -226,7 +226,7 @@ struct audio_client *q6asm_get_audio_client(int session_id);
int q6asm_audio_client_buf_alloc(unsigned int dir/* 1:Out,0:In */,
struct audio_client *ac,
unsigned int bufsz,
- unsigned int bufcnt);
+ uint32_t bufcnt);
int q6asm_audio_client_buf_alloc_contiguous(unsigned int dir
/* 1:Out,0:In */,
struct audio_client *ac,
diff --git a/net/rmnet_data/rmnet_data_config.c b/net/rmnet_data/rmnet_data_config.c
index c49393924e26..ebce455b645d 100644
--- a/net/rmnet_data/rmnet_data_config.c
+++ b/net/rmnet_data/rmnet_data_config.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2016, 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
@@ -21,6 +21,7 @@
#include <linux/skbuff.h>
#include <linux/spinlock.h>
#include <linux/rmnet_data.h>
+#include <net/rmnet_config.h>
#include "rmnet_data_config.h"
#include "rmnet_data_handlers.h"
#include "rmnet_data_vnd.h"
@@ -141,14 +142,22 @@ static inline int _rmnet_is_physical_endpoint_associated(struct net_device *dev)
* - pointer to configuration if successful
* - 0 (null) if device is not associated
*/
-static inline struct rmnet_phys_ep_conf_s *_rmnet_get_phys_ep_config
- (struct net_device *dev)
+struct rmnet_phys_ep_config *_rmnet_get_phys_ep_config
+ (struct net_device *dev)
{
- if (_rmnet_is_physical_endpoint_associated(dev))
- return (struct rmnet_phys_ep_conf_s *)
- rcu_dereference(dev->rx_handler_data);
- else
+ struct rmnet_phys_ep_conf_s *_rmnet_phys_ep_config;
+
+ if (_rmnet_is_physical_endpoint_associated(dev)) {
+ _rmnet_phys_ep_config = (struct rmnet_phys_ep_conf_s *)
+ rcu_dereference(dev->rx_handler_data);
+ if (_rmnet_phys_ep_config && _rmnet_phys_ep_config->config)
+ return (struct rmnet_phys_ep_config *)
+ _rmnet_phys_ep_config->config;
+ else
+ return 0;
+ } else {
return 0;
+ }
}
/**
@@ -165,7 +174,7 @@ static inline struct rmnet_phys_ep_conf_s *_rmnet_get_phys_ep_config
struct rmnet_logical_ep_conf_s *_rmnet_get_logical_ep(struct net_device *dev,
int config_id)
{
- struct rmnet_phys_ep_conf_s *config;
+ struct rmnet_phys_ep_config *config;
struct rmnet_logical_ep_conf_s *epconfig_l;
if (rmnet_vnd_is_vnd(dev))
@@ -400,7 +409,7 @@ static void _rmnet_netlink_get_link_egress_data_format
struct rmnet_nl_msg_s *resp_rmnet)
{
struct net_device *dev;
- struct rmnet_phys_ep_conf_s *config;
+ struct rmnet_phys_ep_config *config;
_RMNET_NETLINK_NULL_CHECKS();
resp_rmnet->crd = RMNET_NETLINK_MSG_RETURNCODE;
@@ -432,7 +441,7 @@ static void _rmnet_netlink_get_link_ingress_data_format
struct rmnet_nl_msg_s *resp_rmnet)
{
struct net_device *dev;
- struct rmnet_phys_ep_conf_s *config;
+ struct rmnet_phys_ep_config *config;
_RMNET_NETLINK_NULL_CHECKS();
resp_rmnet->crd = RMNET_NETLINK_MSG_RETURNCODE;
@@ -725,7 +734,7 @@ int rmnet_set_ingress_data_format(struct net_device *dev,
uint32_t ingress_data_format,
uint8_t tail_spacing)
{
- struct rmnet_phys_ep_conf_s *config;
+ struct rmnet_phys_ep_config *config;
ASSERT_RTNL();
LOGL("(%s,0x%08X);", dev->name, ingress_data_format);
@@ -762,7 +771,7 @@ int rmnet_set_egress_data_format(struct net_device *dev,
uint16_t agg_size,
uint16_t agg_count)
{
- struct rmnet_phys_ep_conf_s *config;
+ struct rmnet_phys_ep_config *config;
ASSERT_RTNL();
LOGL("(%s,0x%08X, %d, %d);",
@@ -800,7 +809,9 @@ int rmnet_set_egress_data_format(struct net_device *dev,
int rmnet_associate_network_device(struct net_device *dev)
{
struct rmnet_phys_ep_conf_s *config;
+ struct rmnet_phys_ep_config *conf;
int rc;
+
ASSERT_RTNL();
LOGL("(%s);\n", dev->name);
@@ -819,19 +830,25 @@ int rmnet_associate_network_device(struct net_device *dev)
}
config = kmalloc(sizeof(*config), GFP_ATOMIC);
+ conf = kmalloc(sizeof(*conf), GFP_ATOMIC);
- if (!config)
+ if (!config || !conf)
return RMNET_CONFIG_NOMEM;
memset(config, 0, sizeof(struct rmnet_phys_ep_conf_s));
- config->dev = dev;
- spin_lock_init(&config->agg_lock);
+ memset(conf, 0, sizeof(struct rmnet_phys_ep_config));
+
+ config->config = conf;
+ conf->dev = dev;
+ spin_lock_init(&conf->agg_lock);
+ config->recycle = kfree_skb;
rc = netdev_rx_handler_register(dev, rmnet_rx_handler, config);
if (rc) {
LOGM("netdev_rx_handler_register returns %d", rc);
kfree(config);
+ kfree(conf);
return RMNET_CONFIG_DEVICE_IN_USE;
}
diff --git a/net/rmnet_data/rmnet_data_config.h b/net/rmnet_data/rmnet_data_config.h
index a76bcef79e6a..78329c38b364 100644
--- a/net/rmnet_data/rmnet_data_config.h
+++ b/net/rmnet_data/rmnet_data_config.h
@@ -17,6 +17,7 @@
#include <linux/types.h>
#include <linux/time.h>
#include <linux/spinlock.h>
+#include <net/rmnet_config.h>
#ifndef _RMNET_DATA_CONFIG_H_
#define _RMNET_DATA_CONFIG_H_
@@ -62,7 +63,7 @@ struct rmnet_logical_ep_conf_s {
* @agg_time: Wall clock time when aggregated frame was created
* @agg_last: Last time the aggregation routing was invoked
*/
-struct rmnet_phys_ep_conf_s {
+struct rmnet_phys_ep_config {
struct net_device *dev;
struct rmnet_logical_ep_conf_s local_ep;
struct rmnet_logical_ep_conf_s muxed_ep[RMNET_DATA_MAX_LOGICAL_EP];
@@ -123,4 +124,7 @@ int rmnet_create_vnd(int id);
int rmnet_create_vnd_prefix(int id, const char *name);
int rmnet_free_vnd(int id);
+struct rmnet_phys_ep_config *_rmnet_get_phys_ep_config
+ (struct net_device *dev);
+
#endif /* _RMNET_DATA_CONFIG_H_ */
diff --git a/net/rmnet_data/rmnet_data_handlers.c b/net/rmnet_data/rmnet_data_handlers.c
index 9d04b2f8ddd9..185b609e637f 100644
--- a/net/rmnet_data/rmnet_data_handlers.c
+++ b/net/rmnet_data/rmnet_data_handlers.c
@@ -22,6 +22,7 @@
#include <linux/netdev_features.h>
#include <linux/ip.h>
#include <linux/ipv6.h>
+#include <net/rmnet_config.h>
#include "rmnet_data_private.h"
#include "rmnet_data_config.h"
#include "rmnet_data_vnd.h"
@@ -321,7 +322,7 @@ static rx_handler_result_t __rmnet_deliver_skb(struct sk_buff *skb,
* - RX_HANDLER_PASS if packet should be passed up the stack by caller
*/
static rx_handler_result_t rmnet_ingress_deliver_packet(struct sk_buff *skb,
- struct rmnet_phys_ep_conf_s *config)
+ struct rmnet_phys_ep_config *config)
{
if (!config) {
LOGD("%s", "NULL physical EP provided");
@@ -356,7 +357,7 @@ static rx_handler_result_t rmnet_ingress_deliver_packet(struct sk_buff *skb,
* - result of __rmnet_deliver_skb() for all other cases
*/
static rx_handler_result_t _rmnet_map_ingress_handler(struct sk_buff *skb,
- struct rmnet_phys_ep_conf_s *config)
+ struct rmnet_phys_ep_config *config)
{
struct rmnet_logical_ep_conf_s *ep;
uint8_t mux_id;
@@ -440,7 +441,7 @@ static rx_handler_result_t _rmnet_map_ingress_handler(struct sk_buff *skb,
* - result of _rmnet_map_ingress_handler() for all other cases
*/
static rx_handler_result_t rmnet_map_ingress_handler(struct sk_buff *skb,
- struct rmnet_phys_ep_conf_s *config)
+ struct rmnet_phys_ep_config *config)
{
struct sk_buff *skbn;
int rc, co = 0;
@@ -480,7 +481,7 @@ static rx_handler_result_t rmnet_map_ingress_handler(struct sk_buff *skb,
* - 1 on failure
*/
static int rmnet_map_egress_handler(struct sk_buff *skb,
- struct rmnet_phys_ep_conf_s *config,
+ struct rmnet_phys_ep_config *config,
struct rmnet_logical_ep_conf_s *ep,
struct net_device *orig_dev)
{
@@ -563,7 +564,7 @@ static int rmnet_map_egress_handler(struct sk_buff *skb,
*/
rx_handler_result_t rmnet_ingress_handler(struct sk_buff *skb)
{
- struct rmnet_phys_ep_conf_s *config;
+ struct rmnet_phys_ep_config *config;
struct net_device *dev;
int rc;
@@ -574,8 +575,7 @@ rx_handler_result_t rmnet_ingress_handler(struct sk_buff *skb)
trace_rmnet_ingress_handler(skb);
rmnet_print_packet(skb, dev->name, 'r');
- config = (struct rmnet_phys_ep_conf_s *)
- rcu_dereference(skb->dev->rx_handler_data);
+ config = _rmnet_get_phys_ep_config(skb->dev);
if (!config) {
LOGD("%s is not associated with rmnet_data", skb->dev->name);
@@ -654,14 +654,13 @@ rx_handler_result_t rmnet_rx_handler(struct sk_buff **pskb)
void rmnet_egress_handler(struct sk_buff *skb,
struct rmnet_logical_ep_conf_s *ep)
{
- struct rmnet_phys_ep_conf_s *config;
+ struct rmnet_phys_ep_config *config;
struct net_device *orig_dev;
int rc;
orig_dev = skb->dev;
skb->dev = ep->egress_dev;
- config = (struct rmnet_phys_ep_conf_s *)
- rcu_dereference(skb->dev->rx_handler_data);
+ config = _rmnet_get_phys_ep_config(skb->dev);
if (!config) {
LOGD("%s is not associated with rmnet_data", skb->dev->name);
diff --git a/net/rmnet_data/rmnet_data_stats.c b/net/rmnet_data/rmnet_data_stats.c
index 5fefda55c72c..20f1628242c7 100644
--- a/net/rmnet_data/rmnet_data_stats.c
+++ b/net/rmnet_data/rmnet_data_stats.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014, 2016 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
@@ -21,6 +21,7 @@
#include <linux/skbuff.h>
#include <linux/spinlock.h>
#include <linux/netdevice.h>
+#include <net/rmnet_config.h>
#include "rmnet_data_private.h"
#include "rmnet_data_stats.h"
#include "rmnet_data_config.h"
@@ -73,8 +74,16 @@ void rmnet_kfree_skb(struct sk_buff *skb, unsigned int reason)
skb_free[reason]++;
spin_unlock_irqrestore(&rmnet_skb_free_lock, flags);
- if (skb)
- kfree_skb(skb);
+ if (likely(skb)) {
+ struct rmnet_phys_ep_conf_s *config;
+
+ config = (struct rmnet_phys_ep_conf_s *)rcu_dereference
+ (skb->dev->rx_handler_data);
+ if (likely(config))
+ config->recycle(skb);
+ else
+ kfree_skb(skb);
+ }
}
void rmnet_stats_queue_xmit(int rc, unsigned int reason)
diff --git a/net/rmnet_data/rmnet_map.h b/net/rmnet_data/rmnet_map.h
index 0a6ad908b827..71abca122dd6 100644
--- a/net/rmnet_data/rmnet_map.h
+++ b/net/rmnet_data/rmnet_map.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2016, 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
@@ -13,6 +13,7 @@
#include <linux/types.h>
#include <linux/spinlock.h>
+#include <net/rmnet_config.h>
#ifndef _RMNET_MAP_H_
#define _RMNET_MAP_H_
@@ -133,14 +134,14 @@ enum rmnet_map_agg_state_e {
uint8_t rmnet_map_demultiplex(struct sk_buff *skb);
struct sk_buff *rmnet_map_deaggregate(struct sk_buff *skb,
- struct rmnet_phys_ep_conf_s *config);
+ struct rmnet_phys_ep_config *config);
struct rmnet_map_header_s *rmnet_map_add_map_header(struct sk_buff *skb,
int hdrlen, int pad);
rx_handler_result_t rmnet_map_command(struct sk_buff *skb,
- struct rmnet_phys_ep_conf_s *config);
+ struct rmnet_phys_ep_config *config);
void rmnet_map_aggregate(struct sk_buff *skb,
- struct rmnet_phys_ep_conf_s *config);
+ struct rmnet_phys_ep_config *config);
int rmnet_map_checksum_downlink_packet(struct sk_buff *skb);
int rmnet_map_checksum_uplink_packet(struct sk_buff *skb,
diff --git a/net/rmnet_data/rmnet_map_command.c b/net/rmnet_data/rmnet_map_command.c
index 4bcfa10db486..055d5f402957 100644
--- a/net/rmnet_data/rmnet_map_command.c
+++ b/net/rmnet_data/rmnet_map_command.c
@@ -18,6 +18,7 @@
#include <linux/rmnet_data.h>
#include <linux/net_map.h>
#include <net/pkt_sched.h>
+#include <net/rmnet_config.h>
#include "rmnet_data_config.h"
#include "rmnet_map.h"
#include "rmnet_data_private.h"
@@ -44,7 +45,7 @@ MODULE_PARM_DESC(rmnet_map_command_stats, "MAP command statistics");
* - RMNET_MAP_COMMAND_ACK on success
*/
static uint8_t rmnet_map_do_flow_control(struct sk_buff *skb,
- struct rmnet_phys_ep_conf_s *config,
+ struct rmnet_phys_ep_config *config,
int enable)
{
struct rmnet_map_control_command_s *cmd;
@@ -116,7 +117,7 @@ static uint8_t rmnet_map_do_flow_control(struct sk_buff *skb,
*/
static void rmnet_map_send_ack(struct sk_buff *skb,
unsigned char type,
- struct rmnet_phys_ep_conf_s *config)
+ struct rmnet_phys_ep_config *config)
{
struct rmnet_map_control_command_s *cmd;
int xmit_status;
@@ -162,7 +163,7 @@ static void rmnet_map_send_ack(struct sk_buff *skb,
* - RX_HANDLER_CONSUMED. Command frames are always consumed.
*/
rx_handler_result_t rmnet_map_command(struct sk_buff *skb,
- struct rmnet_phys_ep_conf_s *config)
+ struct rmnet_phys_ep_config *config)
{
struct rmnet_map_control_command_s *cmd;
unsigned char command_name;
diff --git a/net/rmnet_data/rmnet_map_data.c b/net/rmnet_data/rmnet_map_data.c
index 68caf44c1f92..beff8332c731 100644
--- a/net/rmnet_data/rmnet_map_data.c
+++ b/net/rmnet_data/rmnet_map_data.c
@@ -31,6 +31,7 @@
#include <net/ip.h>
#include <net/checksum.h>
#include <net/ip6_checksum.h>
+#include <net/rmnet_config.h>
#include "rmnet_data_config.h"
#include "rmnet_map.h"
#include "rmnet_data_private.h"
@@ -52,7 +53,7 @@ MODULE_PARM_DESC(agg_bypass_time, "Skip agg when apart spaced more than this");
struct agg_work {
struct delayed_work work;
- struct rmnet_phys_ep_conf_s *config;
+ struct rmnet_phys_ep_config *config;
};
#define RMNET_MAP_DEAGGR_SPACING 64
@@ -131,7 +132,7 @@ done:
* - 0 (null) if no more aggregated packets
*/
struct sk_buff *rmnet_map_deaggregate(struct sk_buff *skb,
- struct rmnet_phys_ep_conf_s *config)
+ struct rmnet_phys_ep_config *config)
{
struct sk_buff *skbn;
struct rmnet_map_header_s *maph;
@@ -185,7 +186,7 @@ struct sk_buff *rmnet_map_deaggregate(struct sk_buff *skb,
static void rmnet_map_flush_packet_queue(struct work_struct *work)
{
struct agg_work *real_work;
- struct rmnet_phys_ep_conf_s *config;
+ struct rmnet_phys_ep_config *config;
unsigned long flags;
struct sk_buff *skb;
int rc, agg_count = 0;
@@ -233,7 +234,7 @@ static void rmnet_map_flush_packet_queue(struct work_struct *work)
* the argument SKB and should not be further processed by any other function.
*/
void rmnet_map_aggregate(struct sk_buff *skb,
- struct rmnet_phys_ep_conf_s *config) {
+ struct rmnet_phys_ep_config *config) {
uint8_t *dest_buff;
struct agg_work *work;
unsigned long flags;
diff --git a/sound/soc/codecs/wcd9335.c b/sound/soc/codecs/wcd9335.c
index 158b9ae08642..b5126351dda0 100644
--- a/sound/soc/codecs/wcd9335.c
+++ b/sound/soc/codecs/wcd9335.c
@@ -793,7 +793,7 @@ struct tasha_priv {
struct wcd_swr_ctrl_platform_data swr_plat_data;
/* Port values for Rx and Tx codec_dai */
- unsigned int rx_port_value;
+ unsigned int rx_port_value[TASHA_RX_MAX];
unsigned int tx_port_value;
unsigned int vi_feed_value;
@@ -2597,7 +2597,8 @@ static int slim_rx_mux_get(struct snd_kcontrol *kcontrol,
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm);
struct tasha_priv *tasha_p = snd_soc_codec_get_drvdata(codec);
- ucontrol->value.enumerated.item[0] = tasha_p->rx_port_value;
+ ucontrol->value.enumerated.item[0] =
+ tasha_p->rx_port_value[widget->shift];
return 0;
}
@@ -2616,25 +2617,27 @@ static int slim_rx_mux_put(struct snd_kcontrol *kcontrol,
struct wcd9xxx *core = dev_get_drvdata(codec->dev->parent);
struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
struct snd_soc_dapm_update *update = NULL;
+ unsigned int rx_port_value;
u32 port_id = widget->shift;
+ tasha_p->rx_port_value[port_id] = ucontrol->value.enumerated.item[0];
+ rx_port_value = tasha_p->rx_port_value[port_id];
+
pr_debug("%s: wname %s cname %s value %u shift %d item %ld\n", __func__,
- widget->name, ucontrol->id.name, tasha_p->rx_port_value,
+ widget->name, ucontrol->id.name, rx_port_value,
widget->shift, ucontrol->value.integer.value[0]);
- tasha_p->rx_port_value = ucontrol->value.enumerated.item[0];
-
mutex_lock(&tasha_p->codec_mutex);
if (tasha_p->intf_type != WCD9XXX_INTERFACE_TYPE_SLIMBUS) {
- if (tasha_p->rx_port_value > 2) {
+ if (rx_port_value > 2) {
dev_err(codec->dev, "%s: invalid AIF for I2C mode\n",
__func__);
goto err;
}
}
/* value need to match the Virtual port and AIF number */
- switch (tasha_p->rx_port_value) {
+ switch (rx_port_value) {
case 0:
list_del_init(&core->rx_chs[port_id].list);
break;
@@ -2694,13 +2697,13 @@ static int slim_rx_mux_put(struct snd_kcontrol *kcontrol,
&tasha_p->dai[AIF_MIX1_PB].wcd9xxx_ch_list);
break;
default:
- pr_err("Unknown AIF %d\n", tasha_p->rx_port_value);
+ pr_err("Unknown AIF %d\n", rx_port_value);
goto err;
}
rtn:
mutex_unlock(&tasha_p->codec_mutex);
snd_soc_dapm_mux_update_power(widget->dapm, kcontrol,
- tasha_p->rx_port_value, e, update);
+ rx_port_value, e, update);
return 0;
err:
diff --git a/sound/soc/msm/qdsp6v2/q6asm.c b/sound/soc/msm/qdsp6v2/q6asm.c
index 20d3f5212323..206fbec249fa 100644
--- a/sound/soc/msm/qdsp6v2/q6asm.c
+++ b/sound/soc/msm/qdsp6v2/q6asm.c
@@ -1195,7 +1195,7 @@ err:
int q6asm_audio_client_buf_alloc(unsigned int dir,
struct audio_client *ac,
unsigned int bufsz,
- unsigned int bufcnt)
+ uint32_t bufcnt)
{
int cnt = 0;
int rc = 0;
@@ -1222,7 +1222,7 @@ int q6asm_audio_client_buf_alloc(unsigned int dir,
return 0;
}
mutex_lock(&ac->cmd_lock);
- if (bufcnt > (LONG_MAX/sizeof(struct audio_buffer))) {
+ if (bufcnt > (U32_MAX/sizeof(struct audio_buffer))) {
pr_err("%s: Buffer size overflows", __func__);
mutex_unlock(&ac->cmd_lock);
goto fail;