Merge "UPSTREAM: Merge remote-tracking branch 'quic/dev/msm-4.9-camx' into msm-4.9 - 092117"
diff --git a/Documentation/devicetree/bindings/arm/msm/msm.txt b/Documentation/devicetree/bindings/arm/msm/msm.txt
index bc82bdc..765b5e4 100644
--- a/Documentation/devicetree/bindings/arm/msm/msm.txt
+++ b/Documentation/devicetree/bindings/arm/msm/msm.txt
@@ -92,6 +92,12 @@
- SDM670
compatible = "qcom,sdm670"
+- QCS605
+ compatible = "qcom,qcs605"
+
+- SDA670
+ compatible = "qcom,sda670"
+
- MSM8952
compatible = "qcom,msm8952"
@@ -276,6 +282,10 @@
compatible = "qcom,sdm670-rumi"
compatible = "qcom,sdm670-cdp"
compatible = "qcom,sdm670-mtp"
+compatible = "qcom,qcs605-cdp"
+compatible = "qcom,qcs605-mtp"
+compatible = "qcom,sda670-cdp"
+compatible = "qcom,sda670-mtp"
compatible = "qcom,msm8952-rumi"
compatible = "qcom,msm8952-sim"
compatible = "qcom,msm8952-qrd"
diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,msm8953-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/qcom,msm8953-pinctrl.txt
new file mode 100644
index 0000000..d4bf1ce
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/qcom,msm8953-pinctrl.txt
@@ -0,0 +1,210 @@
+Qualcomm MSM8953 TLMM block
+
+This binding describes the Top Level Mode Multiplexer block found in the
+MSM8953 platform.
+
+- compatible:
+ Usage: required
+ Value type: <string>
+ Definition: must be "qcom,msm8953-pinctrl"
+
+- reg:
+ Usage: required
+ Value type: <prop-encoded-array>
+ Definition: the base address and size of the TLMM register space.
+
+- interrupts:
+ Usage: required
+ Value type: <prop-encoded-array>
+ Definition: should specify the TLMM summary IRQ.
+
+- interrupt-controller:
+ Usage: required
+ Value type: <none>
+ Definition: identifies this node as an interrupt controller
+
+- #interrupt-cells:
+ Usage: required
+ Value type: <u32>
+ Definition: must be 2. Specifying the pin number and flags, as defined
+ in <dt-bindings/interrupt-controller/irq.h>
+
+- gpio-controller:
+ Usage: required
+ Value type: <none>
+ Definition: identifies this node as a gpio controller
+
+- #gpio-cells:
+ Usage: required
+ Value type: <u32>
+ Definition: must be 2. Specifying the pin number and flags, as defined
+ in <dt-bindings/gpio/gpio.h>
+
+Please refer to ../gpio/gpio.txt and ../interrupt-controller/interrupts.txt for
+a general description of GPIO and interrupt bindings.
+
+Please refer to pinctrl-bindings.txt in this directory for details of the
+common pinctrl bindings used by client devices, including the meaning of the
+phrase "pin configuration node".
+
+The pin configuration nodes act as a container for an arbitrary number of
+subnodes. Each of these subnodes represents some desired configuration for a
+pin, a group, or a list of pins or groups. This configuration can include the
+mux function to select on those pin(s)/group(s), and various pin configuration
+parameters, such as pull-up, drive strength, etc.
+
+
+PIN CONFIGURATION NODES:
+
+The name of each subnode is not important; all subnodes should be enumerated
+and processed purely based on their content.
+
+Each subnode only affects those parameters that are explicitly listed. In
+other words, a subnode that lists a mux function but no pin configuration
+parameters implies no information about any pin configuration parameters.
+Similarly, a pin subnode that describes a pullup parameter implies no
+information about e.g. the mux function.
+
+
+The following generic properties as defined in pinctrl-bindings.txt are valid
+to specify in a pin configuration subnode:
+
+- pins:
+ Usage: required
+ Value type: <string-array>
+ Definition: List of gpio pins affected by the properties specified in
+ this subnode.
+ Valid pins are:
+ gpio0-gpio141,
+ sdc1_clk,
+ sdc1_cmd,
+ sdc1_data,
+ sdc1_rclk,
+ sdc2_clk,
+ sdc2_cmd,
+ sdc2_data,
+ qdsd_cmd,
+ qdsd_data0,
+ qdsd_data1,
+ qdsd_data2,
+ qdsd_data3
+
+- function:
+ Usage: required
+ Value type: <string>
+ Definition: Specify the alternative function to be configured for the
+ specified pins. Functions are only valid for gpio pins.
+ Valid values are:
+ gpio, blsp_spi1, smb_int, adsp_ext, prng_rosc, blsp_i2c1,
+ qdss_cti_trig_out_b0, qdss_cti_trig_out_a1, blsp_spi2, blsp_uart2,
+ ldo_update, dac_calib0, ldo_en, blsp_i2c2, gcc_gp1_clk_b,
+ atest_gpsadc_dtest0_native, blsp_spi3, qdss_tracedata_b,
+ pwr_modem_enabled_b, blsp_i2c3, gcc_gp2_clk_b, gcc_gp3_clk_b, hall_int,
+ blsp_spi4, blsp_uart4, pwr_nav_enabled_b, dac_calib1, cap_int,
+ pwr_crypto_enabled_b, dac_calib2, blsp_i2c4, nfc_disable, blsp_spi5,
+ blsp_uart5, qdss_traceclk_a, atest_bbrx1, nfc_irq, m_voc,
+ qdss_cti_trig_in_a0, atest_bbrx0, blsp_i2c5, qdss_tracectl_a,
+ atest_gpsadc_dtest1_native, qdss_tracedata_a, blsp_spi6, blsp_uart6,
+ qdss_tracectl_b, dac_calib15, qdss_cti_trig_in_b0, dac_calib16, blsp_i2c6,
+ qdss_traceclk_b, atest_wlan0, atest_wlan1, mdp_vsync, pri_mi2s_mclk_a,
+ sec_mi2s_mclk_a, qdss_cti_trig_out_b1, cam_mclk, dac_calib3, cci_i2c,
+ pwr_modem_enabled_a, dac_calib4, dac_calib19, flash_strobe, cci_timer0,
+ cci_timer1, cam_irq, cci_timer2, blsp1_spi, pwr_nav_enabled_a, ois_sync,
+ cci_timer3, cci_timer4, blsp3_spi, qdss_cti_trig_out_a0, dac_calib7,
+ accel_int, gcc_gp1_clk_a, dac_calib8, alsp_int, gcc_gp2_clk_a, dac_calib9,
+ mag_int, gcc_gp3_clk_a, pwr_crypto_enabled_a, cci_async, cam1_standby,
+ dac_calib5, cam1_rst, dac_calib6, dac_calib10, gyro_int, dac_calib11,
+ pressure_int, dac_calib12, blsp6_spi, dac_calib13, fp_int,
+ qdss_cti_trig_in_b1, dac_calib14, uim_batt, cam0_ldo, sd_write, uim1_data,
+ uim1_clk, uim1_reset, uim1_present, uim2_data, uim2_clk, uim2_reset,
+ uim2_present, ts_xvdd, mipi_dsi0, nfc_dwl, us_euro, atest_char3, dbg_out,
+ bimc_dte0, ts_resout, ts_sample, sec_mi2s_mclk_b, pri_mi2s, codec_reset,
+ cdc_pdm0, atest_char1, ebi_cdc, dac_calib17, us_emitter, atest_char0,
+ pri_mi2s_mclk_b, lpass_slimbus, lpass_slimbus0, lpass_slimbus1, codec_int1,
+ codec_int2, wcss_bt, atest_char2, ebi_ch0, wcss_wlan2, wcss_wlan1,
+ wcss_wlan0, wcss_wlan, wcss_fm, ext_lpass, mss_lte, key_volp, pbs0,
+ cri_trng0, key_snapshot, pbs1, cri_trng1, key_focus, pbs2, cri_trng,
+ gcc_tlmm, key_home, pwr_down, dmic0_clk, blsp7_spi, hdmi_int, dmic0_data,
+ qdss_cti_trig_in_a1, pri_mi2s_ws, wsa_io, wsa_en, blsp_spi8, wsa_irq,
+ blsp_i2c8, gcc_plltest, nav_pps_in_a, pa_indicator, nav_pps_in_b, nav_pps,
+ modem_tsync, nav_tsync, ssbi_wtr1, gsm1_tx, dac_calib18, gsm0_tx,
+ atest_char, atest_tsens, bimc_dte1, dac_calib20, cam2_rst, ddr_bist,
+ dac_calib21, cam2_standby, dac_calib22, cam3_rst, dac_calib23,
+ cam3_standby, dac_calib24, sdcard_det, dac_calib25, cam1_ldo, sec_mi2s,
+ blsp_spi7, blsp_i2c7, ss_switch, tsens_max
+
+- bias-disable:
+ Usage: optional
+ Value type: <none>
+ Definition: The specified pins should be configued as no pull.
+
+- bias-pull-down:
+ Usage: optional
+ Value type: <none>
+ Definition: The specified pins should be configued as pull down.
+
+- bias-pull-up:
+ Usage: optional
+ Value type: <none>
+ Definition: The specified pins should be configued as pull up.
+
+- output-high:
+ Usage: optional
+ Value type: <none>
+ Definition: The specified pins are configured in output mode, driven
+ high.
+ Not valid for sdc pins.
+
+- output-low:
+ Usage: optional
+ Value type: <none>
+ Definition: The specified pins are configured in output mode, driven
+ low.
+ Not valid for sdc pins.
+
+- drive-strength:
+ Usage: optional
+ Value type: <u32>
+ Definition: Selects the drive strength for the specified pins, in mA.
+ Valid values are: 2, 4, 6, 8, 10, 12, 14 and 16
+
+Example:
+
+ tlmm: pinctrl@1000000 {
+ compatible = "qcom,msm8953-pinctrl";
+ reg = <0x1000000 0x300000>;
+ interrupts = <0 208 0>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+
+ pmx-uartconsole {
+ uart_console_active: uart_console_active {
+ mux {
+ pins = "gpio4", "gpio5";
+ function = "blsp_uart2";
+ };
+
+ config {
+ pins = "gpio4", "gpio5";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ uart_console_sleep: uart_console_sleep {
+ mux {
+ pins = "gpio4", "gpio5";
+ function = "blsp_uart2";
+ };
+
+ config {
+ pins = "gpio4", "gpio5";
+ drive-strength = <2>;
+ bias-pull-down;
+ };
+ };
+
+ };
+ };
diff --git a/Makefile b/Makefile
index a8d289a..155351a 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
VERSION = 4
PATCHLEVEL = 9
-SUBLEVEL = 48
+SUBLEVEL = 50
EXTRAVERSION =
NAME = Roaring Lionus
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills-smp2p.dtsi b/arch/arm/boot/dts/qcom/sdxpoorwills-smp2p.dtsi
new file mode 100644
index 0000000..f9ad6f4
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills-smp2p.dtsi
@@ -0,0 +1,109 @@
+/* Copyright (c) 2017, 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/interrupt-controller/arm-gic.h>
+
+&soc {
+ qcom,smp2p-modem@17811008 {
+ compatible = "qcom,smp2p";
+ reg = <0x17811008 0x4>;
+ qcom,remote-pid = <1>;
+ qcom,irq-bitmask = <0x4000>;
+ interrupts = <GIC_SPI 113 IRQ_TYPE_EDGE_RISING>;
+ };
+
+ smp2pgpio_smp2p_15_in: qcom,smp2pgpio-smp2p-15-in {
+ compatible = "qcom,smp2pgpio";
+ qcom,entry-name = "smp2p";
+ qcom,remote-pid = <15>;
+ qcom,is-inbound;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ qcom,smp2pgpio_test_smp2p_15_in {
+ compatible = "qcom,smp2pgpio_test_smp2p_15_in";
+ gpios = <&smp2pgpio_smp2p_15_in 0 0>;
+ };
+
+ smp2pgpio_smp2p_15_out: qcom,smp2pgpio-smp2p-15-out {
+ compatible = "qcom,smp2pgpio";
+ qcom,entry-name = "smp2p";
+ qcom,remote-pid = <15>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ qcom,smp2pgpio_test_smp2p_15_out {
+ compatible = "qcom,smp2pgpio_test_smp2p_15_out";
+ gpios = <&smp2pgpio_smp2p_15_out 0 0>;
+ };
+
+ smp2pgpio_smp2p_1_in: qcom,smp2pgpio-smp2p-1-in {
+ compatible = "qcom,smp2pgpio";
+ qcom,entry-name = "smp2p";
+ qcom,remote-pid = <1>;
+ qcom,is-inbound;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ qcom,smp2pgpio_test_smp2p_1_in {
+ compatible = "qcom,smp2pgpio_test_smp2p_1_in";
+ gpios = <&smp2pgpio_smp2p_1_in 0 0>;
+ };
+
+ smp2pgpio_smp2p_1_out: qcom,smp2pgpio-smp2p-1-out {
+ compatible = "qcom,smp2pgpio";
+ qcom,entry-name = "smp2p";
+ qcom,remote-pid = <1>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ qcom,smp2pgpio_test_smp2p_1_out {
+ compatible = "qcom,smp2pgpio_test_smp2p_1_out";
+ gpios = <&smp2pgpio_smp2p_1_out 0 0>;
+ };
+
+ /* ssr - inbound entry from mss */
+ smp2pgpio_ssr_smp2p_1_in: qcom,smp2pgpio-ssr-smp2p-1-in {
+ compatible = "qcom,smp2pgpio";
+ qcom,entry-name = "slave-kernel";
+ qcom,remote-pid = <1>;
+ qcom,is-inbound;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ /* ssr - outbound entry to mss */
+ smp2pgpio_ssr_smp2p_1_out: qcom,smp2pgpio-ssr-smp2p-1-out {
+ compatible = "qcom,smp2pgpio";
+ qcom,entry-name = "master-kernel";
+ qcom,remote-pid = <1>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+};
+
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi b/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi
index 2ef277f..d538efe 100644
--- a/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi
@@ -34,6 +34,13 @@
reg = <0x8fd00000 0x300000>;
label = "peripheral2_mem";
};
+
+ mss_mem: mss_region@87800000 {
+ compatible = "removed-dma-pool";
+ no-map;
+ reg = <0x87800000 0x8000000>;
+ label = "mss_mem";
+ };
};
cpus {
@@ -324,8 +331,134 @@
#interrupt-cells = <4>;
cell-index = <0>;
};
+
+ qcom,ipc-spinlock@1f40000 {
+ compatible = "qcom,ipc-spinlock-sfpb";
+ reg = <0x1f40000 0x8000>;
+ qcom,num-locks = <8>;
+ };
+
+ qcom,smem@8fe40000 {
+ compatible = "qcom,smem";
+ reg = <0x8fe40000 0xc0000>,
+ <0x17811008 0x4>,
+ <0x1fd4000 0x8>;
+ reg-names = "smem", "irq-reg-base",
+ "smem_targ_info_reg";
+ qcom,mpu-enabled;
+ };
+
+ qcom,glink-smem-native-xprt-modem@8fe40000 {
+ compatible = "qcom,glink-smem-native-xprt";
+ reg = <0x8fe40000 0xc0000>,
+ <0x17811008 0x4>;
+ reg-names = "smem", "irq-reg-base";
+ qcom,irq-mask = <0x1000>;
+ interrupts = <GIC_SPI 111 IRQ_TYPE_EDGE_RISING>;
+ label = "mpss";
+ };
+
+ qcom,ipc_router {
+ compatible = "qcom,ipc_router";
+ qcom,node-id = <1>;
+ };
+
+ qcom,ipc_router_modem_xprt {
+ compatible = "qcom,ipc_router_glink_xprt";
+ qcom,ch-name = "IPCRTR";
+ qcom,xprt-remote = "mpss";
+ qcom,glink-xprt = "smem";
+ qcom,xprt-linkid = <1>;
+ qcom,xprt-version = <1>;
+ qcom,fragmented-data;
+ };
+
+ qcom,glink_pkt {
+ compatible = "qcom,glinkpkt";
+
+ qcom,glinkpkt-at-mdm0 {
+ qcom,glinkpkt-transport = "smem";
+ qcom,glinkpkt-edge = "mpss";
+ qcom,glinkpkt-ch-name = "DS";
+ qcom,glinkpkt-dev-name = "at_mdm0";
+ };
+
+ qcom,glinkpkt-loopback_cntl {
+ qcom,glinkpkt-transport = "lloop";
+ qcom,glinkpkt-edge = "local";
+ qcom,glinkpkt-ch-name = "LOCAL_LOOPBACK_CLNT";
+ qcom,glinkpkt-dev-name = "glink_pkt_loopback_ctrl";
+ };
+
+ qcom,glinkpkt-loopback_data {
+ qcom,glinkpkt-transport = "lloop";
+ qcom,glinkpkt-edge = "local";
+ qcom,glinkpkt-ch-name = "glink_pkt_lloop_CLNT";
+ qcom,glinkpkt-dev-name = "glink_pkt_loopback";
+ };
+
+ qcom,glinkpkt-data40-cntl {
+ qcom,glinkpkt-transport = "smem";
+ qcom,glinkpkt-edge = "mpss";
+ qcom,glinkpkt-ch-name = "DATA40_CNTL";
+ qcom,glinkpkt-dev-name = "smdcntl8";
+ };
+
+ qcom,glinkpkt-data1 {
+ qcom,glinkpkt-transport = "smem";
+ qcom,glinkpkt-edge = "mpss";
+ qcom,glinkpkt-ch-name = "DATA1";
+ qcom,glinkpkt-dev-name = "smd7";
+ };
+
+ qcom,glinkpkt-data4 {
+ qcom,glinkpkt-transport = "smem";
+ qcom,glinkpkt-edge = "mpss";
+ qcom,glinkpkt-ch-name = "DATA4";
+ qcom,glinkpkt-dev-name = "smd8";
+ };
+
+ qcom,glinkpkt-data11 {
+ qcom,glinkpkt-transport = "smem";
+ qcom,glinkpkt-edge = "mpss";
+ qcom,glinkpkt-ch-name = "DATA11";
+ qcom,glinkpkt-dev-name = "smd11";
+ };
+ };
+
+ pil_modem: qcom,mss@4080000 {
+ compatible = "qcom,pil-tz-generic";
+ reg = <0x4080000 0x100>;
+ interrupts = <0 250 1>;
+
+ clocks = <&clock_rpmh RPMH_CXO_CLK>;
+ clock-names = "xo";
+ qcom,proxy-clock-names = "xo";
+
+ vdd_cx-supply = <&pmxpoorwills_s5_level>;
+ qcom,proxy-reg-names = "vdd_cx";
+
+ qcom,pas-id = <0>;
+ qcom,smem-id = <421>;
+ qcom,proxy-timeout-ms = <10000>;
+ qcom,sysmon-id = <0>;
+ qcom,ssctl-instance-id = <0x12>;
+ qcom,firmware-name = "modem";
+ memory-region = <&mss_mem>;
+ status = "ok";
+
+ /* GPIO inputs from mss */
+ qcom,gpio-err-fatal = <&smp2pgpio_ssr_smp2p_1_in 0 0>;
+ qcom,gpio-err-ready = <&smp2pgpio_ssr_smp2p_1_in 1 0>;
+ qcom,gpio-proxy-unvote = <&smp2pgpio_ssr_smp2p_1_in 2 0>;
+ qcom,gpio-stop-ack = <&smp2pgpio_ssr_smp2p_1_in 3 0>;
+
+ /* GPIO output to mss */
+ qcom,gpio-force-stop = <&smp2pgpio_ssr_smp2p_1_out 0 0>;
+ };
};
#include "pmxpoorwills.dtsi"
#include "sdxpoorwills-regulator.dtsi"
+#include "sdxpoorwills-smp2p.dtsi"
#include "sdxpoorwills-usb.dtsi"
diff --git a/arch/arm/configs/sdxpoorwills-perf_defconfig b/arch/arm/configs/sdxpoorwills-perf_defconfig
index bde40e0..1826b6f 100644
--- a/arch/arm/configs/sdxpoorwills-perf_defconfig
+++ b/arch/arm/configs/sdxpoorwills-perf_defconfig
@@ -195,6 +195,7 @@
CONFIG_INPUT_GPIO=m
CONFIG_SERIO_LIBPS2=y
# CONFIG_LEGACY_PTYS is not set
+CONFIG_DIAG_CHAR=y
CONFIG_HW_RANDOM=y
CONFIG_I2C=y
CONFIG_I2C_CHARDEV=y
@@ -280,10 +281,15 @@
CONFIG_QCOM_SCM=y
CONFIG_MSM_BOOT_STATS=y
CONFIG_MSM_SMEM=y
+CONFIG_MSM_GLINK=y
+CONFIG_MSM_GLINK_LOOPBACK_SERVER=y
+CONFIG_MSM_GLINK_SMEM_NATIVE_XPRT=y
CONFIG_TRACER_PKT=y
CONFIG_MSM_SMP2P=y
CONFIG_MSM_SMP2P_TEST=y
+CONFIG_MSM_IPC_ROUTER_GLINK_XPRT=y
CONFIG_MSM_QMI_INTERFACE=y
+CONFIG_MSM_GLINK_PKT=y
CONFIG_MSM_SUBSYSTEM_RESTART=y
CONFIG_MSM_PIL=y
CONFIG_MSM_PIL_SSR_GENERIC=y
diff --git a/arch/arm/configs/sdxpoorwills_defconfig b/arch/arm/configs/sdxpoorwills_defconfig
index 24ae9bd..ce61464 100644
--- a/arch/arm/configs/sdxpoorwills_defconfig
+++ b/arch/arm/configs/sdxpoorwills_defconfig
@@ -189,6 +189,7 @@
# CONFIG_LEGACY_PTYS is not set
CONFIG_SERIAL_MSM=y
CONFIG_SERIAL_MSM_CONSOLE=y
+CONFIG_DIAG_CHAR=y
CONFIG_HW_RANDOM=y
CONFIG_I2C=y
CONFIG_I2C_CHARDEV=y
@@ -204,6 +205,7 @@
CONFIG_POWER_SUPPLY=y
CONFIG_THERMAL=y
CONFIG_THERMAL_TSENS=y
+CONFIG_MFD_SYSCON=y
CONFIG_MSM_CDC_PINCTRL=y
CONFIG_MSM_CDC_SUPPLY=y
CONFIG_REGULATOR=y
@@ -272,14 +274,20 @@
CONFIG_IPA_UT=y
CONFIG_SPS=y
CONFIG_SPS_SUPPORT_NDP_BAM=y
-CONFIG_HWSPINLOCK_QCOM=y
+CONFIG_REMOTE_SPINLOCK_MSM=y
CONFIG_MAILBOX=y
-CONFIG_QCOM_SMEM=y
-CONFIG_QCOM_SMD=y
CONFIG_QCOM_SCM=y
CONFIG_MSM_BOOT_STATS=y
+CONFIG_MSM_SMEM=y
+CONFIG_MSM_GLINK=y
+CONFIG_MSM_GLINK_LOOPBACK_SERVER=y
+CONFIG_MSM_GLINK_SMEM_NATIVE_XPRT=y
CONFIG_TRACER_PKT=y
+CONFIG_MSM_SMP2P=y
+CONFIG_MSM_SMP2P_TEST=y
+CONFIG_MSM_IPC_ROUTER_GLINK_XPRT=y
CONFIG_MSM_QMI_INTERFACE=y
+CONFIG_MSM_GLINK_PKT=y
CONFIG_MSM_SUBSYSTEM_RESTART=y
CONFIG_MSM_PIL=y
CONFIG_MSM_PIL_SSR_GENERIC=y
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
index aec74bf..a9ef54d 100644
--- a/arch/arm/mm/fault.c
+++ b/arch/arm/mm/fault.c
@@ -314,8 +314,11 @@
* signal first. We do not need to release the mmap_sem because
* it would already be released in __lock_page_or_retry in
* mm/filemap.c. */
- if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current))
+ if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current)) {
+ if (!user_mode(regs))
+ goto no_context;
return 0;
+ }
/*
* Major/minor page fault accounting is only done on the
diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
index f96fba6..e1454fb 100644
--- a/arch/arm64/Kconfig.platforms
+++ b/arch/arm64/Kconfig.platforms
@@ -139,6 +139,15 @@
This enables support for the SDM670 chipset. If you do not
wish to build a kernel that runs on this chipset, say 'N' here.
+config ARCH_MSM8953
+ bool "Enable Support for Qualcomm Technologies Inc. MSM8953"
+ depends on ARCH_QCOM
+ select COMMON_CLK_QCOM
+ select QCOM_GDSC
+ help
+ This enables support for the MSM8953 chipset. If you do not
+ wish to build a kernel that runs on this chipset, say 'N' here.
+
config ARCH_ROCKCHIP
bool "Rockchip Platforms"
select ARCH_HAS_RESET_CONTROLLER
diff --git a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
index 49a5d8c..68e6f88 100644
--- a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
@@ -170,6 +170,7 @@
interrupt-controller;
reg = <0x1d00000 0x10000>, /* GICD */
<0x1d40000 0x40000>; /* GICR */
+ interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
};
};
diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile
index 779ace6..276e09c 100644
--- a/arch/arm64/boot/dts/qcom/Makefile
+++ b/arch/arm64/boot/dts/qcom/Makefile
@@ -92,7 +92,14 @@
sdm670-usbc-external-codec-cdp-overlay.dtbo \
sdm670-usbc-external-codec-mtp-overlay.dtbo \
sdm670-usbc-external-codec-pm660a-cdp-overlay.dtbo \
- sdm670-usbc-external-codec-pm660a-mtp-overlay.dtbo
+ sdm670-usbc-external-codec-pm660a-mtp-overlay.dtbo \
+ sda670-cdp-overlay.dtbo \
+ sda670-mtp-overlay.dtbo \
+ sda670-pm660a-cdp-overlay.dtbo \
+ sda670-pm660a-mtp-overlay.dtbo \
+ qcs605-cdp-overlay.dtbo \
+ qcs605-mtp-overlay.dtbo \
+ qcs605-external-codec-mtp-overlay.dtbo
sdm670-cdp-overlay.dtbo-base := sdm670.dtb
sdm670-mtp-overlay.dtbo-base := sdm670.dtb
@@ -111,6 +118,14 @@
sdm670-usbc-external-codec-mtp-overlay.dtbo-base := sdm670.dtb
sdm670-usbc-external-codec-pm660a-cdp-overlay.dtbo-base := sdm670.dtb
sdm670-usbc-external-codec-pm660a-mtp-overlay.dtbo-base := sdm670.dtb
+sda670-cdp-overlay.dtbo-base := sda670.dtb
+sda670-mtp-overlay.dtbo-base := sda670.dtb
+sda670-pm660a-cdp-overlay.dtbo-base := sda670.dtb
+sda670-pm660a-mtp-overlay.dtbo-base := sda670.dtb
+qcs605-cdp-overlay.dtbo-base := qcs605.dtb
+qcs605-mtp-overlay.dtbo-base := qcs605.dtb
+qcs605-external-codec-mtp-overlay.dtbo-base := qcs605.dtb
+
else
dtb-$(CONFIG_ARCH_SDM670) += sdm670-rumi.dtb \
sdm670-mtp.dtb \
@@ -128,7 +143,14 @@
sdm670-usbc-external-codec-pm660a-mtp.dtb \
sdm670-usbc-mtp.dtb \
sdm670-usbc-pm660a-cdp.dtb \
- sdm670-usbc-pm660a-mtp.dtb
+ sdm670-usbc-pm660a-mtp.dtb \
+ sda670-mtp.dtb \
+ sda670-cdp.dtb \
+ sda670-pm660a-mtp.dtb \
+ sda670-pm660a-cdp.dtb \
+ qcs605-mtp.dtb \
+ qcs605-cdp.dtb \
+ qcs605-external-codec-mtp.dtb
endif
always := $(dtb-y)
diff --git a/arch/arm64/boot/dts/qcom/pm660.dtsi b/arch/arm64/boot/dts/qcom/pm660.dtsi
index 80103cb..1fdb3f6 100644
--- a/arch/arm64/boot/dts/qcom/pm660.dtsi
+++ b/arch/arm64/boot/dts/qcom/pm660.dtsi
@@ -353,15 +353,6 @@
};
};
- pm660_rradc: rradc@4500 {
- compatible = "qcom,rradc";
- reg = <0x4500 0x100>;
- #address-cells = <1>;
- #size-cells = <0>;
- #io-channel-cells = <1>;
- qcom,pmic-revid = <&pm660_revid>;
- };
-
bcl_sensor: bcl@4200 {
compatible = "qcom,msm-bcl-lmh";
reg = <0x4200 0xff>,
diff --git a/arch/arm64/boot/dts/qcom/qcs605-cdp-overlay.dts b/arch/arm64/boot/dts/qcom/qcs605-cdp-overlay.dts
new file mode 100644
index 0000000..fe7a027
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/qcs605-cdp-overlay.dts
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/clock/qcom,gcc-sdm845.h>
+#include <dt-bindings/clock/qcom,camcc-sdm845.h>
+#include <dt-bindings/clock/qcom,dispcc-sdm845.h>
+#include <dt-bindings/clock/qcom,rpmh.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include "sdm670-cdp.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. QCS605 PM660 + PM660L CDP";
+ compatible = "qcom,qcs605-cdp", "qcom,qcs605", "qcom,cdp";
+ qcom,msm-id = <347 0x0>;
+ qcom,board-id = <1 0>;
+ qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>,
+ <0x0001001b 0x0102001a 0x0 0x0>,
+ <0x0001001b 0x0201011a 0x0 0x0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/qcs605-cdp.dts b/arch/arm64/boot/dts/qcom/qcs605-cdp.dts
new file mode 100644
index 0000000..7b38a58
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/qcs605-cdp.dts
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+
+/dts-v1/;
+
+#include "qcs605.dtsi"
+#include "sdm670-cdp.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. QCS605 PM660 + PM660L CDP";
+ compatible = "qcom,qcs605-cdp", "qcom,qcs605", "qcom,cdp";
+ qcom,board-id = <1 0>;
+ qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>,
+ <0x0001001b 0x0102001a 0x0 0x0>,
+ <0x0001001b 0x0201011a 0x0 0x0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/qcs605-external-codec-mtp-overlay.dts b/arch/arm64/boot/dts/qcom/qcs605-external-codec-mtp-overlay.dts
new file mode 100644
index 0000000..1f439ae
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/qcs605-external-codec-mtp-overlay.dts
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/clock/qcom,gcc-sdm845.h>
+#include <dt-bindings/clock/qcom,camcc-sdm845.h>
+#include <dt-bindings/clock/qcom,dispcc-sdm845.h>
+#include <dt-bindings/clock/qcom,rpmh.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include "sdm670-mtp.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. QCS605 PM660 + PM660L Ext. Audio Codec MTP";
+ compatible = "qcom,qcs605-mtp", "qcom,qcs605", "qcom,mtp";
+ qcom,msm-id = <347 0x0>;
+ qcom,board-id = <8 1>;
+ qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>,
+ <0x0001001b 0x0102001a 0x0 0x0>,
+ <0x0001001b 0x0201011a 0x0 0x0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/qcs605-external-codec-mtp.dts b/arch/arm64/boot/dts/qcom/qcs605-external-codec-mtp.dts
new file mode 100644
index 0000000..abc3f2d
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/qcs605-external-codec-mtp.dts
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+
+/dts-v1/;
+
+#include "qcs605.dtsi"
+#include "sdm670-mtp.dtsi"
+#include "sdm670-external-codec.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. QCS605 PM660 + PM660L Ext. Audio Codec MTP";
+ compatible = "qcom,qcs605-mtp", "qcom,qcs605", "qcom,mtp";
+ qcom,board-id = <8 1>;
+ qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>,
+ <0x0001001b 0x0102001a 0x0 0x0>,
+ <0x0001001b 0x0201011a 0x0 0x0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/qcs605-mtp-overlay.dts b/arch/arm64/boot/dts/qcom/qcs605-mtp-overlay.dts
new file mode 100644
index 0000000..7327440
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/qcs605-mtp-overlay.dts
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/clock/qcom,gcc-sdm845.h>
+#include <dt-bindings/clock/qcom,camcc-sdm845.h>
+#include <dt-bindings/clock/qcom,dispcc-sdm845.h>
+#include <dt-bindings/clock/qcom,rpmh.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include "sdm670-mtp.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. QCS605 PM660 + PM660L MTP";
+ compatible = "qcom,qcs605-mtp", "qcom,qcs605", "qcom,mtp";
+ qcom,msm-id = <347 0x0>;
+ qcom,board-id = <8 0>;
+ qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>,
+ <0x0001001b 0x0102001a 0x0 0x0>,
+ <0x0001001b 0x0201011a 0x0 0x0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/qcs605-mtp.dts b/arch/arm64/boot/dts/qcom/qcs605-mtp.dts
new file mode 100644
index 0000000..bc7b376
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/qcs605-mtp.dts
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+
+/dts-v1/;
+
+#include "qcs605.dtsi"
+#include "sdm670-mtp.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. QCS605 PM660 + PM660L MTP";
+ compatible = "qcom,qcs605-mtp", "qcom,qcs605", "qcom,mtp";
+ qcom,board-id = <8 0>;
+ qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>,
+ <0x0001001b 0x0102001a 0x0 0x0>,
+ <0x0001001b 0x0201011a 0x0 0x0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/qcs605.dts b/arch/arm64/boot/dts/qcom/qcs605.dts
new file mode 100644
index 0000000..28c417f
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/qcs605.dts
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+/dts-v1/;
+
+#include "qcs605.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. QCS605 SoC";
+ compatible = "qcom,qcs605";
+ qcom,board-id = <0 0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/qcs605.dtsi b/arch/arm64/boot/dts/qcom/qcs605.dtsi
new file mode 100644
index 0000000..12da650
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/qcs605.dtsi
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2017, 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 "sda670.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. QCS605";
+ qcom,msm-id = <347 0x0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sda670-cdp-overlay.dts b/arch/arm64/boot/dts/qcom/sda670-cdp-overlay.dts
new file mode 100644
index 0000000..141ed59
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sda670-cdp-overlay.dts
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/clock/qcom,gcc-sdm845.h>
+#include <dt-bindings/clock/qcom,camcc-sdm845.h>
+#include <dt-bindings/clock/qcom,dispcc-sdm845.h>
+#include <dt-bindings/clock/qcom,rpmh.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include "sdm670-cdp.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDA670 PM660 + PM660L CDP";
+ compatible = "qcom,sda670-cdp", "qcom,sda670", "qcom,cdp";
+ qcom,msm-id = <337 0x0>;
+ qcom,board-id = <1 0>;
+ qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>,
+ <0x0001001b 0x0102001a 0x0 0x0>,
+ <0x0001001b 0x0201011a 0x0 0x0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sda670-cdp.dts b/arch/arm64/boot/dts/qcom/sda670-cdp.dts
new file mode 100644
index 0000000..fcb340e
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sda670-cdp.dts
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+
+/dts-v1/;
+
+#include "sda670.dtsi"
+#include "sdm670-cdp.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDA670 PM660 + PM660L CDP";
+ compatible = "qcom,sda670-cdp", "qcom,sda670", "qcom,cdp";
+ qcom,board-id = <1 0>;
+ qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>,
+ <0x0001001b 0x0102001a 0x0 0x0>,
+ <0x0001001b 0x0201011a 0x0 0x0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sda670-mtp-overlay.dts b/arch/arm64/boot/dts/qcom/sda670-mtp-overlay.dts
new file mode 100644
index 0000000..af8e8f1
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sda670-mtp-overlay.dts
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/clock/qcom,gcc-sdm845.h>
+#include <dt-bindings/clock/qcom,camcc-sdm845.h>
+#include <dt-bindings/clock/qcom,dispcc-sdm845.h>
+#include <dt-bindings/clock/qcom,rpmh.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include "sdm670-mtp.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDA670 PM660 + PM660L MTP";
+ compatible = "qcom,sda670-mtp", "qcom,sda670", "qcom,mtp";
+ qcom,msm-id = <337 0x0>;
+ qcom,board-id = <8 0>;
+ qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>,
+ <0x0001001b 0x0102001a 0x0 0x0>,
+ <0x0001001b 0x0201011a 0x0 0x0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sda670-mtp.dts b/arch/arm64/boot/dts/qcom/sda670-mtp.dts
new file mode 100644
index 0000000..2123b44
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sda670-mtp.dts
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+
+/dts-v1/;
+
+#include "sda670.dtsi"
+#include "sdm670-mtp.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDA670 PM660 + PM660L MTP";
+ compatible = "qcom,sda670-mtp", "qcom,sda670", "qcom,mtp";
+ qcom,board-id = <8 0>;
+ qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>,
+ <0x0001001b 0x0102001a 0x0 0x0>,
+ <0x0001001b 0x0201011a 0x0 0x0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sda670-pm660a-cdp-overlay.dts b/arch/arm64/boot/dts/qcom/sda670-pm660a-cdp-overlay.dts
new file mode 100644
index 0000000..3e1365d
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sda670-pm660a-cdp-overlay.dts
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/clock/qcom,gcc-sdm845.h>
+#include <dt-bindings/clock/qcom,camcc-sdm845.h>
+#include <dt-bindings/clock/qcom,dispcc-sdm845.h>
+#include <dt-bindings/clock/qcom,rpmh.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include "sdm670-cdp.dtsi"
+#include "pm660a.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDA670 PM660 + PM660A CDP";
+ compatible = "qcom,sda670-cdp", "qcom,sda670", "qcom,cdp";
+ qcom,msm-id = <337 0x0>;
+ qcom,board-id = <1 0>;
+ qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>,
+ <0x0001001b 0x0002001a 0x0 0x0>,
+ <0x0001001b 0x0202001a 0x0 0x0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sda670-pm660a-cdp.dts b/arch/arm64/boot/dts/qcom/sda670-pm660a-cdp.dts
new file mode 100644
index 0000000..6cbf224
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sda670-pm660a-cdp.dts
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+
+/dts-v1/;
+
+#include "sda670.dtsi"
+#include "sdm670-cdp.dtsi"
+#include "pm660a.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDA670 PM660 + PM660A CDP";
+ compatible = "qcom,sda670-cdp", "qcom,sda670", "qcom,cdp";
+ qcom,board-id = <1 0>;
+ qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>,
+ <0x0001001b 0x0002001a 0x0 0x0>,
+ <0x0001001b 0x0202001a 0x0 0x0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sda670-pm660a-mtp-overlay.dts b/arch/arm64/boot/dts/qcom/sda670-pm660a-mtp-overlay.dts
new file mode 100644
index 0000000..9855b11
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sda670-pm660a-mtp-overlay.dts
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/clock/qcom,gcc-sdm845.h>
+#include <dt-bindings/clock/qcom,camcc-sdm845.h>
+#include <dt-bindings/clock/qcom,dispcc-sdm845.h>
+#include <dt-bindings/clock/qcom,rpmh.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include "sdm670-mtp.dtsi"
+#include "pm660a.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDA670 PM660 + PM660A MTP";
+ compatible = "qcom,sda670-mtp", "qcom,sda670", "qcom,mtp";
+ qcom,msm-id = <337 0x0>;
+ qcom,board-id = <8 0>;
+ qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>,
+ <0x0001001b 0x0002001a 0x0 0x0>,
+ <0x0001001b 0x0202001a 0x0 0x0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sda670-pm660a-mtp.dts b/arch/arm64/boot/dts/qcom/sda670-pm660a-mtp.dts
new file mode 100644
index 0000000..ffb6aa3
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sda670-pm660a-mtp.dts
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+
+/dts-v1/;
+
+#include "sda670.dtsi"
+#include "sdm670-mtp.dtsi"
+#include "pm660a.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDA670 PM660 + PM660A MTP";
+ compatible = "qcom,sda670-mtp", "qcom,sda670", "qcom,mtp";
+ qcom,board-id = <8 0>;
+ qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>,
+ <0x0001001b 0x0002001a 0x0 0x0>,
+ <0x0001001b 0x0202001a 0x0 0x0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sda670.dts b/arch/arm64/boot/dts/qcom/sda670.dts
new file mode 100644
index 0000000..8852e30
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sda670.dts
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+/dts-v1/;
+
+#include "sda670.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDA670 SoC";
+ compatible = "qcom,sda670";
+ qcom,board-id = <0 0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sda670.dtsi b/arch/arm64/boot/dts/qcom/sda670.dtsi
new file mode 100644
index 0000000..d19aac3
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sda670.dtsi
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2017, 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 "sdm670.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDA670";
+ qcom,msm-id = <337 0x0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm670-audio-overlay.dtsi b/arch/arm64/boot/dts/qcom/sdm670-audio-overlay.dtsi
new file mode 100644
index 0000000..94ac27d
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm670-audio-overlay.dtsi
@@ -0,0 +1,375 @@
+/*
+ * Copyright (c) 2017, 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 "sdm670-wcd.dtsi"
+#include "sdm670-wsa881x.dtsi"
+#include <dt-bindings/clock/qcom,audio-ext-clk.h>
+
+&tavil_snd {
+ qcom,msm-mi2s-master = <1>, <1>, <1>, <1>;
+ qcom,audio-routing =
+ "AIF4 VI", "MCLK",
+ "RX_BIAS", "MCLK",
+ "MADINPUT", "MCLK",
+ "hifi amp", "LINEOUT1",
+ "hifi amp", "LINEOUT2",
+ "AMIC2", "MIC BIAS2",
+ "MIC BIAS2", "Headset Mic",
+ "AMIC3", "MIC BIAS2",
+ "MIC BIAS2", "ANCRight Headset Mic",
+ "AMIC4", "MIC BIAS2",
+ "MIC BIAS2", "ANCLeft Headset Mic",
+ "AMIC5", "MIC BIAS3",
+ "MIC BIAS3", "Handset Mic",
+ "DMIC0", "MIC BIAS1",
+ "MIC BIAS1", "Digital Mic0",
+ "DMIC1", "MIC BIAS1",
+ "MIC BIAS1", "Digital Mic1",
+ "DMIC2", "MIC BIAS3",
+ "MIC BIAS3", "Digital Mic2",
+ "DMIC3", "MIC BIAS3",
+ "MIC BIAS3", "Digital Mic3",
+ "DMIC4", "MIC BIAS4",
+ "MIC BIAS4", "Digital Mic4",
+ "DMIC5", "MIC BIAS4",
+ "MIC BIAS4", "Digital Mic5",
+ "SpkrLeft IN", "SPK1 OUT",
+ "SpkrRight IN", "SPK2 OUT";
+
+ qcom,msm-mbhc-hphl-swh = <1>;
+ qcom,msm-mbhc-gnd-swh = <1>;
+ qcom,hph-en0-gpio = <&tavil_hph_en0>;
+ qcom,hph-en1-gpio = <&tavil_hph_en1>;
+ qcom,msm-mclk-freq = <9600000>;
+ qcom,usbc-analog-en1_gpio = <&wcd_usbc_analog_en1_gpio>;
+ asoc-codec = <&stub_codec>;
+ asoc-codec-names = "msm-stub-codec.1";
+ qcom,wsa-max-devs = <2>;
+ qcom,wsa-devs = <&wsa881x_0211>, <&wsa881x_0212>,
+ <&wsa881x_0213>, <&wsa881x_0214>;
+ qcom,wsa-aux-dev-prefix = "SpkrLeft", "SpkrRight",
+ "SpkrLeft", "SpkrRight";
+};
+
+&int_codec {
+ qcom,audio-routing =
+ "RX_BIAS", "INT_MCLK0",
+ "SPK_RX_BIAS", "INT_MCLK0",
+ "INT_LDO_H", "INT_MCLK0",
+ "MIC BIAS External", "Handset Mic",
+ "MIC BIAS External2", "Headset Mic",
+ "MIC BIAS External", "Secondary Mic",
+ "AMIC1", "MIC BIAS External",
+ "AMIC2", "MIC BIAS External2",
+ "AMIC3", "MIC BIAS External",
+ "DMIC1", "MIC BIAS External",
+ "MIC BIAS External", "Digital Mic1",
+ "DMIC2", "MIC BIAS External",
+ "MIC BIAS External", "Digital Mic2",
+ "DMIC3", "MIC BIAS External",
+ "MIC BIAS External", "Digital Mic3",
+ "DMIC4", "MIC BIAS External",
+ "MIC BIAS External", "Digital Mic4",
+ "SpkrLeft IN", "SPK1 OUT",
+ "SpkrRight IN", "SPK2 OUT",
+ "PDM_IN_RX1", "PDM_OUT_RX1",
+ "PDM_IN_RX2", "PDM_OUT_RX2",
+ "PDM_IN_RX3", "PDM_OUT_RX3",
+ "ADC1_IN", "ADC1_OUT",
+ "ADC2_IN", "ADC2_OUT",
+ "ADC3_IN", "ADC3_OUT";
+
+ qcom,msm-mi2s-master = <1>, <1>, <1>, <1>;
+ qcom,msm-mclk-freq = <9600000>;
+ qcom,msm-mbhc-hphl-swh = <1>;
+ qcom,msm-mbhc-gnd-swh = <1>;
+ qcom,msm-micbias2-ext-cap;
+ qcom,msm-hs-micbias-type = "external";
+ qcom,cdc-pdm-gpios = <&cdc_pdm_gpios>;
+ qcom,cdc-comp-gpios = <&cdc_comp_gpios>;
+ qcom,cdc-dmic-gpios = <&cdc_dmic_gpios>;
+
+ asoc-codec = <&stub_codec>, <&msm_digital_codec>,
+ <&pmic_analog_codec>, <&msm_sdw_codec>;
+ asoc-codec-names = "msm-stub-codec.1", "msm-dig-codec",
+ "analog-codec", "msm_sdw_codec";
+
+ qcom,wsa-max-devs = <2>;
+ qcom,wsa-devs = <&wsa881x_211_en>, <&wsa881x_212_en>,
+ <&wsa881x_213_en>, <&wsa881x_214_en>;
+ qcom,wsa-aux-dev-prefix = "SpkrLeft", "SpkrRight",
+ "SpkrLeft", "SpkrRight";
+};
+
+&soc {
+ wcd_usbc_analog_en1_gpio: msm_cdc_pinctrl_usbc_audio_en1 {
+ compatible = "qcom,msm-cdc-pinctrl";
+ pinctrl-names = "aud_active", "aud_sleep";
+ pinctrl-0 = <&wcd_usbc_analog_en1_active>;
+ pinctrl-1 = <&wcd_usbc_analog_en1_idle>;
+ };
+
+ cdc_pdm_gpios: cdc_pdm_pinctrl {
+ compatible = "qcom,msm-cdc-pinctrl";
+ pinctrl-names = "aud_active", "aud_sleep";
+ pinctrl-0 = <&cdc_pdm_clk_active &cdc_pdm_sync_active
+ &cdc_pdm_rx0_active &cdc_pdm_rx1_2_active
+ &cdc_pdm_2_gpios_active>;
+ pinctrl-1 = <&cdc_pdm_clk_sleep &cdc_pdm_sync_sleep
+ &cdc_pdm_rx0_sleep &cdc_pdm_rx1_2_sleep
+ &cdc_pdm_2_gpios_sleep>;
+ qcom,lpi-gpios;
+ };
+
+ cdc_comp_gpios: cdc_comp_pinctrl {
+ compatible = "qcom,msm-cdc-pinctrl";
+ pinctrl-names = "aud_active", "aud_sleep";
+ pinctrl-0 = <&cdc_rx0_comp_active &cdc_rx1_comp_active>;
+ pinctrl-1 = <&cdc_rx0_comp_sleep &cdc_rx1_comp_sleep>;
+ qcom,lpi-gpios;
+ };
+
+ cdc_dmic_gpios: cdc_dmic_pinctrl {
+ compatible = "qcom,msm-cdc-pinctrl";
+ pinctrl-names = "aud_active", "aud_sleep";
+ pinctrl-0 = <&cdc_dmic12_gpios_active
+ &cdc_dmic34_gpios_active>;
+ pinctrl-1 = <&cdc_dmic12_gpios_sleep
+ &cdc_dmic34_gpios_sleep>;
+ qcom,lpi-gpios;
+ };
+
+ cdc_sdw_gpios: sdw_clk_data_pinctrl {
+ compatible = "qcom,msm-cdc-pinctrl";
+ pinctrl-names = "aud_active", "aud_sleep";
+ pinctrl-0 = <&sdw_clk_active &sdw_data_active>;
+ pinctrl-1 = <&sdw_clk_sleep &sdw_data_sleep>;
+ };
+
+ wsa_spkr_en1: wsa_spkr_en1_pinctrl {
+ compatible = "qcom,msm-cdc-pinctrl";
+ pinctrl-names = "aud_active", "aud_sleep";
+ pinctrl-0 = <&spkr_1_sd_n_active>;
+ pinctrl-1 = <&spkr_1_sd_n_sleep>;
+ };
+
+ wsa_spkr_en2: wsa_spkr_en2_pinctrl {
+ compatible = "qcom,msm-cdc-pinctrl";
+ pinctrl-names = "aud_active", "aud_sleep";
+ pinctrl-0 = <&spkr_2_sd_n_active>;
+ pinctrl-1 = <&spkr_2_sd_n_sleep>;
+ };
+
+ msm_sdw_codec: msm-sdw-codec@62ec1000 {
+ status = "okay";
+ compatible = "qcom,msm-sdw-codec";
+ reg = <0x62ec1000 0x0>;
+ interrupts = <0 161 0>;
+ interrupt-names = "swr_master_irq";
+ qcom,cdc-sdw-gpios = <&cdc_sdw_gpios>;
+
+ swr_master {
+ compatible = "qcom,swr-wcd";
+ #address-cells = <2>;
+ #size-cells = <0>;
+
+ wsa881x_211_en: wsa881x_en@20170211 {
+ compatible = "qcom,wsa881x";
+ reg = <0x0 0x20170211>;
+ qcom,spkr-sd-n-node = <&wsa_spkr_en1>;
+ };
+
+ wsa881x_212_en: wsa881x_en@20170212 {
+ compatible = "qcom,wsa881x";
+ reg = <0x0 0x20170212>;
+ qcom,spkr-sd-n-node = <&wsa_spkr_en2>;
+ };
+
+ wsa881x_213_en: wsa881x_en@21170213 {
+ compatible = "qcom,wsa881x";
+ reg = <0x0 0x21170213>;
+ qcom,spkr-sd-n-node = <&wsa_spkr_en1>;
+ };
+
+ wsa881x_214_en: wsa881x_en@21170214 {
+ compatible = "qcom,wsa881x";
+ reg = <0x0 0x21170214>;
+ qcom,spkr-sd-n-node = <&wsa_spkr_en2>;
+ };
+ };
+ };
+
+ wcd9xxx_intc: wcd9xxx-irq {
+ status = "disabled";
+ compatible = "qcom,wcd9xxx-irq";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ interrupt-parent = <&tlmm>;
+ qcom,gpio-connect = <&tlmm 80 0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&wcd_intr_default>;
+ };
+
+ clock_audio_lnbb: audio_ext_clk_lnbb {
+ status = "disabled";
+ compatible = "qcom,audio-ref-clk";
+ clock-names = "osr_clk";
+ clocks = <&clock_rpmh RPMH_LN_BB_CLK2>;
+ qcom,node_has_rpm_clock;
+ #clock-cells = <1>;
+ };
+
+ wcd_rst_gpio: msm_cdc_pinctrl@64 {
+ status = "disabled";
+ compatible = "qcom,msm-cdc-pinctrl";
+ pinctrl-names = "aud_active", "aud_sleep";
+ pinctrl-0 = <&lpi_cdc_reset_active>;
+ pinctrl-1 = <&lpi_cdc_reset_sleep>;
+ qcom,lpi-gpios;
+ };
+
+ wdsp_mgr: qcom,wcd-dsp-mgr {
+ compatible = "qcom,wcd-dsp-mgr";
+ qcom,wdsp-components = <&wcd934x_cdc 0>,
+ <&wcd_spi_0 1>,
+ <&glink_spi_xprt_wdsp 2>;
+ qcom,img-filename = "cpe_9340";
+ };
+
+ wdsp_glink: qcom,wcd-dsp-glink {
+ compatible = "qcom,wcd-dsp-glink";
+ };
+};
+
+&slim_aud {
+ wcd934x_cdc: tavil_codec {
+ status = "disabled";
+ compatible = "qcom,tavil-slim-pgd";
+ elemental-addr = [00 01 50 02 17 02];
+
+ interrupt-parent = <&wcd9xxx_intc>;
+ interrupts = <0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
+ 17 18 19 20 21 22 23 24 25 26 27 28 29
+ 30 31>;
+
+ qcom,wcd-rst-gpio-node = <&wcd_rst_gpio>;
+
+ clock-names = "wcd_clk";
+ clocks = <&clock_audio_lnbb AUDIO_PMIC_LNBB_CLK>;
+
+ cdc-vdd-mic-bias-supply = <&pm660l_bob>;
+ qcom,cdc-vdd-mic-bias-voltage = <3312000 3312000>;
+ qcom,cdc-vdd-mic-bias-current = <30400>;
+
+ qcom,cdc-static-supplies = "cdc-vdd-mic-bias";
+
+ qcom,cdc-micbias1-mv = <1800>;
+ qcom,cdc-micbias2-mv = <1800>;
+ qcom,cdc-micbias3-mv = <1800>;
+ qcom,cdc-micbias4-mv = <1800>;
+
+ qcom,cdc-mclk-clk-rate = <9600000>;
+ qcom,cdc-slim-ifd = "tavil-slim-ifd";
+ qcom,cdc-slim-ifd-elemental-addr = [00 00 50 02 17 02];
+ qcom,cdc-dmic-sample-rate = <4800000>;
+ qcom,cdc-mad-dmic-rate = <600000>;
+
+ qcom,wdsp-cmpnt-dev-name = "tavil_codec";
+
+ wcd_spi_0: wcd_spi {
+ compatible = "qcom,wcd-spi-v2";
+ qcom,master-bus-num = <8>;
+ qcom,chip-select = <0>;
+ qcom,max-frequency = <24000000>;
+ qcom,mem-base-addr = <0x100000>;
+ };
+ };
+};
+
+&pm660l_3 {
+ pmic_analog_codec: analog-codec@f000 {
+ status = "okay";
+ compatible = "qcom,pmic-analog-codec";
+ reg = <0xf000 0x200>;
+ #address-cells = <2>;
+ #size-cells = <0>;
+ interrupt-parent = <&spmi_bus>;
+ interrupts = <0x3 0xf0 0x0 IRQ_TYPE_NONE>,
+ <0x3 0xf0 0x1 IRQ_TYPE_NONE>,
+ <0x3 0xf0 0x2 IRQ_TYPE_NONE>,
+ <0x3 0xf0 0x3 IRQ_TYPE_NONE>,
+ <0x3 0xf0 0x4 IRQ_TYPE_NONE>,
+ <0x3 0xf0 0x5 IRQ_TYPE_NONE>,
+ <0x3 0xf0 0x6 IRQ_TYPE_NONE>,
+ <0x3 0xf0 0x7 IRQ_TYPE_NONE>,
+ <0x3 0xf1 0x0 IRQ_TYPE_NONE>,
+ <0x3 0xf1 0x1 IRQ_TYPE_NONE>,
+ <0x3 0xf1 0x2 IRQ_TYPE_NONE>,
+ <0x3 0xf1 0x3 IRQ_TYPE_NONE>,
+ <0x3 0xf1 0x4 IRQ_TYPE_NONE>,
+ <0x3 0xf1 0x5 IRQ_TYPE_NONE>;
+ interrupt-names = "spk_cnp_int",
+ "spk_clip_int",
+ "spk_ocp_int",
+ "ins_rem_det1",
+ "but_rel_det",
+ "but_press_det",
+ "ins_rem_det",
+ "mbhc_int",
+ "ear_ocp_int",
+ "hphr_ocp_int",
+ "hphl_ocp_det",
+ "ear_cnp_int",
+ "hphr_cnp_int",
+ "hphl_cnp_int";
+
+ cdc-vdda-cp-supply = <&pm660_s4>;
+ qcom,cdc-vdda-cp-voltage = <1900000 2050000>;
+ qcom,cdc-vdda-cp-current = <50000>;
+
+ cdc-vdd-pa-supply = <&pm660_s4>;
+ qcom,cdc-vdd-pa-voltage = <2040000 2040000>;
+ qcom,cdc-vdd-pa-current = <260000>;
+
+ cdc-vdd-mic-bias-supply = <&pm660l_l7>;
+ qcom,cdc-vdd-mic-bias-voltage = <3088000 3088000>;
+ qcom,cdc-vdd-mic-bias-current = <5000>;
+
+ qcom,cdc-mclk-clk-rate = <9600000>;
+
+ qcom,cdc-static-supplies = "cdc-vdda-cp",
+ "cdc-vdd-pa";
+
+ qcom,cdc-on-demand-supplies = "cdc-vdd-mic-bias";
+
+ /*
+ * Not marking address @ as driver searches this child
+ * with name msm-dig-codec
+ */
+ msm_digital_codec: msm-dig-codec {
+ compatible = "qcom,msm-digital-codec";
+ reg = <0x62ec0000 0x0>;
+ };
+ };
+};
+
+&pm660_gpios {
+ gpio@c200 {
+ status = "ok";
+ qcom,mode = <1>;
+ qcom,pull = <4>;
+ qcom,vin-sel = <0>;
+ qcom,src-sel = <2>;
+ qcom,master-en = <1>;
+ qcom,out-strength = <2>;
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm670-audio.dtsi b/arch/arm64/boot/dts/qcom/sdm670-audio.dtsi
index 3bd0350..ac92561 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-audio.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-audio.dtsi
@@ -39,42 +39,6 @@
qcom,wcn-btfm;
qcom,mi2s-audio-intf;
qcom,auxpcm-audio-intf;
- qcom,msm-mi2s-master = <1>, <1>, <1>, <1>;
- qcom,audio-routing =
- "AIF4 VI", "MCLK",
- "RX_BIAS", "MCLK",
- "MADINPUT", "MCLK",
- "hifi amp", "LINEOUT1",
- "hifi amp", "LINEOUT2",
- "AMIC2", "MIC BIAS2",
- "MIC BIAS2", "Headset Mic",
- "AMIC3", "MIC BIAS2",
- "MIC BIAS2", "ANCRight Headset Mic",
- "AMIC4", "MIC BIAS2",
- "MIC BIAS2", "ANCLeft Headset Mic",
- "AMIC5", "MIC BIAS3",
- "MIC BIAS3", "Handset Mic",
- "DMIC0", "MIC BIAS1",
- "MIC BIAS1", "Digital Mic0",
- "DMIC1", "MIC BIAS1",
- "MIC BIAS1", "Digital Mic1",
- "DMIC2", "MIC BIAS3",
- "MIC BIAS3", "Digital Mic2",
- "DMIC3", "MIC BIAS3",
- "MIC BIAS3", "Digital Mic3",
- "DMIC4", "MIC BIAS4",
- "MIC BIAS4", "Digital Mic4",
- "DMIC5", "MIC BIAS4",
- "MIC BIAS4", "Digital Mic5",
- "SpkrLeft IN", "SPK1 OUT",
- "SpkrRight IN", "SPK2 OUT";
-
- qcom,msm-mbhc-hphl-swh = <1>;
- qcom,msm-mbhc-gnd-swh = <1>;
- qcom,hph-en0-gpio = <&tavil_hph_en0>;
- qcom,hph-en1-gpio = <&tavil_hph_en1>;
- qcom,msm-mclk-freq = <9600000>;
- qcom,usbc-analog-en1_gpio = <&wcd_usbc_analog_en1_gpio>;
asoc-platform = <&pcm0>, <&pcm1>, <&pcm2>, <&voip>, <&voice>,
<&loopback>, <&compress>, <&hostless>,
<&afe>, <&lsm>, <&routing>, <&cpe>, <&compr>,
@@ -126,58 +90,15 @@
"msm-dai-q6-tdm.36880", "msm-dai-q6-tdm.36881",
"msm-dai-q6-tdm.36896", "msm-dai-q6-tdm.36897",
"msm-dai-q6-tdm.36912", "msm-dai-q6-tdm.36913";
- asoc-codec = <&stub_codec>;
- asoc-codec-names = "msm-stub-codec.1";
- qcom,wsa-max-devs = <2>;
- qcom,wsa-devs = <&wsa881x_0211>, <&wsa881x_0212>,
- <&wsa881x_0213>, <&wsa881x_0214>;
- qcom,wsa-aux-dev-prefix = "SpkrLeft", "SpkrRight",
- "SpkrLeft", "SpkrRight";
};
-int_codec: sound {
+ int_codec: sound {
status = "okay";
compatible = "qcom,sdm670-asoc-snd";
qcom,model = "sdm670-snd-card";
qcom,wcn-btfm;
qcom,mi2s-audio-intf;
qcom,auxpcm-audio-intf;
- qcom,msm-mi2s-master = <1>, <1>, <1>, <1>;
- qcom,msm-mclk-freq = <9600000>;
- qcom,msm-mbhc-hphl-swh = <1>;
- qcom,msm-mbhc-gnd-swh = <1>;
- qcom,msm-micbias2-ext-cap;
- qcom,msm-hs-micbias-type = "external";
- qcom,cdc-pdm-gpios = <&cdc_pdm_gpios>;
- qcom,cdc-comp-gpios = <&cdc_comp_gpios>;
- qcom,cdc-dmic-gpios = <&cdc_dmic_gpios>;
- qcom,audio-routing =
- "RX_BIAS", "INT_MCLK0",
- "SPK_RX_BIAS", "INT_MCLK0",
- "INT_LDO_H", "INT_MCLK0",
- "MIC BIAS External", "Handset Mic",
- "MIC BIAS External2", "Headset Mic",
- "MIC BIAS External", "Secondary Mic",
- "AMIC1", "MIC BIAS External",
- "AMIC2", "MIC BIAS External2",
- "AMIC3", "MIC BIAS External",
- "DMIC1", "MIC BIAS External",
- "MIC BIAS External", "Digital Mic1",
- "DMIC2", "MIC BIAS External",
- "MIC BIAS External", "Digital Mic2",
- "DMIC3", "MIC BIAS External",
- "MIC BIAS External", "Digital Mic3",
- "DMIC4", "MIC BIAS External",
- "MIC BIAS External", "Digital Mic4",
- "SpkrLeft IN", "SPK1 OUT",
- "SpkrRight IN", "SPK2 OUT",
- "PDM_IN_RX1", "PDM_OUT_RX1",
- "PDM_IN_RX2", "PDM_OUT_RX2",
- "PDM_IN_RX3", "PDM_OUT_RX3",
- "ADC1_IN", "ADC1_OUT",
- "ADC2_IN", "ADC2_OUT",
- "ADC3_IN", "ADC3_OUT";
-
asoc-platform = <&pcm0>, <&pcm1>, <&pcm2>, <&voip>, <&voice>,
<&loopback>, <&compress>, <&hostless>,
<&afe>, <&lsm>, <&routing>, <&compr>,
@@ -224,135 +145,6 @@
"msm-dai-q6-tdm.36880", "msm-dai-q6-tdm.36881",
"msm-dai-q6-tdm.36896", "msm-dai-q6-tdm.36897",
"msm-dai-q6-tdm.36912", "msm-dai-q6-tdm.36913";
- asoc-codec = <&stub_codec>, <&msm_digital_codec>,
- <&pmic_analog_codec>, <&msm_sdw_codec>;
- asoc-codec-names = "msm-stub-codec.1", "msm-dig-codec",
- "analog-codec", "msm_sdw_codec";
-
- qcom,wsa-max-devs = <2>;
- qcom,wsa-devs = <&wsa881x_211_en>, <&wsa881x_212_en>,
- <&wsa881x_213_en>, <&wsa881x_214_en>;
- qcom,wsa-aux-dev-prefix = "SpkrLeft", "SpkrRight",
- "SpkrLeft", "SpkrRight";
- };
-
- cdc_pdm_gpios: cdc_pdm_pinctrl {
- compatible = "qcom,msm-cdc-pinctrl";
- pinctrl-names = "aud_active", "aud_sleep";
- pinctrl-0 = <&cdc_pdm_clk_active &cdc_pdm_sync_active
- &cdc_pdm_rx0_active &cdc_pdm_rx1_2_active
- &cdc_pdm_2_gpios_active>;
- pinctrl-1 = <&cdc_pdm_clk_sleep &cdc_pdm_sync_sleep
- &cdc_pdm_rx0_sleep &cdc_pdm_rx1_2_sleep
- &cdc_pdm_2_gpios_sleep>;
- qcom,lpi-gpios;
- };
-
- cdc_comp_gpios: cdc_comp_pinctrl {
- compatible = "qcom,msm-cdc-pinctrl";
- pinctrl-names = "aud_active", "aud_sleep";
- pinctrl-0 = <&cdc_rx0_comp_active &cdc_rx1_comp_active>;
- pinctrl-1 = <&cdc_rx0_comp_sleep &cdc_rx1_comp_sleep>;
- qcom,lpi-gpios;
- };
-
- cdc_dmic_gpios: cdc_dmic_pinctrl {
- compatible = "qcom,msm-cdc-pinctrl";
- pinctrl-names = "aud_active", "aud_sleep";
- pinctrl-0 = <&cdc_dmic12_gpios_active
- &cdc_dmic34_gpios_active>;
- pinctrl-1 = <&cdc_dmic12_gpios_sleep
- &cdc_dmic34_gpios_sleep>;
- qcom,lpi-gpios;
- };
-
- cdc_sdw_gpios: sdw_clk_data_pinctrl {
- compatible = "qcom,msm-cdc-pinctrl";
- pinctrl-names = "aud_active", "aud_sleep";
- pinctrl-0 = <&sdw_clk_active &sdw_data_active>;
- pinctrl-1 = <&sdw_clk_sleep &sdw_data_sleep>;
- };
-
- wsa_spkr_en1: wsa_spkr_en1_pinctrl {
- compatible = "qcom,msm-cdc-pinctrl";
- pinctrl-names = "aud_active", "aud_sleep";
- pinctrl-0 = <&spkr_1_sd_n_active>;
- pinctrl-1 = <&spkr_1_sd_n_sleep>;
- };
-
- wsa_spkr_en2: wsa_spkr_en2_pinctrl {
- compatible = "qcom,msm-cdc-pinctrl";
- pinctrl-names = "aud_active", "aud_sleep";
- pinctrl-0 = <&spkr_2_sd_n_active>;
- pinctrl-1 = <&spkr_2_sd_n_sleep>;
- };
-
- msm_sdw_codec: msm-sdw-codec@62ec1000 {
- status = "okay";
- compatible = "qcom,msm-sdw-codec";
- reg = <0x62ec1000 0x0>;
- interrupts = <0 161 0>;
- interrupt-names = "swr_master_irq";
- qcom,cdc-sdw-gpios = <&cdc_sdw_gpios>;
-
- swr_master {
- compatible = "qcom,swr-wcd";
- #address-cells = <2>;
- #size-cells = <0>;
-
- wsa881x_211_en: wsa881x_en@20170211 {
- compatible = "qcom,wsa881x";
- reg = <0x0 0x20170211>;
- qcom,spkr-sd-n-node = <&wsa_spkr_en1>;
- };
-
- wsa881x_212_en: wsa881x_en@20170212 {
- compatible = "qcom,wsa881x";
- reg = <0x0 0x20170212>;
- qcom,spkr-sd-n-node = <&wsa_spkr_en2>;
- };
-
- wsa881x_213_en: wsa881x_en@21170213 {
- compatible = "qcom,wsa881x";
- reg = <0x0 0x21170213>;
- qcom,spkr-sd-n-node = <&wsa_spkr_en1>;
- };
-
- wsa881x_214_en: wsa881x_en@21170214 {
- compatible = "qcom,wsa881x";
- reg = <0x0 0x21170214>;
- qcom,spkr-sd-n-node = <&wsa_spkr_en2>;
- };
- };
- };
-
- wcd9xxx_intc: wcd9xxx-irq {
- status = "disabled";
- compatible = "qcom,wcd9xxx-irq";
- interrupt-controller;
- #interrupt-cells = <1>;
- interrupt-parent = <&tlmm>;
- qcom,gpio-connect = <&tlmm 80 0>;
- pinctrl-names = "default";
- pinctrl-0 = <&wcd_intr_default>;
- };
-
- clock_audio_lnbb: audio_ext_clk_lnbb {
- status = "disabled";
- compatible = "qcom,audio-ref-clk";
- clock-names = "osr_clk";
- clocks = <&clock_rpmh RPMH_LN_BB_CLK2>;
- qcom,node_has_rpm_clock;
- #clock-cells = <1>;
- };
-
- wcd_rst_gpio: msm_cdc_pinctrl@64 {
- status = "disabled";
- compatible = "qcom,msm-cdc-pinctrl";
- pinctrl-names = "aud_active", "aud_sleep";
- pinctrl-0 = <&lpi_cdc_reset_active>;
- pinctrl-1 = <&lpi_cdc_reset_sleep>;
- qcom,lpi-gpios;
};
cpe: qcom,msm-cpe-lsm {
@@ -363,18 +155,6 @@
compatible = "qcom,msm-cpe-lsm";
qcom,msm-cpe-lsm-id = <3>;
};
-
- wdsp_mgr: qcom,wcd-dsp-mgr {
- compatible = "qcom,wcd-dsp-mgr";
- qcom,wdsp-components = <&wcd934x_cdc 0>,
- <&wcd_spi_0 1>,
- <&glink_spi_xprt_wdsp 2>;
- qcom,img-filename = "cpe_9340";
- };
-
- wdsp_glink: qcom,wcd-dsp-glink {
- compatible = "qcom,wcd-dsp-glink";
- };
};
&slim_aud {
@@ -384,56 +164,6 @@
compatible = "qcom,msm-dai-slim";
elemental-addr = [ff ff ff fe 17 02];
};
-
- wcd934x_cdc: tavil_codec {
- status = "disabled";
- compatible = "qcom,tavil-slim-pgd";
- elemental-addr = [00 01 50 02 17 02];
-
- interrupt-parent = <&wcd9xxx_intc>;
- interrupts = <0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
- 17 18 19 20 21 22 23 24 25 26 27 28 29
- 30 31>;
-
- qcom,wcd-rst-gpio-node = <&wcd_rst_gpio>;
-
- clock-names = "wcd_clk";
- clocks = <&clock_audio_lnbb AUDIO_PMIC_LNBB_CLK>;
-
- cdc-vdd-mic-bias-supply = <&pm660l_bob>;
- qcom,cdc-vdd-mic-bias-voltage = <3300000 3300000>;
- qcom,cdc-vdd-mic-bias-current = <30400>;
-
- qcom,cdc-static-supplies = "cdc-vdd-mic-bias";
-
- qcom,cdc-micbias1-mv = <1800>;
- qcom,cdc-micbias2-mv = <1800>;
- qcom,cdc-micbias3-mv = <1800>;
- qcom,cdc-micbias4-mv = <1800>;
-
- qcom,cdc-mclk-clk-rate = <9600000>;
- qcom,cdc-slim-ifd = "tavil-slim-ifd";
- qcom,cdc-slim-ifd-elemental-addr = [00 00 50 02 17 02];
- qcom,cdc-dmic-sample-rate = <4800000>;
- qcom,cdc-mad-dmic-rate = <600000>;
-
- qcom,wdsp-cmpnt-dev-name = "tavil_codec";
-
- wcd_spi_0: wcd_spi {
- compatible = "qcom,wcd-spi-v2";
- qcom,master-bus-num = <8>;
- qcom,chip-select = <0>;
- qcom,max-frequency = <24000000>;
- qcom,mem-base-addr = <0x100000>;
- };
-
- wcd_usbc_analog_en1_gpio: msm_cdc_pinctrl_usbc_audio_en1 {
- compatible = "qcom,msm-cdc-pinctrl";
- pinctrl-names = "aud_active", "aud_sleep";
- pinctrl-0 = <&wcd_usbc_analog_en1_active>;
- pinctrl-1 = <&wcd_usbc_analog_en1_idle>;
- };
- };
};
&msm_dai_mi2s {
@@ -486,83 +216,3 @@
qcom,msm-mi2s-tx-lines = <3>;
};
};
-
-&pm660l_3 {
- pmic_analog_codec: analog-codec@f000 {
- status = "okay";
- compatible = "qcom,pmic-analog-codec";
- reg = <0xf000 0x200>;
- #address-cells = <2>;
- #size-cells = <0>;
- interrupt-parent = <&spmi_bus>;
- interrupts = <0x3 0xf0 0x0 IRQ_TYPE_NONE>,
- <0x3 0xf0 0x1 IRQ_TYPE_NONE>,
- <0x3 0xf0 0x2 IRQ_TYPE_NONE>,
- <0x3 0xf0 0x3 IRQ_TYPE_NONE>,
- <0x3 0xf0 0x4 IRQ_TYPE_NONE>,
- <0x3 0xf0 0x5 IRQ_TYPE_NONE>,
- <0x3 0xf0 0x6 IRQ_TYPE_NONE>,
- <0x3 0xf0 0x7 IRQ_TYPE_NONE>,
- <0x3 0xf1 0x0 IRQ_TYPE_NONE>,
- <0x3 0xf1 0x1 IRQ_TYPE_NONE>,
- <0x3 0xf1 0x2 IRQ_TYPE_NONE>,
- <0x3 0xf1 0x3 IRQ_TYPE_NONE>,
- <0x3 0xf1 0x4 IRQ_TYPE_NONE>,
- <0x3 0xf1 0x5 IRQ_TYPE_NONE>;
- interrupt-names = "spk_cnp_int",
- "spk_clip_int",
- "spk_ocp_int",
- "ins_rem_det1",
- "but_rel_det",
- "but_press_det",
- "ins_rem_det",
- "mbhc_int",
- "ear_ocp_int",
- "hphr_ocp_int",
- "hphl_ocp_det",
- "ear_cnp_int",
- "hphr_cnp_int",
- "hphl_cnp_int";
-
-
- cdc-vdda-cp-supply = <&pm660_s4>;
- qcom,cdc-vdda-cp-voltage = <1900000 2050000>;
- qcom,cdc-vdda-cp-current = <50000>;
-
- cdc-vdd-pa-supply = <&pm660_s4>;
- qcom,cdc-vdd-pa-voltage = <2040000 2040000>;
- qcom,cdc-vdd-pa-current = <260000>;
-
- cdc-vdd-mic-bias-supply = <&pm660l_l7>;
- qcom,cdc-vdd-mic-bias-voltage = <3088000 3088000>;
- qcom,cdc-vdd-mic-bias-current = <5000>;
-
- qcom,cdc-mclk-clk-rate = <9600000>;
-
- qcom,cdc-static-supplies = "cdc-vdda-cp",
- "cdc-vdd-pa";
-
- qcom,cdc-on-demand-supplies = "cdc-vdd-mic-bias";
-
- /*
- * Not marking address @ as driver searches this child
- * with name msm-dig-codec
- */
- msm_digital_codec: msm-dig-codec {
- compatible = "qcom,msm-digital-codec";
- reg = <0x62ec0000 0x0>;
- };
- };
-};
-
-&pm660_gpios {
- gpio@c200 {
- status = "ok";
- qcom,mode = <1>;
- qcom,pull = <4>;
- qcom,vin-sel = <0>;
- qcom,src-sel = <2>;
- qcom,master-en = <1>;
- qcom,out-strength = <2>;
- };
-};
diff --git a/arch/arm64/boot/dts/qcom/sdm670-cdp.dts b/arch/arm64/boot/dts/qcom/sdm670-cdp.dts
index 27882dd..7aa87a2 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-cdp.dts
+++ b/arch/arm64/boot/dts/qcom/sdm670-cdp.dts
@@ -15,6 +15,7 @@
#include "sdm670.dtsi"
#include "sdm670-cdp.dtsi"
+#include "sdm670-int-codec-audio-overlay.dtsi"
/ {
model = "Qualcomm Technologies, Inc. SDM670 PM660 + PM660L CDP";
diff --git a/arch/arm64/boot/dts/qcom/sdm670-cdp.dtsi b/arch/arm64/boot/dts/qcom/sdm670-cdp.dtsi
index 00f454c..257698a 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-cdp.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-cdp.dtsi
@@ -10,7 +10,9 @@
* GNU General Public License for more details.
*/
+#include <dt-bindings/gpio/gpio.h>
#include "sdm670-pmic-overlay.dtsi"
+#include "sdm670-sde-display.dtsi"
&ufsphy_mem {
compatible = "qcom,ufs-phy-qmp-v3";
@@ -106,7 +108,8 @@
pinctrl-names = "default";
pinctrl-0 = <&key_cam_snapshot_default
- &key_cam_focus_default>;
+ &key_cam_focus_default
+ &key_vol_up_default>;
cam_snapshot {
label = "cam_snapshot";
@@ -127,5 +130,106 @@
debounce-interval = <15>;
linux,can-disable;
};
+
+ vol_up {
+ label = "volume_up";
+ gpios = <&pm660l_gpios 7 GPIO_ACTIVE_LOW>;
+ linux,input-type = <1>;
+ linux,code = <115>;
+ gpio-key,wakeup;
+ debounce-interval = <15>;
+ linux,can-disable;
+ };
};
};
+
+&dsi_dual_nt35597_truly_video {
+ qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;
+ qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled";
+ qcom,mdss-dsi-bl-min-level = <1>;
+ qcom,mdss-dsi-bl-max-level = <4095>;
+ qcom,mdss-dsi-mode-sel-gpio-state = "dual_port";
+ qcom,panel-mode-gpio = <&tlmm 76 0>;
+ qcom,platform-reset-gpio = <&tlmm 75 0>;
+};
+
+&dsi_dual_nt35597_truly_cmd {
+ qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;
+ qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled";
+ qcom,mdss-dsi-bl-min-level = <1>;
+ qcom,mdss-dsi-bl-max-level = <4095>;
+ qcom,mdss-dsi-mode-sel-gpio-state = "dual_port";
+ qcom,panel-mode-gpio = <&tlmm 76 0>;
+ qcom,platform-reset-gpio = <&tlmm 75 0>;
+ qcom,platform-te-gpio = <&tlmm 10 0>;
+};
+
+&dsi_nt35597_truly_dsc_video {
+ qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;
+ qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled";
+ qcom,mdss-dsi-bl-min-level = <1>;
+ qcom,mdss-dsi-bl-max-level = <4095>;
+ qcom,mdss-dsi-mode-sel-gpio-state = "single_port";
+ qcom,panel-mode-gpio = <&tlmm 76 0>;
+ qcom,platform-reset-gpio = <&tlmm 75 0>;
+};
+
+&dsi_nt35597_truly_dsc_cmd {
+ qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;
+ qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled";
+ qcom,mdss-dsi-bl-min-level = <1>;
+ qcom,mdss-dsi-bl-max-level = <4095>;
+ qcom,mdss-dsi-mode-sel-gpio-state = "single_port";
+ qcom,panel-mode-gpio = <&tlmm 76 0>;
+ qcom,platform-reset-gpio = <&tlmm 75 0>;
+ qcom,platform-te-gpio = <&tlmm 10 0>;
+};
+
+&dsi_sim_vid {
+ qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;
+ qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled";
+ qcom,platform-reset-gpio = <&tlmm 75 0>;
+};
+
+&dsi_dual_sim_vid {
+ qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;
+ qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled";
+ qcom,platform-reset-gpio = <&tlmm 75 0>;
+};
+
+&dsi_sim_cmd {
+ qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;
+ qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled";
+ qcom,platform-reset-gpio = <&tlmm 75 0>;
+};
+
+&dsi_dual_sim_cmd {
+ qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;
+ qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled";
+ qcom,platform-reset-gpio = <&tlmm 75 0>;
+};
+
+&dsi_sim_dsc_375_cmd {
+ qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;
+ qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled";
+ qcom,platform-reset-gpio = <&tlmm 75 0>;
+};
+
+&dsi_dual_sim_dsc_375_cmd {
+ qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;
+ qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled";
+ qcom,platform-reset-gpio = <&tlmm 75 0>;
+};
+
+&dsi_dual_nt35597_truly_video {
+ qcom,dsi-display-active;
+};
+
+&pm660l_wled {
+ status = "okay";
+ qcom,led-strings-list = [01 02];
+};
+
+&mdss_mdp {
+ #cooling-cells = <2>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm670-ext-codec-audio-overlay.dtsi b/arch/arm64/boot/dts/qcom/sdm670-ext-codec-audio-overlay.dtsi
new file mode 100644
index 0000000..775cf48
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm670-ext-codec-audio-overlay.dtsi
@@ -0,0 +1,96 @@
+/* Copyright (c) 2017, 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 "sdm670-audio-overlay.dtsi"
+
+&pmic_analog_codec {
+ status = "disabled";
+};
+
+&msm_sdw_codec {
+ status = "disabled";
+};
+
+&cdc_pdm_gpios {
+ status = "disabled";
+};
+
+&cdc_comp_gpios {
+ status = "disabled";
+};
+
+&cdc_dmic_gpios {
+ status = "disabled";
+};
+
+&cdc_sdw_gpios {
+ status = "disabled";
+};
+
+&wsa_spkr_en1 {
+ status = "disabled";
+};
+
+&wsa_spkr_en2 {
+ status = "disabled";
+};
+
+&qupv3_se8_spi {
+ status = "okay";
+};
+
+&soc {
+ wcd_buck_vreg_gpio: msm_cdc_pinctrl@94 {
+ status = "okay";
+ compatible = "qcom,msm-cdc-pinctrl";
+ pinctrl-names = "aud_active", "aud_sleep";
+ pinctrl-0 = <&wcd_buck_vsel_default>;
+ pinctrl-1 = <&wcd_buck_vsel_default>;
+ };
+};
+
+&wcd9xxx_intc {
+ status = "okay";
+};
+
+&wdsp_mgr {
+ status = "okay";
+};
+
+&wdsp_glink {
+ status = "okay";
+};
+
+&slim_aud {
+ status = "okay";
+};
+
+&dai_slim {
+ status = "okay";
+};
+
+&wcd934x_cdc {
+ status = "okay";
+ qcom,has-buck-vsel-gpio;
+ qcom,buck-vsel-gpio-node = <&wcd_buck_vreg_gpio>;
+};
+
+&clock_audio_lnbb {
+ status = "okay";
+};
+
+&wcd_rst_gpio {
+ status = "okay";
+};
+
+&wcd9xxx_intc {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm670-external-codec.dtsi b/arch/arm64/boot/dts/qcom/sdm670-external-codec.dtsi
index 6ea92ee..dbcc6bd 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-external-codec.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-external-codec.dtsi
@@ -9,3 +9,21 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
+
+#include "sdm670-ext-codec-audio-overlay.dtsi"
+
+&int_codec {
+ status = "disabled";
+};
+
+&tavil_snd {
+ status = "okay";
+};
+
+&slim_aud {
+ status = "okay";
+};
+
+&dai_slim {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm670-int-codec-audio-overlay.dtsi b/arch/arm64/boot/dts/qcom/sdm670-int-codec-audio-overlay.dtsi
new file mode 100644
index 0000000..bc431f2
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm670-int-codec-audio-overlay.dtsi
@@ -0,0 +1,12 @@
+/* Copyright (c) 2017, 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 "sdm670-audio-overlay.dtsi"
diff --git a/arch/arm64/boot/dts/qcom/sdm670-mtp.dts b/arch/arm64/boot/dts/qcom/sdm670-mtp.dts
index 38a9fae..f12be2ae 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-mtp.dts
+++ b/arch/arm64/boot/dts/qcom/sdm670-mtp.dts
@@ -15,6 +15,7 @@
#include "sdm670.dtsi"
#include "sdm670-mtp.dtsi"
+#include "sdm670-int-codec-audio-overlay.dtsi"
/ {
model = "Qualcomm Technologies, Inc. SDM670 PM660 + PM660L MTP";
diff --git a/arch/arm64/boot/dts/qcom/sdm670-mtp.dtsi b/arch/arm64/boot/dts/qcom/sdm670-mtp.dtsi
index 320a1f2..fa76a2e 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-mtp.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-mtp.dtsi
@@ -10,7 +10,9 @@
* GNU General Public License for more details.
*/
+#include <dt-bindings/gpio/gpio.h>
#include "sdm670-pmic-overlay.dtsi"
+#include "sdm670-sde-display.dtsi"
&ufsphy_mem {
compatible = "qcom,ufs-phy-qmp-v3";
@@ -115,7 +117,8 @@
pinctrl-names = "default";
pinctrl-0 = <&key_cam_snapshot_default
- &key_cam_focus_default>;
+ &key_cam_focus_default
+ &key_vol_up_default>;
cam_snapshot {
label = "cam_snapshot";
@@ -136,5 +139,106 @@
debounce-interval = <15>;
linux,can-disable;
};
+
+ vol_up {
+ label = "volume_up";
+ gpios = <&pm660l_gpios 7 GPIO_ACTIVE_LOW>;
+ linux,input-type = <1>;
+ linux,code = <115>;
+ gpio-key,wakeup;
+ debounce-interval = <15>;
+ linux,can-disable;
+ };
};
};
+
+&dsi_dual_nt35597_truly_video {
+ qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;
+ qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled";
+ qcom,mdss-dsi-bl-min-level = <1>;
+ qcom,mdss-dsi-bl-max-level = <4095>;
+ qcom,mdss-dsi-mode-sel-gpio-state = "dual_port";
+ qcom,panel-mode-gpio = <&tlmm 76 0>;
+ qcom,platform-reset-gpio = <&tlmm 75 0>;
+};
+
+&dsi_dual_nt35597_truly_cmd {
+ qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;
+ qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled";
+ qcom,mdss-dsi-bl-min-level = <1>;
+ qcom,mdss-dsi-bl-max-level = <4095>;
+ qcom,mdss-dsi-mode-sel-gpio-state = "dual_port";
+ qcom,panel-mode-gpio = <&tlmm 76 0>;
+ qcom,platform-reset-gpio = <&tlmm 75 0>;
+ qcom,platform-te-gpio = <&tlmm 10 0>;
+};
+
+&dsi_nt35597_truly_dsc_video {
+ qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;
+ qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled";
+ qcom,mdss-dsi-bl-min-level = <1>;
+ qcom,mdss-dsi-bl-max-level = <4095>;
+ qcom,mdss-dsi-mode-sel-gpio-state = "single_port";
+ qcom,panel-mode-gpio = <&tlmm 76 0>;
+ qcom,platform-reset-gpio = <&tlmm 75 0>;
+};
+
+&dsi_nt35597_truly_dsc_cmd {
+ qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;
+ qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled";
+ qcom,mdss-dsi-bl-min-level = <1>;
+ qcom,mdss-dsi-bl-max-level = <4095>;
+ qcom,mdss-dsi-mode-sel-gpio-state = "single_port";
+ qcom,panel-mode-gpio = <&tlmm 76 0>;
+ qcom,platform-reset-gpio = <&tlmm 75 0>;
+ qcom,platform-te-gpio = <&tlmm 10 0>;
+};
+
+&dsi_sim_vid {
+ qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;
+ qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled";
+ qcom,platform-reset-gpio = <&tlmm 75 0>;
+};
+
+&dsi_dual_sim_vid {
+ qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;
+ qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled";
+ qcom,platform-reset-gpio = <&tlmm 75 0>;
+};
+
+&dsi_sim_cmd {
+ qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;
+ qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled";
+ qcom,platform-reset-gpio = <&tlmm 75 0>;
+};
+
+&dsi_dual_sim_cmd {
+ qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;
+ qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled";
+ qcom,platform-reset-gpio = <&tlmm 75 0>;
+};
+
+&dsi_sim_dsc_375_cmd {
+ qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;
+ qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled";
+ qcom,platform-reset-gpio = <&tlmm 75 0>;
+};
+
+&dsi_dual_sim_dsc_375_cmd {
+ qcom,panel-supply-entries = <&dsi_panel_pwr_supply>;
+ qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled";
+ qcom,platform-reset-gpio = <&tlmm 75 0>;
+};
+
+&dsi_dual_nt35597_truly_video {
+ qcom,dsi-display-active;
+};
+
+&pm660l_wled {
+ status = "okay";
+ qcom,led-strings-list = [01 02];
+};
+
+&mdss_mdp {
+ #cooling-cells = <2>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm670-pinctrl.dtsi b/arch/arm64/boot/dts/qcom/sdm670-pinctrl.dtsi
index 2a2b6d8..e747185 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-pinctrl.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-pinctrl.dtsi
@@ -1406,6 +1406,22 @@
};
};
+ wcd_buck_vsel {
+ wcd_buck_vsel_default: wcd_buck_vsel_default{
+ mux {
+ pins = "gpio94";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio94";
+ drive-strength = <8>; /* 8 mA */
+ bias-pull-down; /* pull down */
+ output-high;
+ };
+ };
+ };
+
wcd_gnd_mic_swap {
wcd_gnd_mic_swap_idle: wcd_gnd_mic_swap_idle {
mux {
@@ -1473,5 +1489,123 @@
};
};
+ pmx_sde: pmx_sde {
+ sde_dsi_active: sde_dsi_active {
+ mux {
+ pins = "gpio75", "gpio76";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio75", "gpio76";
+ drive-strength = <8>; /* 8 mA */
+ bias-disable = <0>; /* no pull */
+ };
+ };
+ sde_dsi_suspend: sde_dsi_suspend {
+ mux {
+ pins = "gpio75", "gpio76";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio75", "gpio76";
+ drive-strength = <2>; /* 2 mA */
+ bias-pull-down; /* PULL DOWN */
+ };
+ };
+ };
+
+ pmx_sde_te {
+ sde_te_active: sde_te_active {
+ mux {
+ pins = "gpio10";
+ function = "mdp_vsync";
+ };
+
+ config {
+ pins = "gpio10";
+ drive-strength = <2>; /* 2 mA */
+ bias-pull-down; /* PULL DOWN */
+ };
+ };
+
+ sde_te_suspend: sde_te_suspend {
+ mux {
+ pins = "gpio10";
+ function = "mdp_vsync";
+ };
+
+ config {
+ pins = "gpio10";
+ drive-strength = <2>; /* 2 mA */
+ bias-pull-down; /* PULL DOWN */
+ };
+ };
+ };
+
+ sde_dp_aux_active: sde_dp_aux_active {
+ mux {
+ pins = "gpio40", "gpio50";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio40", "gpio50";
+ bias-disable = <0>; /* no pull */
+ drive-strength = <8>;
+ };
+ };
+
+ sde_dp_aux_suspend: sde_dp_aux_suspend {
+ mux {
+ pins = "gpio40", "gpio50";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio40", "gpio50";
+ bias-pull-down;
+ drive-strength = <2>;
+ };
+ };
+
+ sde_dp_usbplug_cc_active: sde_dp_usbplug_cc_active {
+ mux {
+ pins = "gpio38";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio38";
+ bias-disable;
+ drive-strength = <16>;
+ };
+ };
+
+ sde_dp_usbplug_cc_suspend: sde_dp_usbplug_cc_suspend {
+ mux {
+ pins = "gpio38";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio38";
+ bias-pull-down;
+ drive-strength = <2>;
+ };
+ };
+ };
+};
+
+&pm660l_gpios {
+ key_vol_up {
+ key_vol_up_default: key_vol_up_default {
+ pins = "gpio7";
+ function = "normal";
+ input-enable;
+ bias-pull-up;
+ power-source = <0>;
+ };
};
};
diff --git a/arch/arm64/boot/dts/qcom/sdm670-pm660a-cdp.dts b/arch/arm64/boot/dts/qcom/sdm670-pm660a-cdp.dts
index 5cf3513..95642f9 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-pm660a-cdp.dts
+++ b/arch/arm64/boot/dts/qcom/sdm670-pm660a-cdp.dts
@@ -16,6 +16,7 @@
#include "sdm670.dtsi"
#include "sdm670-cdp.dtsi"
#include "pm660a.dtsi"
+#include "sdm670-int-codec-audio-overlay.dtsi"
/ {
model = "Qualcomm Technologies, Inc. SDM670 PM660 + PM660A CDP";
diff --git a/arch/arm64/boot/dts/qcom/sdm670-pm660a-mtp.dts b/arch/arm64/boot/dts/qcom/sdm670-pm660a-mtp.dts
index febd5d9..5592ce4 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-pm660a-mtp.dts
+++ b/arch/arm64/boot/dts/qcom/sdm670-pm660a-mtp.dts
@@ -16,6 +16,7 @@
#include "sdm670.dtsi"
#include "sdm670-mtp.dtsi"
#include "pm660a.dtsi"
+#include "sdm670-int-codec-audio-overlay.dtsi"
/ {
model = "Qualcomm Technologies, Inc. SDM670 PM660 + PM660A MTP";
diff --git a/arch/arm64/boot/dts/qcom/sdm670-pmic-overlay.dtsi b/arch/arm64/boot/dts/qcom/sdm670-pmic-overlay.dtsi
index 75922b0..aa6be24 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-pmic-overlay.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-pmic-overlay.dtsi
@@ -156,6 +156,15 @@
};
};
+ pm660_rradc: rradc@4500 {
+ compatible = "qcom,rradc";
+ reg = <0x4500 0x100>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #io-channel-cells = <1>;
+ qcom,pmic-revid = <&pm660_revid>;
+ };
+
pm660_fg: qpnp,fg {
compatible = "qcom,fg-gen3";
#address-cells = <1>;
diff --git a/arch/arm64/boot/dts/qcom/sdm670-regulator.dtsi b/arch/arm64/boot/dts/qcom/sdm670-regulator.dtsi
index 23792b1..24b8dd6 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-regulator.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-regulator.dtsi
@@ -642,4 +642,14 @@
qcom,init-voltage = <3312000>;
};
};
+
+ refgen: refgen-regulator@ff1000 {
+ compatible = "qcom,refgen-regulator";
+ reg = <0xff1000 0x60>;
+ regulator-name = "refgen";
+ regulator-enable-ramp-delay = <5>;
+ proxy-supply = <&refgen>;
+ qcom,proxy-consumer-enable;
+ regulator-always-on;
+ };
};
diff --git a/arch/arm64/boot/dts/qcom/sdm670-rumi.dts b/arch/arm64/boot/dts/qcom/sdm670-rumi.dts
index 6201488..e2a2df7 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-rumi.dts
+++ b/arch/arm64/boot/dts/qcom/sdm670-rumi.dts
@@ -16,6 +16,7 @@
#include "sdm670.dtsi"
#include "sdm670-rumi.dtsi"
+#include "sdm670-int-codec-audio-overlay.dtsi"
/ {
model = "Qualcomm Technologies, Inc. SDM670 RUMI";
compatible = "qcom,sdm670-rumi", "qcom,sdm670", "qcom,rumi";
diff --git a/arch/arm64/boot/dts/qcom/sdm670-sde-display.dtsi b/arch/arm64/boot/dts/qcom/sdm670-sde-display.dtsi
new file mode 100644
index 0000000..3e9d967
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm670-sde-display.dtsi
@@ -0,0 +1,597 @@
+/* Copyright (c) 2017, 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 "dsi-panel-sim-video.dtsi"
+#include "dsi-panel-sim-cmd.dtsi"
+#include "dsi-panel-sim-dsc375-cmd.dtsi"
+#include "dsi-panel-sim-dualmipi-video.dtsi"
+#include "dsi-panel-sim-dualmipi-cmd.dtsi"
+#include "dsi-panel-sim-dualmipi-dsc375-cmd.dtsi"
+#include "dsi-panel-nt35597-truly-dualmipi-wqxga-video.dtsi"
+#include "dsi-panel-nt35597-truly-dualmipi-wqxga-cmd.dtsi"
+#include "dsi-panel-nt35597-truly-dsc-wqxga-cmd.dtsi"
+#include "dsi-panel-nt35597-truly-dsc-wqxga-video.dtsi"
+#include <dt-bindings/clock/mdss-10nm-pll-clk.h>
+
+&soc {
+ dsi_panel_pwr_supply: dsi_panel_pwr_supply {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ qcom,panel-supply-entry@0 {
+ reg = <0>;
+ qcom,supply-name = "vddio";
+ qcom,supply-min-voltage = <1800000>;
+ qcom,supply-max-voltage = <1800000>;
+ qcom,supply-enable-load = <62000>;
+ qcom,supply-disable-load = <80>;
+ qcom,supply-post-on-sleep = <20>;
+ };
+
+ qcom,panel-supply-entry@1 {
+ reg = <1>;
+ qcom,supply-name = "lab";
+ qcom,supply-min-voltage = <4600000>;
+ qcom,supply-max-voltage = <6000000>;
+ qcom,supply-enable-load = <100000>;
+ qcom,supply-disable-load = <100>;
+ };
+
+ qcom,panel-supply-entry@2 {
+ reg = <2>;
+ qcom,supply-name = "ibb";
+ qcom,supply-min-voltage = <4600000>;
+ qcom,supply-max-voltage = <6000000>;
+ qcom,supply-enable-load = <100000>;
+ qcom,supply-disable-load = <100>;
+ qcom,supply-post-on-sleep = <20>;
+ };
+ };
+
+ dsi_panel_pwr_supply_no_labibb: dsi_panel_pwr_supply_no_labibb {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ qcom,panel-supply-entry@0 {
+ reg = <0>;
+ qcom,supply-name = "vddio";
+ qcom,supply-min-voltage = <1800000>;
+ qcom,supply-max-voltage = <1800000>;
+ qcom,supply-enable-load = <62000>;
+ qcom,supply-disable-load = <80>;
+ qcom,supply-post-on-sleep = <20>;
+ };
+ };
+
+ dsi_panel_pwr_supply_vdd_no_labibb: dsi_panel_pwr_supply_vdd_no_labibb {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ qcom,panel-supply-entry@0 {
+ reg = <0>;
+ qcom,supply-name = "vddio";
+ qcom,supply-min-voltage = <1800000>;
+ qcom,supply-max-voltage = <1800000>;
+ qcom,supply-enable-load = <62000>;
+ qcom,supply-disable-load = <80>;
+ qcom,supply-post-on-sleep = <20>;
+ };
+
+ qcom,panel-supply-entry@1 {
+ reg = <1>;
+ qcom,supply-name = "vdd";
+ qcom,supply-min-voltage = <3000000>;
+ qcom,supply-max-voltage = <3000000>;
+ qcom,supply-enable-load = <857000>;
+ qcom,supply-disable-load = <0>;
+ qcom,supply-post-on-sleep = <0>;
+ };
+ };
+
+ dsi_dual_nt35597_truly_video_display: qcom,dsi-display@0 {
+ compatible = "qcom,dsi-display";
+ label = "dsi_dual_nt35597_truly_video_display";
+ qcom,display-type = "primary";
+
+ qcom,dsi-ctrl = <&mdss_dsi0 &mdss_dsi1>;
+ qcom,dsi-phy = <&mdss_dsi_phy0 &mdss_dsi_phy1>;
+ clocks = <&mdss_dsi0_pll BYTECLK_MUX_0_CLK>,
+ <&mdss_dsi0_pll PCLK_MUX_0_CLK>;
+ clock-names = "src_byte_clk", "src_pixel_clk";
+
+ pinctrl-names = "panel_active", "panel_suspend";
+ pinctrl-0 = <&sde_dsi_active &sde_te_active>;
+ pinctrl-1 = <&sde_dsi_suspend &sde_te_suspend>;
+ qcom,platform-reset-gpio = <&tlmm 75 0>;
+ qcom,panel-mode-gpio = <&tlmm 76 0>;
+
+ qcom,dsi-panel = <&dsi_dual_nt35597_truly_video>;
+ vddio-supply = <&pm660_l11>;
+ lab-supply = <&lcdb_ldo_vreg>;
+ ibb-supply = <&lcdb_ncp_vreg>;
+ };
+
+ dsi_dual_nt35597_truly_cmd_display: qcom,dsi-display@1 {
+ compatible = "qcom,dsi-display";
+ label = "dsi_dual_nt35597_truly_cmd_display";
+ qcom,display-type = "primary";
+
+ qcom,dsi-ctrl = <&mdss_dsi0 &mdss_dsi1>;
+ qcom,dsi-phy = <&mdss_dsi_phy0 &mdss_dsi_phy1>;
+ clocks = <&mdss_dsi0_pll BYTECLK_MUX_0_CLK>,
+ <&mdss_dsi0_pll PCLK_MUX_0_CLK>;
+ clock-names = "src_byte_clk", "src_pixel_clk";
+
+ pinctrl-names = "panel_active", "panel_suspend";
+ pinctrl-0 = <&sde_dsi_active &sde_te_active>;
+ pinctrl-1 = <&sde_dsi_suspend &sde_te_suspend>;
+ qcom,platform-te-gpio = <&tlmm 10 0>;
+ qcom,platform-reset-gpio = <&tlmm 75 0>;
+ qcom,panel-mode-gpio = <&tlmm 76 0>;
+
+ qcom,dsi-panel = <&dsi_dual_nt35597_truly_cmd>;
+ vddio-supply = <&pm660_l11>;
+ lab-supply = <&lcdb_ldo_vreg>;
+ ibb-supply = <&lcdb_ncp_vreg>;
+ };
+
+ dsi_nt35597_truly_dsc_cmd_display: qcom,dsi-display@2 {
+ compatible = "qcom,dsi-display";
+ label = "dsi_nt35597_truly_dsc_cmd_display";
+ qcom,display-type = "primary";
+
+ qcom,dsi-ctrl = <&mdss_dsi1>;
+ qcom,dsi-phy = <&mdss_dsi_phy1>;
+ clocks = <&mdss_dsi1_pll BYTECLK_MUX_1_CLK>,
+ <&mdss_dsi1_pll PCLK_MUX_1_CLK>;
+ clock-names = "src_byte_clk", "src_pixel_clk";
+
+ pinctrl-names = "panel_active", "panel_suspend";
+ pinctrl-0 = <&sde_dsi_active &sde_te_active>;
+ pinctrl-1 = <&sde_dsi_suspend &sde_te_suspend>;
+ qcom,platform-te-gpio = <&tlmm 10 0>;
+ qcom,platform-reset-gpio = <&tlmm 75 0>;
+ qcom,panel-mode-gpio = <&tlmm 76 0>;
+
+ qcom,dsi-panel = <&dsi_nt35597_truly_dsc_cmd>;
+ vddio-supply = <&pm660_l11>;
+ lab-supply = <&lcdb_ldo_vreg>;
+ ibb-supply = <&lcdb_ncp_vreg>;
+ };
+
+ dsi_nt35597_truly_dsc_video_display: qcom,dsi-display@3 {
+ compatible = "qcom,dsi-display";
+ label = "dsi_nt35597_truly_dsc_video_display";
+ qcom,display-type = "primary";
+
+ qcom,dsi-ctrl = <&mdss_dsi1>;
+ qcom,dsi-phy = <&mdss_dsi_phy1>;
+ clocks = <&mdss_dsi1_pll BYTECLK_MUX_1_CLK>,
+ <&mdss_dsi1_pll PCLK_MUX_1_CLK>;
+ clock-names = "src_byte_clk", "src_pixel_clk";
+
+ pinctrl-names = "panel_active", "panel_suspend";
+ pinctrl-0 = <&sde_dsi_active &sde_te_active>;
+ pinctrl-1 = <&sde_dsi_suspend &sde_te_suspend>;
+ qcom,platform-te-gpio = <&tlmm 10 0>;
+ qcom,platform-reset-gpio = <&tlmm 75 0>;
+ qcom,panel-mode-gpio = <&tlmm 76 0>;
+
+ qcom,dsi-panel = <&dsi_nt35597_truly_dsc_video>;
+ vddio-supply = <&pm660_l11>;
+ lab-supply = <&lcdb_ldo_vreg>;
+ ibb-supply = <&lcdb_ncp_vreg>;
+ };
+
+ dsi_sim_vid_display: qcom,dsi-display@4 {
+ compatible = "qcom,dsi-display";
+ label = "dsi_sim_vid_display";
+ qcom,display-type = "primary";
+
+ qcom,dsi-ctrl = <&mdss_dsi0>;
+ qcom,dsi-phy = <&mdss_dsi_phy0>;
+ clocks = <&mdss_dsi0_pll BYTECLK_MUX_0_CLK>,
+ <&mdss_dsi0_pll PCLK_MUX_0_CLK>;
+ clock-names = "src_byte_clk", "src_pixel_clk";
+
+ pinctrl-names = "panel_active", "panel_suspend";
+ pinctrl-0 = <&sde_dsi_active &sde_te_active>;
+ pinctrl-1 = <&sde_dsi_suspend &sde_te_suspend>;
+
+ qcom,dsi-panel = <&dsi_sim_vid>;
+ };
+
+ dsi_dual_sim_vid_display: qcom,dsi-display@5 {
+ compatible = "qcom,dsi-display";
+ label = "dsi_dual_sim_vid_display";
+ qcom,display-type = "primary";
+
+ qcom,dsi-ctrl = <&mdss_dsi0 &mdss_dsi1>;
+ qcom,dsi-phy = <&mdss_dsi_phy0 &mdss_dsi_phy1>;
+ clocks = <&mdss_dsi0_pll BYTECLK_MUX_0_CLK>,
+ <&mdss_dsi0_pll PCLK_MUX_0_CLK>;
+ clock-names = "src_byte_clk", "src_pixel_clk";
+
+ pinctrl-names = "panel_active", "panel_suspend";
+ pinctrl-0 = <&sde_dsi_active &sde_te_active>;
+ pinctrl-1 = <&sde_dsi_suspend &sde_te_suspend>;
+
+ qcom,dsi-panel = <&dsi_dual_sim_vid>;
+ };
+
+ dsi_sim_cmd_display: qcom,dsi-display@6 {
+ compatible = "qcom,dsi-display";
+ label = "dsi_sim_cmd_display";
+ qcom,display-type = "primary";
+
+ qcom,dsi-ctrl = <&mdss_dsi0>;
+ qcom,dsi-phy = <&mdss_dsi_phy0>;
+ clocks = <&mdss_dsi0_pll BYTECLK_MUX_0_CLK>,
+ <&mdss_dsi0_pll PCLK_MUX_0_CLK>;
+ clock-names = "src_byte_clk", "src_pixel_clk";
+
+ pinctrl-names = "panel_active", "panel_suspend";
+ pinctrl-0 = <&sde_dsi_active &sde_te_active>;
+ pinctrl-1 = <&sde_dsi_suspend &sde_te_suspend>;
+
+ qcom,dsi-panel = <&dsi_sim_cmd>;
+ };
+
+ dsi_dual_sim_cmd_display: qcom,dsi-display@7 {
+ compatible = "qcom,dsi-display";
+ label = "dsi_dual_sim_cmd_display";
+ qcom,display-type = "primary";
+
+ qcom,dsi-ctrl = <&mdss_dsi0 &mdss_dsi1>;
+ qcom,dsi-phy = <&mdss_dsi_phy0 &mdss_dsi_phy1>;
+ clocks = <&mdss_dsi0_pll BYTECLK_MUX_0_CLK>,
+ <&mdss_dsi0_pll PCLK_MUX_0_CLK>;
+ clock-names = "src_byte_clk", "src_pixel_clk";
+
+ pinctrl-names = "panel_active", "panel_suspend";
+ pinctrl-0 = <&sde_dsi_active &sde_te_active>;
+ pinctrl-1 = <&sde_dsi_suspend &sde_te_suspend>;
+
+ qcom,dsi-panel = <&dsi_dual_sim_cmd>;
+ };
+
+ dsi_sim_dsc_375_cmd_display: qcom,dsi-display@8 {
+ compatible = "qcom,dsi-display";
+ label = "dsi_sim_dsc_375_cmd_display";
+ qcom,display-type = "primary";
+
+ qcom,dsi-ctrl = <&mdss_dsi0>;
+ qcom,dsi-phy = <&mdss_dsi_phy0>;
+ clocks = <&mdss_dsi0_pll BYTECLK_MUX_0_CLK>,
+ <&mdss_dsi0_pll PCLK_MUX_0_CLK>;
+ clock-names = "src_byte_clk", "src_pixel_clk";
+
+ pinctrl-names = "panel_active", "panel_suspend";
+ pinctrl-0 = <&sde_dsi_active &sde_te_active>;
+ pinctrl-1 = <&sde_dsi_suspend &sde_te_suspend>;
+
+ qcom,dsi-panel = <&dsi_sim_dsc_375_cmd>;
+ };
+
+ dsi_dual_sim_dsc_375_cmd_display: qcom,dsi-display@9 {
+ compatible = "qcom,dsi-display";
+ label = "dsi_dual_sim_dsc_375_cmd_display";
+ qcom,display-type = "primary";
+
+ qcom,dsi-ctrl = <&mdss_dsi0 &mdss_dsi1>;
+ qcom,dsi-phy = <&mdss_dsi_phy0 &mdss_dsi_phy1>;
+ clocks = <&mdss_dsi0_pll BYTECLK_MUX_0_CLK>,
+ <&mdss_dsi0_pll PCLK_MUX_0_CLK>;
+ clock-names = "src_byte_clk", "src_pixel_clk";
+
+ pinctrl-names = "panel_active", "panel_suspend";
+ pinctrl-0 = <&sde_dsi_active &sde_te_active>;
+ pinctrl-1 = <&sde_dsi_suspend &sde_te_suspend>;
+
+ qcom,dsi-panel = <&dsi_dual_sim_dsc_375_cmd>;
+ };
+
+ sde_wb: qcom,wb-display@0 {
+ compatible = "qcom,wb-display";
+ cell-index = <0>;
+ label = "wb_display";
+ };
+
+ ext_disp: qcom,msm-ext-disp {
+ compatible = "qcom,msm-ext-disp";
+ status = "disabled";
+
+ ext_disp_audio_codec: qcom,msm-ext-disp-audio-codec-rx {
+ compatible = "qcom,msm-ext-disp-audio-codec-rx";
+ };
+ };
+
+ sde_dp: qcom,dp_display@0{
+ cell-index = <0>;
+ compatible = "qcom,dp-display";
+ status = "disabled";
+
+ gdsc-supply = <&mdss_core_gdsc>;
+ vdda-1p2-supply = <&pm660_l1>;
+ vdda-0p9-supply = <&pm660l_l1>;
+
+ reg = <0xae90000 0xa84>,
+ <0x88eaa00 0x200>,
+ <0x88ea200 0x200>,
+ <0x88ea600 0x200>,
+ <0xaf02000 0x1a0>,
+ <0x780000 0x621c>,
+ <0x88ea030 0x10>,
+ <0x0aee1000 0x034>;
+ reg-names = "dp_ctrl", "dp_phy", "dp_ln_tx0", "dp_ln_tx1",
+ "dp_mmss_cc", "qfprom_physical", "dp_pll",
+ "hdcp_physical";
+
+ interrupt-parent = <&mdss_mdp>;
+ interrupts = <12 0>;
+
+ clocks = <&clock_dispcc DISP_CC_MDSS_DP_AUX_CLK>,
+ <&clock_rpmh RPMH_CXO_CLK>,
+ <&clock_gcc GCC_USB3_PRIM_CLKREF_CLK>,
+ <&clock_gcc GCC_USB_PHY_CFG_AHB2PHY_CLK>,
+ <&clock_gcc GCC_USB3_PRIM_PHY_PIPE_CLK>,
+ <&clock_dispcc DISP_CC_MDSS_DP_LINK_CLK>,
+ <&clock_dispcc DISP_CC_MDSS_DP_LINK_INTF_CLK>,
+ <&clock_dispcc DISP_CC_MDSS_DP_PIXEL_CLK>,
+ <&clock_dispcc DISP_CC_MDSS_DP_CRYPTO_CLK>,
+ <&clock_dispcc DISP_CC_MDSS_DP_PIXEL_CLK_SRC>,
+ <&mdss_dp_pll DP_VCO_DIVIDED_CLK_SRC_MUX>;
+ clock-names = "core_aux_clk", "core_usb_ref_clk_src",
+ "core_usb_ref_clk", "core_usb_cfg_ahb_clk",
+ "core_usb_pipe_clk", "ctrl_link_clk",
+ "ctrl_link_iface_clk", "ctrl_pixel_clk",
+ "crypto_clk", "pixel_clk_rcg", "pixel_parent";
+
+ qcom,dp-usbpd-detection = <&pm660_pdphy>;
+ qcom,ext-disp = <&ext_disp>;
+
+ qcom,aux-cfg0-settings = [20 00];
+ qcom,aux-cfg1-settings = [24 13 23 1d];
+ qcom,aux-cfg2-settings = [28 24];
+ qcom,aux-cfg3-settings = [2c 00];
+ qcom,aux-cfg4-settings = [30 0a];
+ qcom,aux-cfg5-settings = [34 26];
+ qcom,aux-cfg6-settings = [38 0a];
+ qcom,aux-cfg7-settings = [3c 03];
+ qcom,aux-cfg8-settings = [40 bb];
+ qcom,aux-cfg9-settings = [44 03];
+
+ qcom,max-pclk-frequency-khz = <675000>;
+
+ qcom,core-supply-entries {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ qcom,core-supply-entry@0 {
+ reg = <0>;
+ qcom,supply-name = "gdsc";
+ qcom,supply-min-voltage = <0>;
+ qcom,supply-max-voltage = <0>;
+ qcom,supply-enable-load = <0>;
+ qcom,supply-disable-load = <0>;
+ };
+ };
+
+ qcom,ctrl-supply-entries {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ qcom,ctrl-supply-entry@0 {
+ reg = <0>;
+ qcom,supply-name = "vdda-1p2";
+ qcom,supply-min-voltage = <1200000>;
+ qcom,supply-max-voltage = <1200000>;
+ qcom,supply-enable-load = <21800>;
+ qcom,supply-disable-load = <4>;
+ };
+ };
+
+ qcom,phy-supply-entries {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ qcom,phy-supply-entry@0 {
+ reg = <0>;
+ qcom,supply-name = "vdda-0p9";
+ qcom,supply-min-voltage = <880000>;
+ qcom,supply-max-voltage = <880000>;
+ qcom,supply-enable-load = <36000>;
+ qcom,supply-disable-load = <32>;
+ };
+ };
+ };
+};
+
+&sde_dp {
+ status = "disabled";
+ pinctrl-names = "mdss_dp_active", "mdss_dp_sleep";
+ pinctrl-0 = <&sde_dp_aux_active &sde_dp_usbplug_cc_active>;
+ pinctrl-1 = <&sde_dp_aux_suspend &sde_dp_usbplug_cc_suspend>;
+ qcom,aux-en-gpio = <&tlmm 50 0>;
+ qcom,aux-sel-gpio = <&tlmm 40 0>;
+ qcom,usbplug-cc-gpio = <&tlmm 38 0>;
+};
+
+&mdss_mdp {
+ connectors = <&sde_rscc &sde_wb>;
+};
+
+&dsi_dual_nt35597_truly_video {
+ qcom,mdss-dsi-t-clk-post = <0x0D>;
+ qcom,mdss-dsi-t-clk-pre = <0x2D>;
+ qcom,mdss-dsi-display-timings {
+ timing@0{
+ qcom,mdss-dsi-panel-phy-timings = [00 1c 07 07 23 21 07
+ 07 05 03 04 00];
+ qcom,display-topology = <2 0 2>,
+ <1 0 2>;
+ qcom,default-topology-index = <0>;
+ };
+ };
+};
+
+&dsi_dual_nt35597_truly_cmd {
+ qcom,mdss-dsi-t-clk-post = <0x0D>;
+ qcom,mdss-dsi-t-clk-pre = <0x2D>;
+ qcom,mdss-dsi-display-timings {
+ timing@0{
+ qcom,mdss-dsi-panel-phy-timings = [00 1c 07 07 23 21 07
+ 07 05 03 04 00];
+ qcom,display-topology = <2 0 2>,
+ <1 0 2>;
+ qcom,default-topology-index = <0>;
+ };
+ };
+};
+
+&dsi_nt35597_truly_dsc_cmd {
+ qcom,mdss-dsi-t-clk-post = <0x0b>;
+ qcom,mdss-dsi-t-clk-pre = <0x23>;
+ qcom,mdss-dsi-display-timings {
+ timing@0{
+ qcom,mdss-dsi-panel-phy-timings = [00 15 05 05 20 1f 05
+ 05 03 03 04 00];
+ qcom,display-topology = <1 1 1>,
+ <2 2 1>, /* dsc merge */
+ <2 1 1>; /* 3d mux */
+ qcom,default-topology-index = <1>;
+ };
+ };
+};
+
+&dsi_nt35597_truly_dsc_video {
+ qcom,mdss-dsi-t-clk-post = <0x0b>;
+ qcom,mdss-dsi-t-clk-pre = <0x23>;
+ qcom,mdss-dsi-display-timings {
+ timing@0{
+ qcom,mdss-dsi-panel-phy-timings = [00 15 05 05 20 1f 05
+ 04 03 03 04 00];
+ qcom,display-topology = <1 1 1>,
+ <2 2 1>, /* dsc merge */
+ <2 1 1>; /* 3d mux */
+ qcom,default-topology-index = <1>;
+ };
+ };
+};
+
+&dsi_sim_vid {
+ qcom,mdss-dsi-t-clk-post = <0x0d>;
+ qcom,mdss-dsi-t-clk-pre = <0x2d>;
+ qcom,mdss-dsi-display-timings {
+ timing@0{
+ qcom,mdss-dsi-panel-phy-timings = [00 1c 07 07 23 21 07
+ 07 05 03 04 00];
+ qcom,display-topology = <1 0 1>,
+ <2 0 1>;
+ qcom,default-topology-index = <0>;
+ };
+ };
+};
+
+&dsi_dual_sim_vid {
+ qcom,mdss-dsi-t-clk-post = <0x0d>;
+ qcom,mdss-dsi-t-clk-pre = <0x2d>;
+ qcom,mdss-dsi-display-timings {
+ timing@0{
+ qcom,mdss-dsi-panel-phy-timings = [00 1c 07 07 23 21 07
+ 07 05 03 04 00];
+ qcom,display-topology = <2 0 2>,
+ <1 0 2>;
+ qcom,default-topology-index = <0>;
+ };
+ };
+};
+
+&dsi_sim_cmd {
+ qcom,mdss-dsi-t-clk-post = <0x0d>;
+ qcom,mdss-dsi-t-clk-pre = <0x2d>;
+ qcom,mdss-dsi-display-timings {
+ timing@0{
+ qcom,mdss-dsi-panel-phy-timings = [00 1c 07 07 23 21 07
+ 07 05 03 04 00];
+ qcom,display-topology = <1 0 1>,
+ <2 0 1>;
+ qcom,default-topology-index = <0>;
+ };
+ };
+};
+
+&dsi_dual_sim_cmd {
+ qcom,mdss-dsi-t-clk-post = <0x0d>;
+ qcom,mdss-dsi-t-clk-pre = <0x2d>;
+ qcom,mdss-dsi-display-timings {
+ timing@0{
+ qcom,mdss-dsi-panel-phy-timings = [00 24 09 09 26 24 09
+ 09 06 03 04 00];
+ qcom,display-topology = <2 0 2>;
+ qcom,default-topology-index = <0>;
+ };
+ timing@1{
+ qcom,mdss-dsi-panel-phy-timings = [00 1c 07 07 23 21 07
+ 07 05 03 04 00];
+ qcom,display-topology = <2 0 2>,
+ <1 0 2>;
+ qcom,default-topology-index = <0>;
+ };
+ timing@2{
+ qcom,mdss-dsi-panel-phy-timings = [00 18 06 06 21 20 06
+ 06 04 03 04 00];
+ qcom,display-topology = <2 0 2>;
+ qcom,default-topology-index = <0>;
+ };
+ };
+};
+
+&dsi_sim_dsc_375_cmd {
+ qcom,mdss-dsi-t-clk-post = <0x0d>;
+ qcom,mdss-dsi-t-clk-pre = <0x2d>;
+ qcom,mdss-dsi-display-timings {
+ timing@0 { /* 1080p */
+ qcom,mdss-dsi-panel-phy-timings = [00 1A 06 06 22 20 07
+ 07 04 03 04 00];
+ qcom,display-topology = <1 1 1>;
+ qcom,default-topology-index = <0>;
+ };
+ timing@1 { /* qhd */
+ qcom,mdss-dsi-panel-phy-timings = [00 15 05 05 20 1f 05
+ 05 03 03 04 00];
+ qcom,display-topology = <1 1 1>,
+ <2 2 1>, /* dsc merge */
+ <2 1 1>; /* 3d mux */
+ qcom,default-topology-index = <0>;
+ };
+ };
+};
+
+&dsi_dual_sim_dsc_375_cmd {
+ qcom,mdss-dsi-t-clk-post = <0x0d>;
+ qcom,mdss-dsi-t-clk-pre = <0x2d>;
+ qcom,mdss-dsi-display-timings {
+ timing@0 { /* qhd */
+ qcom,mdss-dsi-panel-phy-timings = [00 1c 07 07 23 21 07
+ 07 05 03 04 00];
+ qcom,display-topology = <2 2 2>;
+ qcom,default-topology-index = <0>;
+ };
+ timing@1 { /* 4k */
+ qcom,mdss-dsi-panel-phy-timings = [00 18 06 06 21 20 06
+ 06 04 03 04 00];
+ qcom,display-topology = <2 2 2>;
+ qcom,default-topology-index = <0>;
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm670-sde-pll.dtsi b/arch/arm64/boot/dts/qcom/sdm670-sde-pll.dtsi
new file mode 100644
index 0000000..78e5d94
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm670-sde-pll.dtsi
@@ -0,0 +1,110 @@
+/* Copyright (c) 2017, 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.
+ */
+
+&soc {
+ mdss_dsi0_pll: qcom,mdss_dsi_pll@ae94a00 {
+ compatible = "qcom,mdss_dsi_pll_10nm";
+ label = "MDSS DSI 0 PLL";
+ cell-index = <0>;
+ #clock-cells = <1>;
+ reg = <0xae94a00 0x1e0>,
+ <0xae94400 0x800>,
+ <0xaf03000 0x8>;
+ reg-names = "pll_base", "phy_base", "gdsc_base";
+ clocks = <&clock_dispcc DISP_CC_MDSS_AHB_CLK>;
+ clock-names = "iface_clk";
+ clock-rate = <0>;
+ gdsc-supply = <&mdss_core_gdsc>;
+ qcom,platform-supply-entries {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ qcom,platform-supply-entry@0 {
+ reg = <0>;
+ qcom,supply-name = "gdsc";
+ qcom,supply-min-voltage = <0>;
+ qcom,supply-max-voltage = <0>;
+ qcom,supply-enable-load = <0>;
+ qcom,supply-disable-load = <0>;
+ };
+ };
+ };
+
+ mdss_dsi1_pll: qcom,mdss_dsi_pll@ae96a00 {
+ compatible = "qcom,mdss_dsi_pll_10nm";
+ label = "MDSS DSI 1 PLL";
+ cell-index = <1>;
+ #clock-cells = <1>;
+ reg = <0xae96a00 0x1e0>,
+ <0xae96400 0x800>,
+ <0xaf03000 0x8>;
+ reg-names = "pll_base", "phy_base", "gdsc_base";
+ clocks = <&clock_dispcc DISP_CC_MDSS_AHB_CLK>;
+ clock-names = "iface_clk";
+ clock-rate = <0>;
+ gdsc-supply = <&mdss_core_gdsc>;
+ qcom,platform-supply-entries {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ qcom,platform-supply-entry@0 {
+ reg = <0>;
+ qcom,supply-name = "gdsc";
+ qcom,supply-min-voltage = <0>;
+ qcom,supply-max-voltage = <0>;
+ qcom,supply-enable-load = <0>;
+ qcom,supply-disable-load = <0>;
+ };
+ };
+ };
+
+ mdss_dp_pll: qcom,mdss_dp_pll@88ea000 {
+ compatible = "qcom,mdss_dp_pll_10nm";
+ status = "disabled";
+ label = "MDSS DP PLL";
+ cell-index = <0>;
+ #clock-cells = <1>;
+
+ reg = <0x088ea000 0x200>,
+ <0x088eaa00 0x200>,
+ <0x088ea200 0x200>,
+ <0x088ea600 0x200>,
+ <0xaf03000 0x8>;
+ reg-names = "pll_base", "phy_base", "ln_tx0_base",
+ "ln_tx1_base", "gdsc_base";
+
+ gdsc-supply = <&mdss_core_gdsc>;
+
+ clocks = <&clock_dispcc DISP_CC_MDSS_AHB_CLK>,
+ <&clock_rpmh RPMH_CXO_CLK>,
+ <&clock_gcc GCC_USB3_PRIM_CLKREF_CLK>,
+ <&clock_gcc GCC_USB_PHY_CFG_AHB2PHY_CLK>,
+ <&clock_gcc GCC_USB3_PRIM_PHY_PIPE_CLK>;
+ clock-names = "iface_clk", "ref_clk_src", "ref_clk",
+ "cfg_ahb_clk", "pipe_clk";
+ clock-rate = <0>;
+
+ qcom,platform-supply-entries {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ qcom,platform-supply-entry@0 {
+ reg = <0>;
+ qcom,supply-name = "gdsc";
+ qcom,supply-min-voltage = <0>;
+ qcom,supply-max-voltage = <0>;
+ qcom,supply-enable-load = <0>;
+ qcom,supply-disable-load = <0>;
+ };
+
+ };
+ };
+
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm670-sde.dtsi b/arch/arm64/boot/dts/qcom/sdm670-sde.dtsi
new file mode 100644
index 0000000..bb30a20
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm670-sde.dtsi
@@ -0,0 +1,532 @@
+/* Copyright (c) 2017, 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.
+ */
+
+&soc {
+ mdss_mdp: qcom,mdss_mdp@ae00000 {
+ compatible = "qcom,sde-kms";
+ reg = <0x0ae00000 0x81d40>,
+ <0x0aeb0000 0x2008>,
+ <0x0aeac000 0xf0>;
+ reg-names = "mdp_phys",
+ "vbif_phys",
+ "regdma_phys";
+
+ clocks =
+ <&clock_gcc GCC_DISP_AHB_CLK>,
+ <&clock_gcc GCC_DISP_AXI_CLK>,
+ <&clock_dispcc DISP_CC_MDSS_AHB_CLK>,
+ <&clock_dispcc DISP_CC_MDSS_AXI_CLK>,
+ <&clock_dispcc DISP_CC_MDSS_MDP_CLK>,
+ <&clock_dispcc DISP_CC_MDSS_VSYNC_CLK>;
+ clock-names = "gcc_iface", "gcc_bus", "iface_clk",
+ "bus_clk", "core_clk", "vsync_clk";
+ clock-rate = <0 0 0 0 300000000 19200000 0>;
+ clock-max-rate = <0 0 0 0 412500000 19200000 0>;
+
+ sde-vdd-supply = <&mdss_core_gdsc>;
+
+ /* interrupt config */
+ interrupt-parent = <&pdc>;
+ interrupts = <0 83 0>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ iommus = <&apps_smmu 0x880 0x8>,
+ <&apps_smmu 0xc80 0x8>;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ /* hw blocks */
+ qcom,sde-off = <0x1000>;
+ qcom,sde-len = <0x45C>;
+
+ qcom,sde-ctl-off = <0x2000 0x2200 0x2400
+ 0x2600 0x2800>;
+ qcom,sde-ctl-size = <0xE4>;
+
+ qcom,sde-mixer-off = <0x45000 0x46000 0x47000
+ 0x48000 0x49000 0x4a000>;
+ qcom,sde-mixer-size = <0x320>;
+
+ qcom,sde-dspp-top-off = <0x1300>;
+ qcom,sde-dspp-top-size = <0xc>;
+
+ qcom,sde-dspp-off = <0x55000 0x57000>;
+ qcom,sde-dspp-size = <0x17e0>;
+
+ qcom,sde-wb-off = <0x66000>;
+ qcom,sde-wb-size = <0x2c8>;
+ qcom,sde-wb-xin-id = <6>;
+ qcom,sde-wb-id = <2>;
+ qcom,sde-wb-clk-ctrl = <0x3b8 24>;
+
+ qcom,sde-intf-off = <0x6b000 0x6b800
+ 0x6c000 0x6c800>;
+ qcom,sde-intf-size = <0x280>;
+
+ qcom,sde-intf-type = "dp", "dsi", "dsi", "dp";
+ qcom,sde-pp-off = <0x71000 0x71800
+ 0x72000 0x72800 0x73000>;
+ qcom,sde-pp-slave = <0x0 0x0 0x0 0x0 0x1>;
+ qcom,sde-pp-size = <0xd4>;
+
+ qcom,sde-te2-off = <0x2000 0x2000 0x0 0x0 0x0>;
+ qcom,sde-cdm-off = <0x7a200>;
+ qcom,sde-cdm-size = <0x224>;
+
+ qcom,sde-dsc-off = <0x81000 0x81400>;
+ qcom,sde-dsc-size = <0x140>;
+
+ qcom,sde-dither-off = <0x30e0 0x30e0 0x30e0 0x30e0 0x0>;
+ qcom,sde-dither-version = <0x00010000>;
+ qcom,sde-dither-size = <0x20>;
+
+ qcom,sde-sspp-type = "vig", "vig",
+ "dma", "dma", "dma";
+
+ qcom,sde-sspp-off = <0x5000 0x7000 0x25000 0x27000 0x29000>;
+ qcom,sde-sspp-src-size = <0x1c8>;
+
+ qcom,sde-sspp-xin-id = <0 4 1 5 9>;
+ qcom,sde-sspp-excl-rect = <1 1 1 1 1>;
+ qcom,sde-sspp-smart-dma-priority = <4 5 1 2 3>;
+ qcom,sde-smart-dma-rev = "smart_dma_v2";
+
+ qcom,sde-mixer-pair-mask = <2 1 6 0 0 3>;
+
+ qcom,sde-mixer-blend-op-off = <0x20 0x38 0x50 0x68 0x80 0x98
+ 0xb0 0xc8 0xe0 0xf8 0x110>;
+
+ /* offsets are relative to "mdp_phys + qcom,sde-off */
+ qcom,sde-sspp-clk-ctrl =
+ <0x2ac 0>, <0x2b4 0>,
+ <0x2ac 8>, <0x2b4 8>, <0x2bc 8>;
+ qcom,sde-sspp-csc-off = <0x1a00>;
+ qcom,sde-csc-type = "csc-10bit";
+ qcom,sde-qseed-type = "qseedv3";
+ qcom,sde-sspp-qseed-off = <0xa00>;
+ qcom,sde-mixer-linewidth = <2560>;
+ qcom,sde-sspp-linewidth = <2560>;
+ qcom,sde-wb-linewidth = <4096>;
+ qcom,sde-mixer-blendstages = <0xb>;
+ qcom,sde-highest-bank-bit = <0x1>;
+ qcom,sde-ubwc-version = <0x200>;
+ qcom,sde-panic-per-pipe;
+ qcom,sde-has-cdp;
+ qcom,sde-has-src-split;
+ qcom,sde-has-dim-layer;
+ qcom,sde-has-idle-pc;
+ qcom,sde-max-bw-low-kbps = <9600000>;
+ qcom,sde-max-bw-high-kbps = <9600000>;
+ qcom,sde-dram-channels = <2>;
+ qcom,sde-num-nrt-paths = <0>;
+ qcom,sde-dspp-ad-version = <0x00040000>;
+ qcom,sde-dspp-ad-off = <0x28000 0x27000>;
+
+ qcom,sde-vbif-off = <0>;
+ qcom,sde-vbif-size = <0x1040>;
+ qcom,sde-vbif-id = <0>;
+ qcom,sde-vbif-memtype-0 = <3 3 3 3 3 3 3 3>;
+ qcom,sde-vbif-memtype-1 = <3 3 3 3 3 3>;
+
+ qcom,sde-vbif-qos-rt-remap = <3 3 4 4 5 5 6 6>;
+ qcom,sde-vbif-qos-nrt-remap = <3 3 3 3 3 3 3 3>;
+
+ qcom,sde-danger-lut = <0x0000000f 0x0000ffff 0x00000000
+ 0x00000000>;
+ qcom,sde-safe-lut = <0xfffc 0xff00 0xffff 0xffff>;
+ qcom,sde-qos-lut-linear =
+ <4 0x00000000 0x00000357>,
+ <5 0x00000000 0x00003357>,
+ <6 0x00000000 0x00023357>,
+ <7 0x00000000 0x00223357>,
+ <8 0x00000000 0x02223357>,
+ <9 0x00000000 0x22223357>,
+ <10 0x00000002 0x22223357>,
+ <11 0x00000022 0x22223357>,
+ <12 0x00000222 0x22223357>,
+ <13 0x00002222 0x22223357>,
+ <14 0x00012222 0x22223357>,
+ <0 0x00112222 0x22223357>;
+ qcom,sde-qos-lut-macrotile =
+ <10 0x00000003 0x44556677>,
+ <11 0x00000033 0x44556677>,
+ <12 0x00000233 0x44556677>,
+ <13 0x00002233 0x44556677>,
+ <14 0x00012233 0x44556677>,
+ <0 0x00112233 0x44556677>;
+ qcom,sde-qos-lut-nrt =
+ <0 0x00000000 0x00000000>;
+ qcom,sde-qos-lut-cwb =
+ <0 0x75300000 0x00000000>;
+
+ qcom,sde-cdp-setting = <1 1>, <1 0>;
+
+ qcom,sde-inline-rotator = <&mdss_rotator 0>;
+ qcom,sde-inline-rot-xin = <10 11>;
+ qcom,sde-inline-rot-xin-type = "sspp", "wb";
+
+ /* offsets are relative to "mdp_phys + qcom,sde-off */
+ qcom,sde-inline-rot-clk-ctrl = <0x2bc 0x8>, <0x2bc 0xc>;
+
+ qcom,sde-reg-dma-off = <0>;
+ qcom,sde-reg-dma-version = <0x1>;
+ qcom,sde-reg-dma-trigger-off = <0x119c>;
+
+ qcom,sde-sspp-vig-blocks {
+ qcom,sde-vig-csc-off = <0x1a00>;
+ qcom,sde-vig-qseed-off = <0xa00>;
+ qcom,sde-vig-qseed-size = <0xa0>;
+ };
+
+ qcom,sde-dspp-blocks {
+ qcom,sde-dspp-igc = <0x0 0x00030001>;
+ qcom,sde-dspp-vlut = <0xa00 0x00010008>;
+ qcom,sde-dspp-gamut = <0x1000 0x00040000>;
+ qcom,sde-dspp-pcc = <0x1700 0x00040000>;
+ qcom,sde-dspp-gc = <0x17c0 0x00010008>;
+ };
+
+ qcom,platform-supply-entries {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ qcom,platform-supply-entry@0 {
+ reg = <0>;
+ qcom,supply-name = "sde-vdd";
+ qcom,supply-min-voltage = <0>;
+ qcom,supply-max-voltage = <0>;
+ qcom,supply-enable-load = <0>;
+ qcom,supply-disable-load = <0>;
+ };
+ };
+
+ smmu_sde_sec: qcom,smmu_sde_sec_cb {
+ compatible = "qcom,smmu_sde_sec";
+ iommus = <&apps_smmu 0x881 0x8>,
+ <&apps_smmu 0xc81 0x8>;
+ };
+
+ /* data and reg bus scale settings */
+ qcom,sde-data-bus {
+ qcom,msm-bus,name = "mdss_sde_mnoc";
+ qcom,msm-bus,num-cases = <3>;
+ qcom,msm-bus,num-paths = <2>;
+ qcom,msm-bus,vectors-KBps =
+ <22 773 0 0>, <23 773 0 0>,
+ <22 773 0 6400000>, <23 773 0 6400000>,
+ <22 773 0 6400000>, <23 773 0 6400000>;
+ };
+
+ qcom,sde-llcc-bus {
+ qcom,msm-bus,name = "mdss_sde_llcc";
+ qcom,msm-bus,num-cases = <3>;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,vectors-KBps =
+ <132 770 0 0>,
+ <132 770 0 6400000>,
+ <132 770 0 6400000>;
+ };
+
+ qcom,sde-ebi-bus {
+ qcom,msm-bus,name = "mdss_sde_ebi";
+ qcom,msm-bus,num-cases = <3>;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,vectors-KBps =
+ <129 512 0 0>,
+ <129 512 0 6400000>,
+ <129 512 0 6400000>;
+ };
+
+ qcom,sde-reg-bus {
+ qcom,msm-bus,name = "mdss_reg";
+ qcom,msm-bus,num-cases = <4>;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,active-only;
+ qcom,msm-bus,vectors-KBps =
+ <1 590 0 0>,
+ <1 590 0 76800>,
+ <1 590 0 150000>,
+ <1 590 0 300000>;
+ };
+ };
+
+ sde_rscc: qcom,sde_rscc@af20000 {
+ cell-index = <0>;
+ compatible = "qcom,sde-rsc";
+ reg = <0xaf20000 0x1c44>,
+ <0xaf30000 0x3fd4>;
+ reg-names = "drv", "wrapper";
+ qcom,sde-rsc-version = <1>;
+
+ vdd-supply = <&mdss_core_gdsc>;
+ clocks = <&clock_dispcc DISP_CC_MDSS_RSCC_VSYNC_CLK>,
+ <&clock_dispcc DISP_CC_MDSS_RSCC_AHB_CLK>;
+ clock-names = "vsync_clk", "iface_clk";
+ clock-rate = <0 0>;
+
+ qcom,sde-dram-channels = <2>;
+
+ mboxes = <&disp_rsc 0>;
+ mbox-names = "disp_rsc";
+
+ /* data and reg bus scale settings */
+ qcom,sde-data-bus {
+ qcom,msm-bus,name = "disp_rsc_mnoc";
+ qcom,msm-bus,active-only;
+ qcom,msm-bus,num-cases = <3>;
+ qcom,msm-bus,num-paths = <2>;
+ qcom,msm-bus,vectors-KBps =
+ <20003 20515 0 0>, <20004 20515 0 0>,
+ <20003 20515 0 6400000>, <20004 20515 0 6400000>,
+ <20003 20515 0 6400000>, <20004 20515 0 6400000>;
+ };
+
+ qcom,sde-llcc-bus {
+ qcom,msm-bus,name = "disp_rsc_llcc";
+ qcom,msm-bus,active-only;
+ qcom,msm-bus,num-cases = <3>;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,vectors-KBps =
+ <20001 20513 0 0>,
+ <20001 20513 0 6400000>,
+ <20001 20513 0 6400000>;
+ };
+
+ qcom,sde-ebi-bus {
+ qcom,msm-bus,name = "disp_rsc_ebi";
+ qcom,msm-bus,active-only;
+ qcom,msm-bus,num-cases = <3>;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,vectors-KBps =
+ <20000 20512 0 0>,
+ <20000 20512 0 6400000>,
+ <20000 20512 0 6400000>;
+ };
+ };
+
+ mdss_rotator: qcom,mdss_rotator@ae00000 {
+ compatible = "qcom,sde_rotator";
+ reg = <0x0ae00000 0xac000>,
+ <0x0aeb8000 0x3000>;
+ reg-names = "mdp_phys",
+ "rot_vbif_phys";
+
+ #list-cells = <1>;
+
+ qcom,mdss-rot-mode = <1>;
+ qcom,mdss-highest-bank-bit = <0x1>;
+
+ /* Bus Scale Settings */
+ qcom,msm-bus,name = "mdss_rotator";
+ qcom,msm-bus,num-cases = <3>;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,vectors-KBps =
+ <25 512 0 0>,
+ <25 512 0 6400000>,
+ <25 512 0 6400000>;
+
+ rot-vdd-supply = <&mdss_core_gdsc>;
+ qcom,supply-names = "rot-vdd";
+
+ clocks =
+ <&clock_gcc GCC_DISP_AHB_CLK>,
+ <&clock_gcc GCC_DISP_AXI_CLK>,
+ <&clock_dispcc DISP_CC_MDSS_AHB_CLK>,
+ <&clock_dispcc DISP_CC_MDSS_ROT_CLK>,
+ <&clock_dispcc DISP_CC_MDSS_AXI_CLK>;
+ clock-names = "gcc_iface", "gcc_bus",
+ "iface_clk", "rot_clk", "axi_clk";
+
+ interrupt-parent = <&mdss_mdp>;
+ interrupts = <2 0>;
+
+ /* Offline rotator QoS setting */
+ qcom,mdss-rot-vbif-qos-setting = <3 3 3 3 3 3 3 3>;
+ qcom,mdss-rot-vbif-memtype = <3 3>;
+ qcom,mdss-rot-cdp-setting = <1 1>;
+ qcom,mdss-rot-qos-lut = <0x0 0x0 0x0 0x0>;
+ qcom,mdss-rot-danger-lut = <0x0 0x0>;
+ qcom,mdss-rot-safe-lut = <0x0000ffff 0x0000ffff>;
+
+ /* Inline rotator QoS Setting */
+ /* setting default register values for RD - qos/danger/safe */
+ qcom,mdss-inline-rot-qos-lut = <0x44556677 0x00112233
+ 0x44556677 0x00112233>;
+ qcom,mdss-inline-rot-danger-lut = <0x0055aaff 0x0000ffff>;
+ qcom,mdss-inline-rot-safe-lut = <0x0000f000 0x0000ff00>;
+
+ qcom,mdss-default-ot-rd-limit = <32>;
+ qcom,mdss-default-ot-wr-limit = <32>;
+
+ qcom,mdss-sbuf-headroom = <20>;
+
+ cache-slice-names = "rotator";
+ cache-slices = <&llcc 4>;
+
+ /* reg bus scale settings */
+ rot_reg: qcom,rot-reg-bus {
+ qcom,msm-bus,name = "mdss_rot_reg";
+ qcom,msm-bus,num-cases = <2>;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,active-only;
+ qcom,msm-bus,vectors-KBps =
+ <1 590 0 0>,
+ <1 590 0 76800>;
+ };
+
+ smmu_rot_unsec: qcom,smmu_rot_unsec_cb {
+ compatible = "qcom,smmu_sde_rot_unsec";
+ iommus = <&apps_smmu 0x1090 0x0>;
+ };
+
+ smmu_rot_sec: qcom,smmu_rot_sec_cb {
+ compatible = "qcom,smmu_sde_rot_sec";
+ iommus = <&apps_smmu 0x1091 0x0>;
+ };
+ };
+
+ mdss_dsi0: qcom,mdss_dsi_ctrl0@ae94000 {
+ compatible = "qcom,dsi-ctrl-hw-v2.2";
+ label = "dsi-ctrl-0";
+ cell-index = <0>;
+ reg = <0xae94000 0x400>,
+ <0xaf08000 0x4>;
+ reg-names = "dsi_ctrl", "disp_cc_base";
+ interrupt-parent = <&mdss_mdp>;
+ interrupts = <4 0>;
+ vdda-1p2-supply = <&pm660_l1>;
+ clocks = <&clock_dispcc DISP_CC_MDSS_BYTE0_CLK>,
+ <&clock_dispcc DISP_CC_MDSS_BYTE0_CLK_SRC>,
+ <&clock_dispcc DISP_CC_MDSS_BYTE0_INTF_CLK>,
+ <&clock_dispcc DISP_CC_MDSS_PCLK0_CLK>,
+ <&clock_dispcc DISP_CC_MDSS_PCLK0_CLK_SRC>,
+ <&clock_dispcc DISP_CC_MDSS_ESC0_CLK>;
+ clock-names = "byte_clk", "byte_clk_rcg", "byte_intf_clk",
+ "pixel_clk", "pixel_clk_rcg",
+ "esc_clk";
+
+ qcom,ctrl-supply-entries {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ qcom,ctrl-supply-entry@0 {
+ reg = <0>;
+ qcom,supply-name = "vdda-1p2";
+ qcom,supply-min-voltage = <1200000>;
+ qcom,supply-max-voltage = <1200000>;
+ qcom,supply-enable-load = <21800>;
+ qcom,supply-disable-load = <4>;
+ };
+ };
+ };
+
+ mdss_dsi1: qcom,mdss_dsi_ctrl1@ae96000 {
+ compatible = "qcom,dsi-ctrl-hw-v2.2";
+ label = "dsi-ctrl-1";
+ cell-index = <1>;
+ reg = <0xae96000 0x400>,
+ <0xaf08000 0x4>;
+ reg-names = "dsi_ctrl", "disp_cc_base";
+ interrupt-parent = <&mdss_mdp>;
+ interrupts = <5 0>;
+ vdda-1p2-supply = <&pm660_l1>;
+ clocks = <&clock_dispcc DISP_CC_MDSS_BYTE1_CLK>,
+ <&clock_dispcc DISP_CC_MDSS_BYTE1_CLK_SRC>,
+ <&clock_dispcc DISP_CC_MDSS_BYTE1_INTF_CLK>,
+ <&clock_dispcc DISP_CC_MDSS_PCLK1_CLK>,
+ <&clock_dispcc DISP_CC_MDSS_PCLK1_CLK_SRC>,
+ <&clock_dispcc DISP_CC_MDSS_ESC1_CLK>;
+ clock-names = "byte_clk", "byte_clk_rcg", "byte_intf_clk",
+ "pixel_clk", "pixel_clk_rcg", "esc_clk";
+ qcom,ctrl-supply-entries {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ qcom,ctrl-supply-entry@0 {
+ reg = <0>;
+ qcom,supply-name = "vdda-1p2";
+ qcom,supply-min-voltage = <1200000>;
+ qcom,supply-max-voltage = <1200000>;
+ qcom,supply-enable-load = <21800>;
+ qcom,supply-disable-load = <4>;
+ };
+ };
+ };
+
+ mdss_dsi_phy0: qcom,mdss_dsi_phy0@ae94400 {
+ compatible = "qcom,dsi-phy-v3.0";
+ label = "dsi-phy-0";
+ cell-index = <0>;
+ reg = <0xae94400 0x7c0>;
+ reg-names = "dsi_phy";
+ gdsc-supply = <&mdss_core_gdsc>;
+ vdda-0p9-supply = <&pm660l_l1>;
+ qcom,platform-strength-ctrl = [55 03
+ 55 03
+ 55 03
+ 55 03
+ 55 00];
+ qcom,platform-lane-config = [00 00 00 00
+ 00 00 00 00
+ 00 00 00 00
+ 00 00 00 00
+ 00 00 00 80];
+ qcom,platform-regulator-settings = [1d 1d 1d 1d 1d];
+ qcom,phy-supply-entries {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ qcom,phy-supply-entry@0 {
+ reg = <0>;
+ qcom,supply-name = "vdda-0p9";
+ qcom,supply-min-voltage = <880000>;
+ qcom,supply-max-voltage = <880000>;
+ qcom,supply-enable-load = <36000>;
+ qcom,supply-disable-load = <32>;
+ };
+ };
+ };
+
+ mdss_dsi_phy1: qcom,mdss_dsi_phy0@ae96400 {
+ compatible = "qcom,dsi-phy-v3.0";
+ label = "dsi-phy-1";
+ cell-index = <1>;
+ reg = <0xae96400 0x7c0>;
+ reg-names = "dsi_phy";
+ gdsc-supply = <&mdss_core_gdsc>;
+ vdda-0p9-supply = <&pm660l_l1>;
+ qcom,platform-strength-ctrl = [55 03
+ 55 03
+ 55 03
+ 55 03
+ 55 00];
+ qcom,platform-regulator-settings = [1d 1d 1d 1d 1d];
+ qcom,platform-lane-config = [00 00 00 00
+ 00 00 00 00
+ 00 00 00 00
+ 00 00 00 00
+ 00 00 00 80];
+ qcom,phy-supply-entries {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ qcom,phy-supply-entry@0 {
+ reg = <0>;
+ qcom,supply-name = "vdda-0p9";
+ qcom,supply-min-voltage = <880000>;
+ qcom,supply-max-voltage = <880000>;
+ qcom,supply-enable-load = <36000>;
+ qcom,supply-disable-load = <32>;
+ };
+ };
+ };
+
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm670.dtsi b/arch/arm64/boot/dts/qcom/sdm670.dtsi
index c8bb003..f0c1c92 100644
--- a/arch/arm64/boot/dts/qcom/sdm670.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670.dtsi
@@ -614,6 +614,10 @@
#include "sdm670-vidc.dtsi"
+#include "sdm670-sde-pll.dtsi"
+
+#include "sdm670-sde.dtsi"
+
&soc {
#address-cells = <1>;
#size-cells = <1>;
@@ -646,6 +650,14 @@
qcom,pipe-attr-ee;
};
+ qcom,qbt1000 {
+ compatible = "qcom,qbt1000";
+ clock-names = "core", "iface";
+ clock-frequency = <25000000>;
+ qcom,ipc-gpio = <&tlmm 121 0>;
+ qcom,finger-detect-gpio = <&tlmm 122 0>;
+ };
+
thermal_zones: thermal-zones {};
tsens0: tsens@c222000 {
@@ -833,7 +845,7 @@
};
clock_aop: qcom,aopclk {
- compatible = "qcom,aop-qmp-clk-v2";
+ compatible = "qcom,aop-qmp-clk-v1";
#clock-cells = <1>;
mboxes = <&qmp_aop 0>;
mbox-names = "qdss_clk";
@@ -1675,17 +1687,17 @@
<90 512 80000 640000>,
<90 585 80000 640000>,
<1 676 80000 80000>,
- <143 777 0 150000>,
+ <143 777 0 150>, /* IB defined for IPA clk in MHz*/
/* NOMINAL */
<90 512 206000 960000>,
<90 585 206000 960000>,
<1 676 206000 160000>,
- <143 777 0 300000>,
+ <143 777 0 300>, /* IB defined for IPA clk in MHz*/
/* TURBO */
<90 512 206000 3600000>,
<90 585 206000 3600000>,
<1 676 206000 300000>,
- <143 777 0 355333>;
+ <143 777 0 355>; /* IB defined for IPA clk in MHz*/
qcom,bus-vector-names = "MIN", "SVS", "NOMINAL", "TURBO";
/* IPA RAM mmap */
@@ -2270,8 +2282,21 @@
< 2438400 6881 >;
};
};
+
+ gpu_gx_domain_addr: syscon@0x5091508 {
+ compatible = "syscon";
+ reg = <0x5091508 0x4>;
+ };
+
+ gpu_gx_sw_reset: syscon@0x5091008 {
+ compatible = "syscon";
+ reg = <0x5091008 0x4>;
+ };
};
+#include "pm660.dtsi"
+#include "pm660l.dtsi"
+#include "sdm670-regulator.dtsi"
#include "sdm670-pinctrl.dtsi"
#include "msm-arm-smmu-sdm670.dtsi"
#include "msm-gdsc-sdm845.dtsi"
@@ -2346,6 +2371,9 @@
clocks = <&clock_gfx GPU_CC_GX_GFX3D_CLK_SRC>;
qcom,force-enable-root-clk;
parent-supply = <&pm660l_s2_level>;
+ domain-addr = <&gpu_gx_domain_addr>;
+ sw-reset = <&gpu_gx_sw_reset>;
+ qcom,reset-aon-logic;
status = "ok";
};
@@ -2363,9 +2391,6 @@
status = "ok";
};
-#include "pm660.dtsi"
-#include "pm660l.dtsi"
-#include "sdm670-regulator.dtsi"
#include "sdm670-audio.dtsi"
#include "sdm670-usb.dtsi"
#include "sdm670-gpu.dtsi"
diff --git a/arch/arm64/boot/dts/qcom/sdm845-interposer-pm660.dtsi b/arch/arm64/boot/dts/qcom/sdm845-interposer-pm660.dtsi
index e36a759e..5578ece 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-interposer-pm660.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-interposer-pm660.dtsi
@@ -216,11 +216,11 @@
&clock_gpucc {
/delete-property/ vdd_cx-supply;
+ /delete-property/ vdd_mx-supply;
};
&clock_gfx {
/delete-property/ vdd_gfx-supply;
- /delete-property/ vdd_mx-supply;
};
&pil_modem {
diff --git a/arch/arm64/boot/dts/qcom/sdm845-interposer-sdm670-audio-overlay.dtsi b/arch/arm64/boot/dts/qcom/sdm845-interposer-sdm670-audio-overlay.dtsi
new file mode 100644
index 0000000..54bd5201
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm845-interposer-sdm670-audio-overlay.dtsi
@@ -0,0 +1,53 @@
+/* Copyright (c) 2017, 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 "sdm670-audio-overlay.dtsi"
+
+&pm660l_3 {
+ /delete-node/analog-codec;
+};
+
+&soc {
+ /delete-node/msm-sdw-codec@62ec1000;
+ /delete-node/cdc_pdm_pinctrl;
+ /delete-node/wsa_spkr_en1_pinctrl;
+ /delete-node/wsa_spkr_en2_pinctrl;
+ /delete-node/sdw_clk_data_pinctrl;
+};
+
+&qupv3_se8_spi {
+ status = "okay";
+};
+
+&wcd9xxx_intc {
+ status = "okay";
+ qcom,gpio-connect = <&tlmm 54 0>;
+};
+
+&wdsp_mgr {
+ status = "okay";
+};
+
+&wdsp_glink {
+ status = "okay";
+};
+
+&wcd934x_cdc {
+ status = "okay";
+};
+
+&clock_audio_lnbb {
+ status = "okay";
+};
+
+&wcd_rst_gpio {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm845-interposer-sdm670-audio.dtsi b/arch/arm64/boot/dts/qcom/sdm845-interposer-sdm670-audio.dtsi
index f861ca3..88892d7 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-interposer-sdm670-audio.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-interposer-sdm670-audio.dtsi
@@ -10,44 +10,17 @@
* GNU General Public License for more details.
*/
-#include "sdm670-audio.dtsi"
&msm_audio_ion {
iommus = <&apps_smmu 0x1821 0x0>;
qcom,smmu-sid-mask = /bits/ 64 <0xf>;
};
-&qupv3_se8_spi {
- status = "okay";
-};
-
-&pm660l_3 {
- /delete-node/analog-codec;
-};
-
&soc {
- /delete-node/msm-sdw-codec@62ec1000;
/delete-node/sound;
- /delete-node/cdc_pdm_pinctrl;
- /delete-node/wsa_spkr_en1_pinctrl;
- /delete-node/wsa_spkr_en2_pinctrl;
- /delete-node/sdw_clk_data_pinctrl;
};
-&msm_audio_ion {
- iommus = <&apps_smmu 0x1821 0x0>;
-};
-
-&wcd9xxx_intc {
- status = "okay";
- qcom,gpio-connect = <&tlmm 54 0>;
-};
-
-&wdsp_mgr {
- status = "okay";
-};
-
-&wdsp_glink {
+&tavil_snd {
status = "okay";
};
@@ -58,24 +31,3 @@
&dai_slim {
status = "okay";
};
-
-&wcd934x_cdc {
- status = "okay";
-};
-
-&clock_audio_lnbb {
- status = "okay";
-};
-
-&wcd_rst_gpio {
- status = "okay";
-};
-
-&wcd9xxx_intc {
- status = "okay";
-};
-
-&tavil_snd {
- status = "okay";
-};
-
diff --git a/arch/arm64/boot/dts/qcom/sdm845-interposer-sdm670-cdp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm845-interposer-sdm670-cdp-overlay.dts
index da59bcf..9d61324 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-interposer-sdm670-cdp-overlay.dts
+++ b/arch/arm64/boot/dts/qcom/sdm845-interposer-sdm670-cdp-overlay.dts
@@ -21,7 +21,7 @@
#include "sdm845-sde-display.dtsi"
#include "sdm845-interposer-sdm670-cdp.dtsi"
-
+#include "sdm845-interposer-sdm670-audio-overlay.dtsi"
/ {
model = "Qualcomm Technologies, Inc. SDM845 v1 Interposer SDM670 CDP";
compatible = "qcom,sdm845-cdp", "qcom,sdm845", "qcom,cdp";
diff --git a/arch/arm64/boot/dts/qcom/sdm845-interposer-sdm670-cdp.dts b/arch/arm64/boot/dts/qcom/sdm845-interposer-sdm670-cdp.dts
index ebb5e8f..597773e 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-interposer-sdm670-cdp.dts
+++ b/arch/arm64/boot/dts/qcom/sdm845-interposer-sdm670-cdp.dts
@@ -16,6 +16,8 @@
#include "sdm845-interposer-sdm670.dtsi"
#include "sdm845-sde-display.dtsi"
#include "sdm845-interposer-sdm670-cdp.dtsi"
+#include "sdm670-audio.dtsi"
+#include "sdm845-interposer-sdm670-audio.dtsi"
/ {
model = "Qualcomm Technologies, Inc. MSM sdm845 v1 Interposer SDM670 CDP";
diff --git a/arch/arm64/boot/dts/qcom/sdm845-interposer-sdm670-cdp.dtsi b/arch/arm64/boot/dts/qcom/sdm845-interposer-sdm670-cdp.dtsi
index e435cdd..1265d2a 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-interposer-sdm670-cdp.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-interposer-sdm670-cdp.dtsi
@@ -12,7 +12,6 @@
#include "sdm845-cdp.dtsi"
#include "sdm845-interposer-pm660.dtsi"
-#include "sdm845-interposer-sdm670-audio.dtsi"
&soc {
/delete-node/ ssusb@a800000;
diff --git a/arch/arm64/boot/dts/qcom/sdm845-interposer-sdm670-mtp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm845-interposer-sdm670-mtp-overlay.dts
index 3ca15b9..1690174 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-interposer-sdm670-mtp-overlay.dts
+++ b/arch/arm64/boot/dts/qcom/sdm845-interposer-sdm670-mtp-overlay.dts
@@ -21,7 +21,7 @@
#include "sdm845-sde-display.dtsi"
#include "sdm845-interposer-sdm670-mtp.dtsi"
-
+#include "sdm845-interposer-sdm670-audio-overlay.dtsi"
/ {
model = "Qualcomm Technologies, Inc. SDM845 v1 Interposer SDM670 MTP";
compatible = "qcom,sdm845-mtp", "qcom,sdm845", "qcom,mtp";
diff --git a/arch/arm64/boot/dts/qcom/sdm845-interposer-sdm670-mtp.dts b/arch/arm64/boot/dts/qcom/sdm845-interposer-sdm670-mtp.dts
index 39664f1..52869da 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-interposer-sdm670-mtp.dts
+++ b/arch/arm64/boot/dts/qcom/sdm845-interposer-sdm670-mtp.dts
@@ -16,6 +16,8 @@
#include "sdm845-interposer-sdm670.dtsi"
#include "sdm845-sde-display.dtsi"
#include "sdm845-interposer-sdm670-mtp.dtsi"
+#include "sdm670-audio.dtsi"
+#include "sdm845-interposer-sdm670-audio.dtsi"
/ {
model = "Qualcomm Technologies, Inc. MSM sdm845 v1 Interposer SDM670 MTP";
diff --git a/arch/arm64/boot/dts/qcom/sdm845-interposer-sdm670-mtp.dtsi b/arch/arm64/boot/dts/qcom/sdm845-interposer-sdm670-mtp.dtsi
index 4b24b0d..9d722df 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-interposer-sdm670-mtp.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-interposer-sdm670-mtp.dtsi
@@ -12,7 +12,6 @@
#include "sdm845-mtp.dtsi"
#include "sdm845-interposer-pm660.dtsi"
-#include "sdm845-interposer-sdm670-audio.dtsi"
&qupv3_se10_i2c {
/delete-node/ qcom,smb1355@8;
diff --git a/arch/arm64/boot/dts/qcom/sdm845-v2.dtsi b/arch/arm64/boot/dts/qcom/sdm845-v2.dtsi
index 0b55736..80ef35f 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-v2.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-v2.dtsi
@@ -57,7 +57,7 @@
qcom,cpr-saw-use-unit-mV;
qcom,saw-avs-ctrl = <0x101C031>;
- qcom,saw-avs-limit = <0x3B803B8>;
+ qcom,saw-avs-limit = <0x3E803E8>;
qcom,cpr-enable;
qcom,cpr-hw-closed-loop;
@@ -85,9 +85,9 @@
regulator-max-microvolt = <18>;
qcom,cpr-fuse-corners = <4>;
- qcom,cpr-fuse-combos = <16>;
- qcom,cpr-speed-bins = <2>;
- qcom,cpr-speed-bin-corners = <18 18>;
+ qcom,cpr-fuse-combos = <24>;
+ qcom,cpr-speed-bins = <3>;
+ qcom,cpr-speed-bin-corners = <18 18 18>;
qcom,cpr-corners = <18>;
qcom,cpr-corner-fmax-map = <6 12 15 18>;
@@ -133,10 +133,62 @@
1950 2632>;
qcom,cpr-open-loop-voltage-fuse-adjustment =
- < 0 0 12000 12000>;
+ /* Speed bin 0 */
+ < 0 0 12000 12000>,
+ <(-15000) (-15000) (-3000) (-3000)>,
+ <(-15000) (-15000) (-3000) (-3000)>,
+ <(-15000) (-15000) (-3000) (-3000)>,
+ <(-15000) (-15000) (-3000) (-3000)>,
+ <(-15000) (-15000) (-3000) (-3000)>,
+ <(-15000) (-15000) (-3000) (-3000)>,
+ <(-15000) (-15000) (-3000) (-3000)>,
+ /* Speed bin 1 */
+ < 0 0 12000 12000>,
+ <(-15000) (-15000) (-3000) (-3000)>,
+ <(-15000) (-15000) (-3000) (-3000)>,
+ <(-15000) (-15000) (-3000) (-3000)>,
+ <(-15000) (-15000) (-3000) (-3000)>,
+ <(-15000) (-15000) (-3000) (-3000)>,
+ <(-15000) (-15000) (-3000) (-3000)>,
+ <(-15000) (-15000) (-3000) (-3000)>,
+ /* Speed bin 2 */
+ < 0 0 12000 12000>,
+ <(-15000) (-15000) (-3000) (-3000)>,
+ <(-15000) (-15000) (-3000) (-3000)>,
+ <(-15000) (-15000) (-3000) (-3000)>,
+ <(-15000) (-15000) (-3000) (-3000)>,
+ <(-15000) (-15000) (-3000) (-3000)>,
+ <(-15000) (-15000) (-3000) (-3000)>,
+ <(-15000) (-15000) (-3000) (-3000)>;
qcom,cpr-closed-loop-voltage-fuse-adjustment =
- < 0 0 12000 10000>;
+ /* Speed bin 0 */
+ < 0 0 12000 10000>,
+ <(-15000) (-15000) (-3000) (-5000)>,
+ <(-15000) (-15000) (-3000) (-5000)>,
+ <(-15000) (-15000) (-3000) (-5000)>,
+ <(-15000) (-15000) (-3000) (-5000)>,
+ <(-15000) (-15000) (-3000) (-5000)>,
+ <(-15000) (-15000) (-3000) (-5000)>,
+ <(-15000) (-15000) (-3000) (-5000)>,
+ /* Speed bin 1 */
+ < 0 0 12000 10000>,
+ <(-15000) (-15000) (-3000) (-5000)>,
+ <(-15000) (-15000) (-3000) (-5000)>,
+ <(-15000) (-15000) (-3000) (-5000)>,
+ <(-15000) (-15000) (-3000) (-5000)>,
+ <(-15000) (-15000) (-3000) (-5000)>,
+ <(-15000) (-15000) (-3000) (-5000)>,
+ <(-15000) (-15000) (-3000) (-5000)>,
+ /* Speed bin 2 */
+ < 0 0 12000 10000>,
+ <(-15000) (-15000) (-3000) (-5000)>,
+ <(-15000) (-15000) (-3000) (-5000)>,
+ <(-15000) (-15000) (-3000) (-5000)>,
+ <(-15000) (-15000) (-3000) (-5000)>,
+ <(-15000) (-15000) (-3000) (-5000)>,
+ <(-15000) (-15000) (-3000) (-5000)>,
+ <(-15000) (-15000) (-3000) (-5000)>;
qcom,allow-voltage-interpolation;
qcom,allow-quotient-interpolation;
@@ -149,6 +201,8 @@
/* Speed bin 0 */
<0 1 1 1 1 1 1 1>,
/* Speed bin 1 */
+ <0 1 1 1 1 1 1 1>,
+ /* Speed bin 2 */
<0 1 1 1 1 1 1 1>;
qcom,allow-aging-open-loop-voltage-adjustment =
<1>;
@@ -168,19 +222,23 @@
regulator-max-microvolt = <15>;
qcom,cpr-fuse-corners = <4>;
- qcom,cpr-fuse-combos = <16>;
- qcom,cpr-speed-bins = <2>;
- qcom,cpr-speed-bin-corners = <14 15>;
+ qcom,cpr-fuse-combos = <24>;
+ qcom,cpr-speed-bins = <3>;
+ qcom,cpr-speed-bin-corners = <14 15 15>;
qcom,cpr-corners =
/* Speed bin 0 */
<14 14 14 14 14 14 14 14>,
/* Speed bin 1 */
+ <15 15 15 15 15 15 15 15>,
+ /* Speed bin 2 */
<15 15 15 15 15 15 15 15>;
qcom,cpr-corner-fmax-map =
/* Speed bin 0 */
<4 8 11 14>,
/* Speed bin 1 */
+ <4 8 11 15>,
+ /* Speed bin 2 */
<4 8 11 15>;
qcom,cpr-voltage-ceiling =
@@ -192,6 +250,11 @@
<828000 828000 828000 828000 828000
828000 828000 828000 828000 828000
828000 932000 932000 1000000
+ 1000000>,
+ /* Speed bin 2 */
+ <828000 828000 828000 828000 828000
+ 828000 828000 828000 828000 828000
+ 828000 932000 932000 1000000
1000000>;
qcom,cpr-voltage-floor =
@@ -203,6 +266,11 @@
<568000 568000 568000 568000 568000
568000 568000 568000 568000 568000
568000 568000 568000 568000
+ 568000>,
+ /* Speed bin 2 */
+ <568000 568000 568000 568000 568000
+ 568000 568000 568000 568000 568000
+ 568000 568000 568000 568000
568000>;
qcom,cpr-floor-to-ceiling-max-range =
@@ -213,6 +281,10 @@
/* Speed bin 1 */
<32000 32000 32000 32000 32000
32000 32000 32000 32000 32000
+ 32000 32000 32000 40000 40000>,
+ /* Speed bin 2 */
+ <32000 32000 32000 32000 32000
+ 32000 32000 32000 32000 32000
32000 32000 32000 40000 40000>;
qcom,corner-frequencies =
@@ -227,6 +299,12 @@
576000000 652800000 748800000
844800000 940800000 1036800000
1132800000 1209600000 1305600000
+ 1401600000 1497600000 1593600000>,
+ /* Speed bin 2 */
+ <300000000 403200000 480000000
+ 576000000 652800000 748800000
+ 844800000 940800000 1036800000
+ 1132800000 1209600000 1305600000
1401600000 1497600000 1593600000>;
qcom,cpr-ro-scaling-factor =
@@ -244,22 +322,76 @@
2501 2095>;
qcom,cpr-open-loop-voltage-fuse-adjustment =
- < 8000 16000 16000 12000>;
+ /* Speed bin 0 */
+ < 8000 16000 16000 12000>,
+ < (-7000) 1000 1000 (-3000)>,
+ < (-7000) 1000 1000 (-3000)>,
+ < (-7000) 1000 1000 (-3000)>,
+ < (-7000) 1000 1000 (-3000)>,
+ < (-7000) 1000 1000 (-3000)>,
+ < (-7000) 1000 1000 (-3000)>,
+ < (-7000) 1000 1000 (-3000)>,
+ /* Speed bin 1 */
+ < 8000 16000 16000 12000>,
+ < (-7000) 1000 1000 (-3000)>,
+ < (-7000) 1000 1000 (-3000)>,
+ < (-7000) 1000 1000 (-3000)>,
+ < (-7000) 1000 1000 (-3000)>,
+ < (-7000) 1000 1000 (-3000)>,
+ < (-7000) 1000 1000 (-3000)>,
+ < (-7000) 1000 1000 (-3000)>,
+ /* Speed bin 2 */
+ < 8000 16000 16000 12000>,
+ < (-7000) 1000 1000 (-3000)>,
+ < (-7000) 1000 1000 (-3000)>,
+ < (-7000) 1000 1000 (-3000)>,
+ < (-7000) 1000 1000 (-3000)>,
+ < (-7000) 1000 1000 (-3000)>,
+ < (-7000) 1000 1000 (-3000)>,
+ < (-7000) 1000 1000 (-3000)>;
qcom,cpr-closed-loop-voltage-fuse-adjustment =
- < 6000 14000 16000 12000>;
+ /* Speed bin 0 */
+ < 6000 14000 16000 12000>,
+ < (-9000) (-1000) 1000 (-3000)>,
+ < (-9000) (-1000) 1000 (-3000)>,
+ < (-9000) (-1000) 1000 (-3000)>,
+ < (-9000) (-1000) 1000 (-3000)>,
+ < (-9000) (-1000) 1000 (-3000)>,
+ < (-9000) (-1000) 1000 (-3000)>,
+ < (-9000) (-1000) 1000 (-3000)>,
+ /* Speed bin 1 */
+ < 6000 14000 16000 12000>,
+ < (-9000) (-1000) 1000 (-3000)>,
+ < (-9000) (-1000) 1000 (-3000)>,
+ < (-9000) (-1000) 1000 (-3000)>,
+ < (-9000) (-1000) 1000 (-3000)>,
+ < (-9000) (-1000) 1000 (-3000)>,
+ < (-9000) (-1000) 1000 (-3000)>,
+ < (-9000) (-1000) 1000 (-3000)>,
+ /* Speed bin 2 */
+ < 6000 14000 16000 12000>,
+ < (-9000) (-1000) 1000 (-3000)>,
+ < (-9000) (-1000) 1000 (-3000)>,
+ < (-9000) (-1000) 1000 (-3000)>,
+ < (-9000) (-1000) 1000 (-3000)>,
+ < (-9000) (-1000) 1000 (-3000)>,
+ < (-9000) (-1000) 1000 (-3000)>,
+ < (-9000) (-1000) 1000 (-3000)>;
qcom,allow-voltage-interpolation;
qcom,allow-quotient-interpolation;
qcom,cpr-scaled-open-loop-voltage-as-ceiling;
qcom,cpr-aging-max-voltage-adjustment = <15000>;
- qcom,cpr-aging-ref-corner = <14 15>;
+ qcom,cpr-aging-ref-corner = <14 15 15>;
qcom,cpr-aging-ro-scaling-factor = <1620>;
qcom,allow-aging-voltage-adjustment =
/* Speed bin 0 */
<0 1 1 1 1 1 1 1>,
/* Speed bin 1 */
+ <0 1 1 1 1 1 1 1>,
+ /* Speed bin 2 */
<0 1 1 1 1 1 1 1>;
qcom,allow-aging-open-loop-voltage-adjustment =
<1>;
@@ -302,7 +434,7 @@
qcom,cpr-saw-use-unit-mV;
qcom,saw-avs-ctrl = <0x101C031>;
- qcom,saw-avs-limit = <0x4700470>;
+ qcom,saw-avs-limit = <0x4880488>;
qcom,cpr-enable;
qcom,cpr-hw-closed-loop;
@@ -312,7 +444,7 @@
qcom,cpr-panic-reg-name-list =
"APSS_GOLD_CPRH_STATUS_0", "GOLD_SAW4_PMIC_STS";
- qcom,cpr-aging-ref-voltage = <1136000>;
+ qcom,cpr-aging-ref-voltage = <1160000>;
vdd-supply = <&pm8998_s12>;
thread@0 {
@@ -325,23 +457,27 @@
apc1_perfcl_vreg: regulator {
regulator-name = "apc1_perfcl_corner";
regulator-min-microvolt = <1>;
- regulator-max-microvolt = <33>;
+ regulator-max-microvolt = <35>;
qcom,cpr-fuse-corners = <5>;
- qcom,cpr-fuse-combos = <16>;
- qcom,cpr-speed-bins = <2>;
- qcom,cpr-speed-bin-corners = <28 31>;
+ qcom,cpr-fuse-combos = <24>;
+ qcom,cpr-speed-bins = <3>;
+ qcom,cpr-speed-bin-corners = <28 31 33>;
qcom,cpr-corners =
/* Speed bin 0 */
<28 28 28 28 28 28 28 28>,
/* Speed bin 1 */
- <31 31 31 31 31 31 31 31>;
+ <31 31 31 31 31 31 31 31>,
+ /* Speed bin 2 */
+ <33 33 33 33 33 33 33 33>;
qcom,cpr-corner-fmax-map =
/* Speed bin 0 */
<7 14 22 27 28>,
/* Speed bin 1 */
- <7 14 22 27 31>;
+ <7 14 22 27 31>,
+ /* Speed bin 2 */
+ <7 14 22 30 33>;
qcom,cpr-voltage-ceiling =
/* Speed bin 0 */
@@ -350,15 +486,23 @@
828000 828000 828000 828000 828000
828000 828000 828000 932000 932000
932000 932000 1104000 1104000 1104000
- 1104000 1136000 1136000>,
+ 1104000 1160000 1160000>,
/* Speed bin 1 */
<828000 828000 828000 828000 828000
828000 828000 828000 828000 828000
828000 828000 828000 828000 828000
828000 828000 828000 932000 932000
932000 932000 1104000 1104000 1104000
- 1104000 1136000 1136000 1136000 1136000
- 1136000>;
+ 1104000 1160000 1160000 1160000 1160000
+ 1160000>,
+ /* Speed bin 2 */
+ <828000 828000 828000 828000 828000
+ 828000 828000 828000 828000 828000
+ 828000 828000 828000 828000 828000
+ 828000 828000 828000 932000 932000
+ 932000 932000 1104000 1104000 1104000
+ 1104000 1160000 1160000 1160000 1160000
+ 1160000 1160000 1160000>;
qcom,cpr-voltage-floor =
/* Speed bin 0 */
@@ -375,7 +519,15 @@
568000 568000 568000 568000 568000
568000 568000 568000 568000 568000
568000 568000 568000 568000 568000
- 568000>;
+ 568000>,
+ /* Speed bin 2 */
+ <568000 568000 568000 568000 568000
+ 568000 568000 568000 568000 568000
+ 568000 568000 568000 568000 568000
+ 568000 568000 568000 568000 568000
+ 568000 568000 568000 568000 568000
+ 568000 568000 568000 568000 568000
+ 568000 568000 568000>;
qcom,cpr-floor-to-ceiling-max-range =
/* Speed bin 0 */
@@ -392,7 +544,15 @@
32000 32000 32000 32000 32000
32000 32000 32000 32000 32000
32000 32000 40000 40000 40000
- 40000>;
+ 40000>,
+ /* Speed bin 2 */
+ <32000 32000 32000 32000 32000
+ 32000 32000 32000 32000 32000
+ 32000 32000 32000 32000 32000
+ 32000 32000 32000 32000 32000
+ 32000 32000 32000 32000 32000
+ 32000 32000 40000 40000 40000
+ 40000 40000 40000>;
qcom,corner-frequencies =
/* Speed bin 0 */
@@ -417,7 +577,19 @@
1996800000 2092800000 2169600000
2246400000 2323200000 2400000000
2476800000 2553600000 2649600000
- 2707200000>;
+ 2707200000>,
+ /* Speed bin 2 */
+ <300000000 403200000 480000000
+ 576000000 652800000 748800000
+ 825600000 902400000 979200000
+ 1056000000 1132800000 1209600000
+ 1286400000 1363200000 1459200000
+ 1536000000 1612800000 1689600000
+ 1766400000 1843200000 1920000000
+ 1996800000 2092800000 2169600000
+ 2246400000 2323200000 2400000000
+ 2476800000 2553600000 2649600000
+ 2707200000 2726400000 2745600000>;
qcom,cpr-ro-scaling-factor =
<2857 3056 2828 2952 2699 2796 2447
@@ -437,28 +609,76 @@
2003 1675>;
qcom,cpr-open-loop-voltage-fuse-adjustment =
- /* Speed bin 0 */
- < 8000 8000 8000 0 0>,
- /* Speed bin 1 */
- < 8000 8000 8000 0 16000>;
+ /* Speed bin 0 */
+ < 8000 8000 8000 0 0>,
+ < (-7000) (-7000) (-7000) (-15000) (-15000)>,
+ < (-7000) (-7000) (-7000) (-15000) (-15000)>,
+ < (-7000) (-7000) (-7000) (-15000) (-15000)>,
+ < (-7000) (-7000) (-7000) (-15000) (-15000)>,
+ < (-7000) (-7000) (-7000) (-15000) (-15000)>,
+ < (-7000) (-7000) (-7000) (-15000) (-15000)>,
+ < (-7000) (-7000) (-7000) (-15000) (-15000)>,
+ /* Speed bin 1 */
+ < 8000 8000 8000 0 16000>,
+ < (-7000) (-7000) (-7000) (-15000) 1000>,
+ < (-7000) (-7000) (-7000) (-15000) 1000>,
+ < (-7000) (-7000) (-7000) (-15000) 1000>,
+ < (-7000) (-7000) (-7000) (-15000) 1000>,
+ < (-7000) (-7000) (-7000) (-15000) 1000>,
+ < (-7000) (-7000) (-7000) (-15000) 1000>,
+ < (-7000) (-7000) (-7000) (-15000) 1000>,
+ /* Speed bin 2 */
+ < 8000 8000 8000 0 16000>,
+ < (-7000) (-7000) (-7000) (-15000) 1000>,
+ < (-7000) (-7000) (-7000) (-15000) 1000>,
+ < (-7000) (-7000) (-7000) (-15000) 1000>,
+ < (-7000) (-7000) (-7000) (-15000) 1000>,
+ < (-7000) (-7000) (-7000) (-15000) 1000>,
+ < (-7000) (-7000) (-7000) (-15000) 1000>,
+ < (-7000) (-7000) (-7000) (-15000) 1000>;
qcom,cpr-closed-loop-voltage-fuse-adjustment =
- /* Speed bin 0 */
- < 6000 6000 8000 0 0>,
- /* Speed bin 1 */
- < 6000 6000 8000 0 16000>;
+ /* Speed bin 0 */
+ < 6000 6000 8000 0 0>,
+ < (-9000) (-9000) (-7000) (-15000) (-15000)>,
+ < (-9000) (-9000) (-7000) (-15000) (-15000)>,
+ < (-9000) (-9000) (-7000) (-15000) (-15000)>,
+ < (-9000) (-9000) (-7000) (-15000) (-15000)>,
+ < (-9000) (-9000) (-7000) (-15000) (-15000)>,
+ < (-9000) (-9000) (-7000) (-15000) (-15000)>,
+ < (-9000) (-9000) (-7000) (-15000) (-15000)>,
+ /* Speed bin 1 */
+ < 6000 6000 8000 0 16000>,
+ < (-9000) (-9000) (-7000) (-15000) 1000>,
+ < (-9000) (-9000) (-7000) (-15000) 1000>,
+ < (-9000) (-9000) (-7000) (-15000) 1000>,
+ < (-9000) (-9000) (-7000) (-15000) 1000>,
+ < (-9000) (-9000) (-7000) (-15000) 1000>,
+ < (-9000) (-9000) (-7000) (-15000) 1000>,
+ < (-9000) (-9000) (-7000) (-15000) 1000>,
+ /* Speed bin 2 */
+ < 6000 6000 8000 0 16000>,
+ < (-9000) (-9000) (-7000) (-15000) 1000>,
+ < (-9000) (-9000) (-7000) (-15000) 1000>,
+ < (-9000) (-9000) (-7000) (-15000) 1000>,
+ < (-9000) (-9000) (-7000) (-15000) 1000>,
+ < (-9000) (-9000) (-7000) (-15000) 1000>,
+ < (-9000) (-9000) (-7000) (-15000) 1000>,
+ < (-9000) (-9000) (-7000) (-15000) 1000>;
qcom,allow-voltage-interpolation;
qcom,allow-quotient-interpolation;
qcom,cpr-scaled-open-loop-voltage-as-ceiling;
qcom,cpr-aging-max-voltage-adjustment = <15000>;
- qcom,cpr-aging-ref-corner = <27 31>;
+ qcom,cpr-aging-ref-corner = <27 31 33>;
qcom,cpr-aging-ro-scaling-factor = <1700>;
qcom,allow-aging-voltage-adjustment =
/* Speed bin 0 */
<0 1 1 1 1 1 1 1>,
/* Speed bin 1 */
+ <0 1 1 1 1 1 1 1>,
+ /* Speed bin 2 */
<0 1 1 1 1 1 1 1>;
qcom,allow-aging-open-loop-voltage-adjustment =
<1>;
@@ -490,7 +710,7 @@
/* VDD_APC1 */
&pm8998_s12 {
regulator-min-microvolt = <568000>;
- regulator-max-microvolt = <1136000>;
+ regulator-max-microvolt = <1160000>;
};
&clock_cpucc {
@@ -533,6 +753,23 @@
< 1497600000 0x403c0d4e 0x00003e3e 0x2 14 >,
< 1593600000 0x403c0e53 0x00004242 0x2 15 >;
+ qcom,l3-speedbin2-v0 =
+ < 300000000 0x000c000f 0x00002020 0x1 1 >,
+ < 403200000 0x500c0115 0x00002020 0x1 2 >,
+ < 480000000 0x50140219 0x00002020 0x1 3 >,
+ < 576000000 0x5014031e 0x00002020 0x1 4 >,
+ < 652800000 0x401c0422 0x00002020 0x1 5 >,
+ < 748800000 0x401c0527 0x00002020 0x1 6 >,
+ < 844800000 0x4024062c 0x00002323 0x2 7 >,
+ < 940800000 0x40240731 0x00002727 0x2 8 >,
+ < 1036800000 0x40240836 0x00002b2b 0x2 9 >,
+ < 1132800000 0x402c093b 0x00002f2f 0x2 10 >,
+ < 1209600000 0x402c0a3f 0x00003232 0x2 11 >,
+ < 1305600000 0x40340b44 0x00003636 0x2 12 >,
+ < 1401600000 0x40340c49 0x00003a3a 0x2 13 >,
+ < 1497600000 0x403c0d4e 0x00003e3e 0x2 14 >,
+ < 1593600000 0x403c0e53 0x00004242 0x2 15 >;
+
qcom,pwrcl-speedbin0-v0 =
< 300000000 0x000c000f 0x00002020 0x1 1 >,
< 403200000 0x500c0115 0x00002020 0x1 2 >,
@@ -573,6 +810,26 @@
< 1689600000 0x40441058 0x00004646 0x2 17 >,
< 1766400000 0x4044115c 0x00004a4a 0x2 18 >;
+ qcom,pwrcl-speedbin2-v0 =
+ < 300000000 0x000c000f 0x00002020 0x1 1 >,
+ < 403200000 0x500c0115 0x00002020 0x1 2 >,
+ < 480000000 0x50140219 0x00002020 0x1 3 >,
+ < 576000000 0x5014031e 0x00002020 0x1 4 >,
+ < 652800000 0x401c0422 0x00002020 0x1 5 >,
+ < 748800000 0x401c0527 0x00002020 0x1 6 >,
+ < 825600000 0x401c062b 0x00002222 0x1 7 >,
+ < 902400000 0x4024072f 0x00002626 0x1 8 >,
+ < 979200000 0x40240833 0x00002929 0x1 9 >,
+ < 1056000000 0x402c0937 0x00002c2c 0x2 10 >,
+ < 1132800000 0x402c0a3b 0x00002f2f 0x2 11 >,
+ < 1228800000 0x402c0b40 0x00003333 0x2 12 >,
+ < 1324800000 0x40340c45 0x00003737 0x2 13 >,
+ < 1420800000 0x40340d4a 0x00003b3b 0x2 14 >,
+ < 1516800000 0x403c0e4f 0x00003f3f 0x2 15 >,
+ < 1612800000 0x403c0f54 0x00004343 0x2 16 >,
+ < 1689600000 0x40441058 0x00004646 0x2 17 >,
+ < 1766400000 0x4044115c 0x00004a4a 0x2 18 >;
+
qcom,perfcl-speedbin0-v0 =
< 300000000 0x000c000f 0x00002020 0x1 1 >,
< 403200000 0x500c0115 0x00002020 0x1 2 >,
@@ -635,14 +892,53 @@
< 2649600000 0x40541d8a 0x00006e6e 0x2 30 >,
< 2745600000 0x40511e8f 0x00007272 0x2 31 >;
+ qcom,perfcl-speedbin2-v0 =
+ < 300000000 0x000c000f 0x00002020 0x1 1 >,
+ < 403200000 0x500c0115 0x00002020 0x1 2 >,
+ < 480000000 0x50140219 0x00002020 0x1 3 >,
+ < 576000000 0x5014031e 0x00002020 0x1 4 >,
+ < 652800000 0x401c0422 0x00002020 0x1 5 >,
+ < 748800000 0x401c0527 0x00002020 0x1 6 >,
+ < 825600000 0x401c062b 0x00002222 0x1 7 >,
+ < 902400000 0x4024072f 0x00002626 0x1 8 >,
+ < 979200000 0x40240833 0x00002929 0x1 9 >,
+ < 1056000000 0x402c0937 0x00002c2c 0x1 10 >,
+ < 1132800000 0x402c0a3b 0x00002f2f 0x1 11 >,
+ < 1209600000 0x402c0b3f 0x00003232 0x2 12 >,
+ < 1286400000 0x40340c43 0x00003636 0x2 13 >,
+ < 1363200000 0x40340d47 0x00003939 0x2 14 >,
+ < 1459200000 0x403c0e4c 0x00003d3d 0x2 15 >,
+ < 1536000000 0x403c0f50 0x00004040 0x2 16 >,
+ < 1612800000 0x403c1054 0x00004343 0x2 17 >,
+ < 1689600000 0x40441158 0x00004646 0x2 18 >,
+ < 1766400000 0x4044125c 0x00004a4a 0x2 19 >,
+ < 1843200000 0x40441360 0x00004d4d 0x2 20 >,
+ < 1920000000 0x404c1464 0x00005050 0x2 21 >,
+ < 1996800000 0x404c1568 0x00005353 0x2 22 >,
+ < 2092800000 0x4054166d 0x00005757 0x2 23 >,
+ < 2169600000 0x40541771 0x00005a5a 0x2 24 >,
+ < 2246400000 0x40541875 0x00005e5e 0x2 25 >,
+ < 2323200000 0x40541979 0x00006161 0x2 26 >,
+ < 2400000000 0x40541a7d 0x00006464 0x2 27 >,
+ < 2476800000 0x40541b81 0x00006767 0x2 28 >,
+ < 2553600000 0x40541c85 0x00006a6a 0x2 29 >,
+ < 2649600000 0x40541d8a 0x00006e6e 0x2 30 >,
+ < 2707200000 0x40511e8d 0x00007171 0x2 30 >,
+ < 2764800000 0x40511f90 0x00007373 0x2 31 >,
+ < 2784000000 0x40512091 0x00007474 0x2 32 >,
+ < 2803200000 0x40512192 0x00007575 0x2 33 >;
+
qcom,l3-memacc-level-vc-bin0 = <8 13>;
qcom,l3-memacc-level-vc-bin1 = <8 13>;
+ qcom,l3-memacc-level-vc-bin2 = <8 13>;
qcom,pwrcl-memacc-level-vc-bin0 = <12 16>;
qcom,pwrcl-memacc-level-vc-bin1 = <12 16>;
+ qcom,pwrcl-memacc-level-vc-bin2 = <12 16>;
qcom,perfcl-memacc-level-vc-bin0 = <14 22>;
qcom,perfcl-memacc-level-vc-bin1 = <14 22>;
+ qcom,perfcl-memacc-level-vc-bin2 = <14 22>;
};
&pcie1 {
diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi
index b4c1fb3..ff092ea 100644
--- a/arch/arm64/boot/dts/qcom/sdm845.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi
@@ -1094,6 +1094,7 @@
reg = <0x5090000 0x9000>;
reg-names = "cc_base";
vdd_cx-supply = <&pm8998_s9_level>;
+ vdd_mx-supply = <&pm8998_s6_level>;
qcom,gpu_cc_gmu_clk_src-opp-handle = <&gmu>;
#clock-cells = <1>;
#reset-cells = <1>;
@@ -1104,7 +1105,6 @@
reg = <0x5090000 0x9000>;
reg-names = "cc_base";
vdd_gfx-supply = <&pm8005_s1_level>;
- vdd_mx-supply = <&pm8998_s6_level>;
qcom,gpu_cc_gx_gfx3d_clk_src-opp-handle = <&msm_gpu>;
#clock-cells = <1>;
#reset-cells = <1>;
diff --git a/arch/arm64/configs/msm8953-perf_defconfig b/arch/arm64/configs/msm8953-perf_defconfig
new file mode 100644
index 0000000..98def01
--- /dev/null
+++ b/arch/arm64/configs/msm8953-perf_defconfig
@@ -0,0 +1,474 @@
+CONFIG_LOCALVERSION="-perf"
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_FHANDLE is not set
+CONFIG_AUDIT=y
+# CONFIG_AUDITSYSCALL is not set
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_IRQ_TIME_ACCOUNTING=y
+CONFIG_SCHED_WALT=y
+CONFIG_RCU_EXPERT=y
+CONFIG_RCU_FAST_NO_HZ=y
+CONFIG_RCU_NOCB_CPU=y
+CONFIG_RCU_NOCB_CPU_ALL=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_CPU_MAX_BUF_SHIFT=17
+CONFIG_CGROUP_FREEZER=y
+CONFIG_CPUSETS=y
+CONFIG_CGROUP_CPUACCT=y
+CONFIG_CGROUP_SCHEDTUNE=y
+CONFIG_RT_GROUP_SCHED=y
+CONFIG_CGROUP_BPF=y
+CONFIG_SCHED_CORE_CTL=y
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_PID_NS is not set
+CONFIG_SCHED_AUTOGROUP=y
+CONFIG_SCHED_TUNE=y
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_RD_XZ is not set
+# CONFIG_RD_LZO is not set
+# CONFIG_RD_LZ4 is not set
+CONFIG_KALLSYMS_ALL=y
+CONFIG_BPF_SYSCALL=y
+# CONFIG_AIO is not set
+# CONFIG_MEMBARRIER is not set
+CONFIG_EMBEDDED=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_PROFILING=y
+CONFIG_CC_STACKPROTECTOR_STRONG=y
+CONFIG_ARCH_MMAP_RND_COMPAT_BITS=16
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SIG=y
+CONFIG_MODULE_SIG_FORCE=y
+CONFIG_MODULE_SIG_SHA512=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_IOSCHED_DEADLINE is not set
+CONFIG_ARCH_QCOM=y
+CONFIG_ARCH_MSM8953=y
+CONFIG_SCHED_MC=y
+CONFIG_NR_CPUS=8
+CONFIG_PREEMPT=y
+CONFIG_HZ_100=y
+CONFIG_CMA=y
+CONFIG_ZSMALLOC=y
+CONFIG_BALANCE_ANON_FILE_RECLAIM=y
+CONFIG_SECCOMP=y
+CONFIG_ARMV8_DEPRECATED=y
+CONFIG_SWP_EMULATION=y
+CONFIG_CP15_BARRIER_EMULATION=y
+CONFIG_SETEND_EMULATION=y
+# CONFIG_ARM64_VHE is not set
+CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_COMPAT=y
+CONFIG_PM_AUTOSLEEP=y
+CONFIG_PM_WAKELOCKS=y
+CONFIG_PM_WAKELOCKS_LIMIT=0
+# CONFIG_PM_WAKELOCKS_GC is not set
+CONFIG_CPU_IDLE=y
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
+CONFIG_CPU_BOOST=y
+CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_XFRM_USER=y
+CONFIG_XFRM_STATISTICS=y
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_INET_AH=y
+CONFIG_INET_ESP=y
+CONFIG_INET_IPCOMP=y
+CONFIG_INET_DIAG_DESTROY=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_ROUTE_INFO=y
+CONFIG_IPV6_OPTIMISTIC_DAD=y
+CONFIG_INET6_AH=y
+CONFIG_INET6_ESP=y
+CONFIG_INET6_IPCOMP=y
+CONFIG_IPV6_MIP6=y
+CONFIG_IPV6_MULTIPLE_TABLES=y
+CONFIG_IPV6_SUBTREES=y
+CONFIG_NETFILTER=y
+CONFIG_NF_CONNTRACK=y
+CONFIG_NF_CONNTRACK_SECMARK=y
+CONFIG_NF_CONNTRACK_EVENTS=y
+CONFIG_NF_CT_PROTO_DCCP=y
+CONFIG_NF_CT_PROTO_SCTP=y
+CONFIG_NF_CT_PROTO_UDPLITE=y
+CONFIG_NF_CONNTRACK_AMANDA=y
+CONFIG_NF_CONNTRACK_FTP=y
+CONFIG_NF_CONNTRACK_H323=y
+CONFIG_NF_CONNTRACK_IRC=y
+CONFIG_NF_CONNTRACK_NETBIOS_NS=y
+CONFIG_NF_CONNTRACK_PPTP=y
+CONFIG_NF_CONNTRACK_SANE=y
+CONFIG_NF_CONNTRACK_TFTP=y
+CONFIG_NF_CT_NETLINK=y
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=y
+CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=y
+CONFIG_NETFILTER_XT_TARGET_IDLETIMER=y
+CONFIG_NETFILTER_XT_TARGET_HARDIDLETIMER=y
+CONFIG_NETFILTER_XT_TARGET_LOG=y
+CONFIG_NETFILTER_XT_TARGET_MARK=y
+CONFIG_NETFILTER_XT_TARGET_NFLOG=y
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y
+CONFIG_NETFILTER_XT_TARGET_NOTRACK=y
+CONFIG_NETFILTER_XT_TARGET_TEE=y
+CONFIG_NETFILTER_XT_TARGET_TPROXY=y
+CONFIG_NETFILTER_XT_TARGET_TRACE=y
+CONFIG_NETFILTER_XT_TARGET_SECMARK=y
+CONFIG_NETFILTER_XT_TARGET_TCPMSS=y
+CONFIG_NETFILTER_XT_MATCH_COMMENT=y
+CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=y
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
+CONFIG_NETFILTER_XT_MATCH_DSCP=y
+CONFIG_NETFILTER_XT_MATCH_ESP=y
+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=y
+CONFIG_NETFILTER_XT_MATCH_HELPER=y
+CONFIG_NETFILTER_XT_MATCH_IPRANGE=y
+# CONFIG_NETFILTER_XT_MATCH_L2TP is not set
+CONFIG_NETFILTER_XT_MATCH_LENGTH=y
+CONFIG_NETFILTER_XT_MATCH_LIMIT=y
+CONFIG_NETFILTER_XT_MATCH_MAC=y
+CONFIG_NETFILTER_XT_MATCH_MARK=y
+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=y
+CONFIG_NETFILTER_XT_MATCH_POLICY=y
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y
+CONFIG_NETFILTER_XT_MATCH_QTAGUID=y
+CONFIG_NETFILTER_XT_MATCH_QUOTA=y
+CONFIG_NETFILTER_XT_MATCH_QUOTA2=y
+CONFIG_NETFILTER_XT_MATCH_SOCKET=y
+CONFIG_NETFILTER_XT_MATCH_STATE=y
+CONFIG_NETFILTER_XT_MATCH_STATISTIC=y
+CONFIG_NETFILTER_XT_MATCH_STRING=y
+CONFIG_NETFILTER_XT_MATCH_TIME=y
+CONFIG_NETFILTER_XT_MATCH_U32=y
+CONFIG_NF_CONNTRACK_IPV4=y
+CONFIG_IP_NF_IPTABLES=y
+CONFIG_IP_NF_MATCH_AH=y
+CONFIG_IP_NF_MATCH_ECN=y
+CONFIG_IP_NF_MATCH_RPFILTER=y
+CONFIG_IP_NF_MATCH_TTL=y
+CONFIG_IP_NF_FILTER=y
+CONFIG_IP_NF_TARGET_REJECT=y
+CONFIG_IP_NF_NAT=y
+CONFIG_IP_NF_TARGET_MASQUERADE=y
+CONFIG_IP_NF_TARGET_NETMAP=y
+CONFIG_IP_NF_TARGET_REDIRECT=y
+CONFIG_IP_NF_MANGLE=y
+CONFIG_IP_NF_RAW=y
+CONFIG_IP_NF_SECURITY=y
+CONFIG_IP_NF_ARPTABLES=y
+CONFIG_IP_NF_ARPFILTER=y
+CONFIG_IP_NF_ARP_MANGLE=y
+CONFIG_NF_CONNTRACK_IPV6=y
+CONFIG_IP6_NF_IPTABLES=y
+CONFIG_IP6_NF_MATCH_RPFILTER=y
+CONFIG_IP6_NF_FILTER=y
+CONFIG_IP6_NF_TARGET_REJECT=y
+CONFIG_IP6_NF_MANGLE=y
+CONFIG_IP6_NF_RAW=y
+CONFIG_BRIDGE_NF_EBTABLES=y
+CONFIG_BRIDGE_EBT_BROUTE=y
+CONFIG_L2TP=y
+CONFIG_L2TP_V3=y
+CONFIG_L2TP_IP=y
+CONFIG_L2TP_ETH=y
+CONFIG_BRIDGE=y
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_HTB=y
+CONFIG_NET_SCH_PRIO=y
+CONFIG_NET_SCH_MULTIQ=y
+CONFIG_NET_SCH_INGRESS=y
+CONFIG_NET_CLS_FW=y
+CONFIG_NET_CLS_U32=y
+CONFIG_CLS_U32_MARK=y
+CONFIG_NET_CLS_FLOW=y
+CONFIG_NET_EMATCH=y
+CONFIG_NET_EMATCH_CMP=y
+CONFIG_NET_EMATCH_NBYTE=y
+CONFIG_NET_EMATCH_U32=y
+CONFIG_NET_EMATCH_META=y
+CONFIG_NET_EMATCH_TEXT=y
+CONFIG_NET_CLS_ACT=y
+CONFIG_NET_ACT_GACT=y
+CONFIG_NET_ACT_MIRRED=y
+CONFIG_NET_ACT_SKBEDIT=y
+CONFIG_RMNET_DATA=y
+CONFIG_RMNET_DATA_FC=y
+CONFIG_RMNET_DATA_DEBUG_PKT=y
+CONFIG_BT=y
+CONFIG_MSM_BT_POWER=y
+CONFIG_CFG80211=y
+CONFIG_CFG80211_INTERNAL_REGDB=y
+# CONFIG_CFG80211_CRDA_SUPPORT is not set
+CONFIG_RFKILL=y
+CONFIG_NFC_NQ=y
+CONFIG_IPC_ROUTER=y
+CONFIG_IPC_ROUTER_SECURITY=y
+CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y
+CONFIG_DMA_CMA=y
+CONFIG_ZRAM=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_QSEECOM=y
+CONFIG_MEMORY_STATE_TIME=y
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_SG=y
+CONFIG_CHR_DEV_SCH=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+CONFIG_SCSI_SCAN_ASYNC=y
+CONFIG_SCSI_UFSHCD=y
+CONFIG_SCSI_UFSHCD_PLATFORM=y
+CONFIG_SCSI_UFS_QCOM=y
+CONFIG_SCSI_UFS_QCOM_ICE=y
+CONFIG_SCSI_UFSHCD_CMD_LOGGING=y
+CONFIG_MD=y
+CONFIG_BLK_DEV_DM=y
+CONFIG_DM_DEBUG=y
+CONFIG_DM_CRYPT=y
+CONFIG_DM_REQ_CRYPT=y
+CONFIG_DM_UEVENT=y
+CONFIG_DM_VERITY=y
+CONFIG_DM_VERITY_FEC=y
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=y
+CONFIG_TUN=y
+CONFIG_PPP=y
+CONFIG_PPP_BSDCOMP=y
+CONFIG_PPP_DEFLATE=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_MPPE=y
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPPOE=y
+CONFIG_PPPOL2TP=y
+CONFIG_PPPOLAC=y
+CONFIG_PPPOPNS=y
+CONFIG_PPP_ASYNC=y
+CONFIG_PPP_SYNC_TTY=y
+CONFIG_WCNSS_MEM_PRE_ALLOC=y
+CONFIG_CLD_LL_CORE=y
+CONFIG_INPUT_EVDEV=y
+CONFIG_KEYBOARD_GPIO=y
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_JOYSTICK=y
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_HBTP_INPUT=y
+CONFIG_INPUT_UINPUT=y
+# CONFIG_SERIO_SERPORT is not set
+# CONFIG_VT is not set
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_SERIAL_MSM=y
+CONFIG_SERIAL_MSM_CONSOLE=y
+CONFIG_HW_RANDOM=y
+CONFIG_HW_RANDOM_MSM_LEGACY=y
+CONFIG_MSM_ADSPRPC=y
+CONFIG_MSM_RDBG=m
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_QCOM_GENI=y
+CONFIG_SPI=y
+CONFIG_SPI_QUP=y
+CONFIG_SPI_QCOM_GENI=y
+CONFIG_SPI_SPIDEV=y
+CONFIG_SLIMBUS_MSM_NGD=y
+CONFIG_SPMI=y
+CONFIG_SPMI_MSM_PMIC_ARB_DEBUG=y
+CONFIG_PINCTRL_MSM8953=y
+CONFIG_PINCTRL_QCOM_SPMI_PMIC=y
+CONFIG_GPIOLIB=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_POWER_RESET_QCOM=y
+CONFIG_QCOM_DLOAD_MODE=y
+CONFIG_POWER_RESET_XGENE=y
+CONFIG_POWER_RESET_SYSCON=y
+CONFIG_SENSORS_QPNP_ADC_VOLTAGE=y
+CONFIG_THERMAL=y
+CONFIG_THERMAL_QPNP=y
+CONFIG_THERMAL_QPNP_ADC_TM=y
+CONFIG_THERMAL_TSENS=y
+CONFIG_MSM_BCL_PERIPHERAL_CTL=y
+CONFIG_QTI_THERMAL_LIMITS_DCVS=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_REGULATOR_CPRH_KBSS=y
+CONFIG_REGULATOR_QPNP_LABIBB=y
+CONFIG_REGULATOR_QPNP=y
+CONFIG_REGULATOR_STUB=y
+CONFIG_MEDIA_SUPPORT=y
+CONFIG_MEDIA_CAMERA_SUPPORT=y
+CONFIG_MEDIA_CONTROLLER=y
+CONFIG_VIDEO_V4L2_SUBDEV_API=y
+CONFIG_V4L_PLATFORM_DRIVERS=y
+CONFIG_MSM_VIDC_V4L2=y
+CONFIG_MSM_VIDC_GOVERNORS=y
+CONFIG_MSM_SDE_ROTATOR=y
+CONFIG_MSM_SDE_ROTATOR_EVTLOG_DEBUG=y
+CONFIG_QCOM_KGSL=y
+CONFIG_DRM=y
+CONFIG_DRM_SDE_EVTLOG_DEBUG=y
+CONFIG_DRM_SDE_RSC=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_DYNAMIC_MINORS=y
+CONFIG_SND_SOC=y
+CONFIG_UHID=y
+CONFIG_HID_APPLE=y
+CONFIG_HID_ELECOM=y
+CONFIG_HID_MAGICMOUSE=y
+CONFIG_HID_MICROSOFT=y
+CONFIG_HID_MULTITOUCH=y
+CONFIG_USB_DWC3=y
+CONFIG_NOP_USB_XCEIV=y
+CONFIG_DUAL_ROLE_USB_INTF=y
+CONFIG_USB_MSM_SSPHY_QMP=y
+CONFIG_MSM_QUSB_PHY=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET_DEBUG_FILES=y
+CONFIG_USB_GADGET_DEBUG_FS=y
+CONFIG_USB_GADGET_VBUS_DRAW=500
+CONFIG_MMC=y
+CONFIG_MMC_PERF_PROFILING=y
+CONFIG_MMC_PARANOID_SD_INIT=y
+CONFIG_MMC_CLKGATE=y
+CONFIG_MMC_BLOCK_MINORS=32
+CONFIG_MMC_BLOCK_DEFERRED_RESUME=y
+CONFIG_MMC_TEST=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_SDHCI_MSM=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_QPNP=y
+CONFIG_LEDS_QPNP_WLED=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_EDAC=y
+CONFIG_EDAC_MM_EDAC=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_QPNP=y
+CONFIG_DMADEVICES=y
+CONFIG_QCOM_SPS_DMA=y
+CONFIG_UIO=y
+CONFIG_UIO_MSM_SHAREDMEM=y
+CONFIG_STAGING=y
+CONFIG_ASHMEM=y
+CONFIG_ANDROID_LOW_MEMORY_KILLER=y
+CONFIG_ION=y
+CONFIG_ION_MSM=y
+CONFIG_GSI=y
+CONFIG_IPA3=y
+CONFIG_RMNET_IPA3=y
+CONFIG_RNDIS_IPA=y
+CONFIG_IPA_UT=y
+CONFIG_SPS=y
+CONFIG_SPS_SUPPORT_NDP_BAM=y
+CONFIG_QPNP_COINCELL=y
+CONFIG_QPNP_REVID=y
+CONFIG_USB_BAM=y
+CONFIG_QCOM_MDSS_PLL=y
+CONFIG_REMOTE_SPINLOCK_MSM=y
+CONFIG_ARM_SMMU=y
+CONFIG_MSM_BOOT_STATS=y
+CONFIG_QCOM_EUD=y
+CONFIG_QCOM_WATCHDOG_V2=y
+CONFIG_QCOM_MEMORY_DUMP_V2=y
+CONFIG_QCOM_SECURE_BUFFER=y
+CONFIG_QCOM_EARLY_RANDOM=y
+CONFIG_MSM_SMEM=y
+CONFIG_MSM_GLINK=y
+CONFIG_MSM_GLINK_LOOPBACK_SERVER=y
+CONFIG_MSM_GLINK_SMEM_NATIVE_XPRT=y
+CONFIG_MSM_GLINK_SPI_XPRT=y
+CONFIG_MSM_SMP2P=y
+CONFIG_MSM_SMP2P_TEST=y
+CONFIG_MSM_IPC_ROUTER_GLINK_XPRT=y
+CONFIG_MSM_QMI_INTERFACE=y
+CONFIG_MSM_GLINK_PKT=y
+CONFIG_MSM_SUBSYSTEM_RESTART=y
+CONFIG_MSM_PIL=y
+CONFIG_MSM_PIL_SSR_GENERIC=y
+CONFIG_MSM_PIL_MSS_QDSP6V5=y
+CONFIG_ICNSS=y
+CONFIG_MSM_PERFORMANCE=y
+CONFIG_MSM_EVENT_TIMER=y
+CONFIG_MSM_PM=y
+CONFIG_QTI_RPM_STATS_LOG=y
+CONFIG_QCOM_FORCE_WDOG_BITE_ON_PANIC=y
+CONFIG_PWM=y
+CONFIG_PWM_QPNP=y
+CONFIG_ARM_GIC_V3_ACL=y
+CONFIG_ANDROID=y
+CONFIG_ANDROID_BINDER_IPC=y
+CONFIG_SENSORS_SSC=y
+CONFIG_MSM_TZ_LOG=y
+CONFIG_QUOTA=y
+CONFIG_QUOTA_NETLINK_INTERFACE=y
+CONFIG_FUSE_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_ECRYPT_FS=y
+CONFIG_ECRYPT_FS_MESSAGING=y
+# CONFIG_NETWORK_FILESYSTEMS is not set
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_PRINTK_TIME=y
+CONFIG_DEBUG_INFO=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_PANIC_TIMEOUT=5
+CONFIG_SCHEDSTATS=y
+# CONFIG_DEBUG_PREEMPT is not set
+CONFIG_IPC_LOGGING=y
+CONFIG_CPU_FREQ_SWITCH_PROFILER=y
+CONFIG_DEBUG_ALIGN_RODATA=y
+CONFIG_CORESIGHT=y
+CONFIG_CORESIGHT_STM=y
+CONFIG_CORESIGHT_EVENT=y
+CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y
+CONFIG_SECURITY=y
+CONFIG_HARDENED_USERCOPY=y
+CONFIG_SECURITY_SELINUX=y
+CONFIG_SECURITY_SMACK=y
+CONFIG_CRYPTO_CTR=y
+CONFIG_CRYPTO_XCBC=y
+CONFIG_CRYPTO_MD4=y
+CONFIG_CRYPTO_TWOFISH=y
+CONFIG_CRYPTO_ANSI_CPRNG=y
+CONFIG_CRYPTO_DEV_QCOM_MSM_QCE=y
+CONFIG_CRYPTO_DEV_QCRYPTO=y
+CONFIG_CRYPTO_DEV_QCEDEV=y
+CONFIG_CRYPTO_DEV_QCOM_ICE=y
+CONFIG_ARM64_CRYPTO=y
+CONFIG_CRYPTO_SHA1_ARM64_CE=y
+CONFIG_CRYPTO_SHA2_ARM64_CE=y
+CONFIG_CRYPTO_GHASH_ARM64_CE=y
+CONFIG_CRYPTO_AES_ARM64_CE_CCM=y
+CONFIG_CRYPTO_AES_ARM64_CE_BLK=y
+CONFIG_CRYPTO_AES_ARM64_NEON_BLK=y
+CONFIG_CRYPTO_CRC32_ARM64=y
+CONFIG_QMI_ENCDEC=y
diff --git a/arch/arm64/configs/msm8953_defconfig b/arch/arm64/configs/msm8953_defconfig
new file mode 100644
index 0000000..8b5c2ea
--- /dev/null
+++ b/arch/arm64/configs/msm8953_defconfig
@@ -0,0 +1,544 @@
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_FHANDLE is not set
+CONFIG_AUDIT=y
+# CONFIG_AUDITSYSCALL is not set
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_IRQ_TIME_ACCOUNTING=y
+CONFIG_SCHED_WALT=y
+CONFIG_TASKSTATS=y
+CONFIG_TASK_DELAY_ACCT=y
+CONFIG_TASK_XACCT=y
+CONFIG_TASK_IO_ACCOUNTING=y
+CONFIG_RCU_EXPERT=y
+CONFIG_RCU_FAST_NO_HZ=y
+CONFIG_RCU_NOCB_CPU=y
+CONFIG_RCU_NOCB_CPU_ALL=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_CPU_MAX_BUF_SHIFT=17
+CONFIG_CGROUP_DEBUG=y
+CONFIG_CGROUP_FREEZER=y
+CONFIG_CPUSETS=y
+CONFIG_CGROUP_CPUACCT=y
+CONFIG_CGROUP_SCHEDTUNE=y
+CONFIG_RT_GROUP_SCHED=y
+CONFIG_CGROUP_BPF=y
+CONFIG_SCHED_CORE_CTL=y
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_PID_NS is not set
+CONFIG_SCHED_AUTOGROUP=y
+CONFIG_SCHED_TUNE=y
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_RD_XZ is not set
+# CONFIG_RD_LZO is not set
+# CONFIG_RD_LZ4 is not set
+CONFIG_KALLSYMS_ALL=y
+CONFIG_BPF_SYSCALL=y
+# CONFIG_AIO is not set
+# CONFIG_MEMBARRIER is not set
+CONFIG_EMBEDDED=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_PROFILING=y
+CONFIG_CC_STACKPROTECTOR_STRONG=y
+CONFIG_ARCH_MMAP_RND_COMPAT_BITS=16
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SIG=y
+CONFIG_MODULE_SIG_FORCE=y
+CONFIG_MODULE_SIG_SHA512=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_IOSCHED_DEADLINE is not set
+CONFIG_ARCH_QCOM=y
+CONFIG_ARCH_MSM8953=y
+CONFIG_SCHED_MC=y
+CONFIG_NR_CPUS=8
+CONFIG_PREEMPT=y
+CONFIG_HZ_100=y
+CONFIG_CLEANCACHE=y
+CONFIG_CMA=y
+CONFIG_CMA_DEBUGFS=y
+CONFIG_ZSMALLOC=y
+CONFIG_BALANCE_ANON_FILE_RECLAIM=y
+CONFIG_SECCOMP=y
+CONFIG_ARMV8_DEPRECATED=y
+CONFIG_SWP_EMULATION=y
+CONFIG_CP15_BARRIER_EMULATION=y
+CONFIG_SETEND_EMULATION=y
+# CONFIG_ARM64_VHE is not set
+CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_COMPAT=y
+CONFIG_PM_AUTOSLEEP=y
+CONFIG_PM_WAKELOCKS=y
+CONFIG_PM_WAKELOCKS_LIMIT=0
+# CONFIG_PM_WAKELOCKS_GC is not set
+CONFIG_PM_DEBUG=y
+CONFIG_CPU_IDLE=y
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
+CONFIG_CPU_BOOST=y
+CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_XFRM_USER=y
+CONFIG_XFRM_STATISTICS=y
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_INET_AH=y
+CONFIG_INET_ESP=y
+CONFIG_INET_IPCOMP=y
+CONFIG_INET_DIAG_DESTROY=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_ROUTE_INFO=y
+CONFIG_IPV6_OPTIMISTIC_DAD=y
+CONFIG_INET6_AH=y
+CONFIG_INET6_ESP=y
+CONFIG_INET6_IPCOMP=y
+CONFIG_IPV6_MIP6=y
+CONFIG_IPV6_MULTIPLE_TABLES=y
+CONFIG_IPV6_SUBTREES=y
+CONFIG_NETFILTER=y
+CONFIG_NF_CONNTRACK=y
+CONFIG_NF_CONNTRACK_SECMARK=y
+CONFIG_NF_CONNTRACK_EVENTS=y
+CONFIG_NF_CT_PROTO_DCCP=y
+CONFIG_NF_CT_PROTO_SCTP=y
+CONFIG_NF_CT_PROTO_UDPLITE=y
+CONFIG_NF_CONNTRACK_AMANDA=y
+CONFIG_NF_CONNTRACK_FTP=y
+CONFIG_NF_CONNTRACK_H323=y
+CONFIG_NF_CONNTRACK_IRC=y
+CONFIG_NF_CONNTRACK_NETBIOS_NS=y
+CONFIG_NF_CONNTRACK_PPTP=y
+CONFIG_NF_CONNTRACK_SANE=y
+CONFIG_NF_CONNTRACK_TFTP=y
+CONFIG_NF_CT_NETLINK=y
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=y
+CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=y
+CONFIG_NETFILTER_XT_TARGET_IDLETIMER=y
+CONFIG_NETFILTER_XT_TARGET_HARDIDLETIMER=y
+CONFIG_NETFILTER_XT_TARGET_LOG=y
+CONFIG_NETFILTER_XT_TARGET_MARK=y
+CONFIG_NETFILTER_XT_TARGET_NFLOG=y
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y
+CONFIG_NETFILTER_XT_TARGET_NOTRACK=y
+CONFIG_NETFILTER_XT_TARGET_TEE=y
+CONFIG_NETFILTER_XT_TARGET_TPROXY=y
+CONFIG_NETFILTER_XT_TARGET_TRACE=y
+CONFIG_NETFILTER_XT_TARGET_SECMARK=y
+CONFIG_NETFILTER_XT_TARGET_TCPMSS=y
+CONFIG_NETFILTER_XT_MATCH_COMMENT=y
+CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=y
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
+CONFIG_NETFILTER_XT_MATCH_DSCP=y
+CONFIG_NETFILTER_XT_MATCH_ESP=y
+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=y
+CONFIG_NETFILTER_XT_MATCH_HELPER=y
+CONFIG_NETFILTER_XT_MATCH_IPRANGE=y
+# CONFIG_NETFILTER_XT_MATCH_L2TP is not set
+CONFIG_NETFILTER_XT_MATCH_LENGTH=y
+CONFIG_NETFILTER_XT_MATCH_LIMIT=y
+CONFIG_NETFILTER_XT_MATCH_MAC=y
+CONFIG_NETFILTER_XT_MATCH_MARK=y
+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=y
+CONFIG_NETFILTER_XT_MATCH_POLICY=y
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y
+CONFIG_NETFILTER_XT_MATCH_QTAGUID=y
+CONFIG_NETFILTER_XT_MATCH_QUOTA=y
+CONFIG_NETFILTER_XT_MATCH_QUOTA2=y
+CONFIG_NETFILTER_XT_MATCH_SOCKET=y
+CONFIG_NETFILTER_XT_MATCH_STATE=y
+CONFIG_NETFILTER_XT_MATCH_STATISTIC=y
+CONFIG_NETFILTER_XT_MATCH_STRING=y
+CONFIG_NETFILTER_XT_MATCH_TIME=y
+CONFIG_NETFILTER_XT_MATCH_U32=y
+CONFIG_NF_CONNTRACK_IPV4=y
+CONFIG_IP_NF_IPTABLES=y
+CONFIG_IP_NF_MATCH_AH=y
+CONFIG_IP_NF_MATCH_ECN=y
+CONFIG_IP_NF_MATCH_RPFILTER=y
+CONFIG_IP_NF_MATCH_TTL=y
+CONFIG_IP_NF_FILTER=y
+CONFIG_IP_NF_TARGET_REJECT=y
+CONFIG_IP_NF_NAT=y
+CONFIG_IP_NF_TARGET_MASQUERADE=y
+CONFIG_IP_NF_TARGET_NETMAP=y
+CONFIG_IP_NF_TARGET_REDIRECT=y
+CONFIG_IP_NF_MANGLE=y
+CONFIG_IP_NF_RAW=y
+CONFIG_IP_NF_SECURITY=y
+CONFIG_IP_NF_ARPTABLES=y
+CONFIG_IP_NF_ARPFILTER=y
+CONFIG_IP_NF_ARP_MANGLE=y
+CONFIG_NF_CONNTRACK_IPV6=y
+CONFIG_IP6_NF_IPTABLES=y
+CONFIG_IP6_NF_MATCH_RPFILTER=y
+CONFIG_IP6_NF_FILTER=y
+CONFIG_IP6_NF_TARGET_REJECT=y
+CONFIG_IP6_NF_MANGLE=y
+CONFIG_IP6_NF_RAW=y
+CONFIG_BRIDGE_NF_EBTABLES=y
+CONFIG_BRIDGE_EBT_BROUTE=y
+CONFIG_L2TP=y
+CONFIG_L2TP_DEBUGFS=y
+CONFIG_L2TP_V3=y
+CONFIG_L2TP_IP=y
+CONFIG_L2TP_ETH=y
+CONFIG_BRIDGE=y
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_HTB=y
+CONFIG_NET_SCH_PRIO=y
+CONFIG_NET_SCH_MULTIQ=y
+CONFIG_NET_SCH_INGRESS=y
+CONFIG_NET_CLS_FW=y
+CONFIG_NET_CLS_U32=y
+CONFIG_CLS_U32_MARK=y
+CONFIG_NET_CLS_FLOW=y
+CONFIG_NET_EMATCH=y
+CONFIG_NET_EMATCH_CMP=y
+CONFIG_NET_EMATCH_NBYTE=y
+CONFIG_NET_EMATCH_U32=y
+CONFIG_NET_EMATCH_META=y
+CONFIG_NET_EMATCH_TEXT=y
+CONFIG_NET_CLS_ACT=y
+CONFIG_NET_ACT_GACT=y
+CONFIG_NET_ACT_MIRRED=y
+CONFIG_NET_ACT_SKBEDIT=y
+CONFIG_DNS_RESOLVER=y
+CONFIG_RMNET_DATA=y
+CONFIG_RMNET_DATA_FC=y
+CONFIG_RMNET_DATA_DEBUG_PKT=y
+CONFIG_BT=y
+CONFIG_MSM_BT_POWER=y
+CONFIG_CFG80211=y
+CONFIG_CFG80211_INTERNAL_REGDB=y
+# CONFIG_CFG80211_CRDA_SUPPORT is not set
+CONFIG_RFKILL=y
+CONFIG_NFC_NQ=y
+CONFIG_IPC_ROUTER=y
+CONFIG_IPC_ROUTER_SECURITY=y
+CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y
+CONFIG_DMA_CMA=y
+CONFIG_ZRAM=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_QSEECOM=y
+CONFIG_UID_SYS_STATS=y
+CONFIG_MEMORY_STATE_TIME=y
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_SG=y
+CONFIG_CHR_DEV_SCH=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+CONFIG_SCSI_SCAN_ASYNC=y
+CONFIG_SCSI_UFSHCD=y
+CONFIG_SCSI_UFSHCD_PLATFORM=y
+CONFIG_SCSI_UFS_QCOM=y
+CONFIG_SCSI_UFS_QCOM_ICE=y
+CONFIG_SCSI_UFSHCD_CMD_LOGGING=y
+CONFIG_MD=y
+CONFIG_BLK_DEV_DM=y
+CONFIG_DM_DEBUG=y
+CONFIG_DM_CRYPT=y
+CONFIG_DM_REQ_CRYPT=y
+CONFIG_DM_UEVENT=y
+CONFIG_DM_VERITY=y
+CONFIG_DM_VERITY_FEC=y
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=y
+CONFIG_TUN=y
+CONFIG_PPP=y
+CONFIG_PPP_BSDCOMP=y
+CONFIG_PPP_DEFLATE=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_MPPE=y
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPPOE=y
+CONFIG_PPPOL2TP=y
+CONFIG_PPPOLAC=y
+CONFIG_PPPOPNS=y
+CONFIG_PPP_ASYNC=y
+CONFIG_PPP_SYNC_TTY=y
+CONFIG_WCNSS_MEM_PRE_ALLOC=y
+CONFIG_CLD_LL_CORE=y
+CONFIG_INPUT_EVDEV=y
+CONFIG_KEYBOARD_GPIO=y
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_JOYSTICK=y
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_HBTP_INPUT=y
+CONFIG_INPUT_UINPUT=y
+# CONFIG_SERIO_SERPORT is not set
+# CONFIG_VT is not set
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_SERIAL_MSM=y
+CONFIG_SERIAL_MSM_CONSOLE=y
+CONFIG_HW_RANDOM=y
+CONFIG_HW_RANDOM_MSM_LEGACY=y
+CONFIG_MSM_ADSPRPC=y
+CONFIG_MSM_RDBG=m
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_QCOM_GENI=y
+CONFIG_SPI=y
+CONFIG_SPI_QUP=y
+CONFIG_SPI_QCOM_GENI=y
+CONFIG_SPI_SPIDEV=y
+CONFIG_SLIMBUS_MSM_NGD=y
+CONFIG_SPMI=y
+CONFIG_SPMI_MSM_PMIC_ARB_DEBUG=y
+CONFIG_PINCTRL_MSM8953=y
+CONFIG_PINCTRL_QCOM_SPMI_PMIC=y
+CONFIG_GPIOLIB=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_POWER_RESET_QCOM=y
+CONFIG_QCOM_DLOAD_MODE=y
+CONFIG_POWER_RESET_XGENE=y
+CONFIG_POWER_RESET_SYSCON=y
+CONFIG_SENSORS_QPNP_ADC_VOLTAGE=y
+CONFIG_THERMAL=y
+CONFIG_THERMAL_QPNP=y
+CONFIG_THERMAL_QPNP_ADC_TM=y
+CONFIG_THERMAL_TSENS=y
+CONFIG_MSM_BCL_PERIPHERAL_CTL=y
+CONFIG_QTI_THERMAL_LIMITS_DCVS=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_REGULATOR_CPRH_KBSS=y
+CONFIG_REGULATOR_QPNP_LABIBB=y
+CONFIG_REGULATOR_QPNP=y
+CONFIG_REGULATOR_STUB=y
+CONFIG_MEDIA_SUPPORT=y
+CONFIG_MEDIA_CAMERA_SUPPORT=y
+CONFIG_MEDIA_CONTROLLER=y
+CONFIG_VIDEO_V4L2_SUBDEV_API=y
+CONFIG_V4L_PLATFORM_DRIVERS=y
+CONFIG_MSM_VIDC_V4L2=y
+CONFIG_MSM_VIDC_GOVERNORS=y
+CONFIG_MSM_SDE_ROTATOR=y
+CONFIG_MSM_SDE_ROTATOR_EVTLOG_DEBUG=y
+CONFIG_QCOM_KGSL=y
+CONFIG_DRM=y
+CONFIG_DRM_SDE_EVTLOG_DEBUG=y
+CONFIG_DRM_SDE_RSC=y
+CONFIG_FB_VIRTUAL=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_DYNAMIC_MINORS=y
+CONFIG_SND_SOC=y
+CONFIG_UHID=y
+CONFIG_HID_APPLE=y
+CONFIG_HID_ELECOM=y
+CONFIG_HID_MAGICMOUSE=y
+CONFIG_HID_MICROSOFT=y
+CONFIG_HID_MULTITOUCH=y
+CONFIG_USB_DWC3=y
+CONFIG_NOP_USB_XCEIV=y
+CONFIG_DUAL_ROLE_USB_INTF=y
+CONFIG_USB_MSM_SSPHY_QMP=y
+CONFIG_MSM_QUSB_PHY=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET_DEBUG_FILES=y
+CONFIG_USB_GADGET_DEBUG_FS=y
+CONFIG_USB_GADGET_VBUS_DRAW=500
+CONFIG_MMC=y
+CONFIG_MMC_PERF_PROFILING=y
+CONFIG_MMC_RING_BUFFER=y
+CONFIG_MMC_PARANOID_SD_INIT=y
+CONFIG_MMC_CLKGATE=y
+CONFIG_MMC_BLOCK_MINORS=32
+CONFIG_MMC_BLOCK_DEFERRED_RESUME=y
+CONFIG_MMC_TEST=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_SDHCI_MSM=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_QPNP=y
+CONFIG_LEDS_QPNP_WLED=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_EDAC=y
+CONFIG_EDAC_MM_EDAC=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_QPNP=y
+CONFIG_DMADEVICES=y
+CONFIG_QCOM_SPS_DMA=y
+CONFIG_UIO=y
+CONFIG_UIO_MSM_SHAREDMEM=y
+CONFIG_STAGING=y
+CONFIG_ASHMEM=y
+CONFIG_ANDROID_LOW_MEMORY_KILLER=y
+CONFIG_ION=y
+CONFIG_ION_MSM=y
+CONFIG_GSI=y
+CONFIG_IPA3=y
+CONFIG_RMNET_IPA3=y
+CONFIG_RNDIS_IPA=y
+CONFIG_SPS=y
+CONFIG_SPS_SUPPORT_NDP_BAM=y
+CONFIG_QPNP_COINCELL=y
+CONFIG_QPNP_REVID=y
+CONFIG_USB_BAM=y
+CONFIG_QCOM_MDSS_PLL=y
+CONFIG_REMOTE_SPINLOCK_MSM=y
+CONFIG_ARM_SMMU=y
+CONFIG_IOMMU_DEBUG=y
+CONFIG_IOMMU_DEBUG_TRACKING=y
+CONFIG_IOMMU_TESTS=y
+CONFIG_MSM_BOOT_STATS=y
+CONFIG_MSM_CORE_HANG_DETECT=y
+CONFIG_MSM_GLADIATOR_HANG_DETECT=y
+CONFIG_QCOM_EUD=y
+CONFIG_QCOM_WATCHDOG_V2=y
+CONFIG_QCOM_MEMORY_DUMP_V2=y
+CONFIG_QCOM_SECURE_BUFFER=y
+CONFIG_QCOM_EARLY_RANDOM=y
+CONFIG_MSM_SMEM=y
+CONFIG_MSM_GLINK=y
+CONFIG_MSM_GLINK_LOOPBACK_SERVER=y
+CONFIG_MSM_GLINK_SMEM_NATIVE_XPRT=y
+CONFIG_MSM_GLINK_SPI_XPRT=y
+CONFIG_TRACER_PKT=y
+CONFIG_MSM_SMP2P=y
+CONFIG_MSM_SMP2P_TEST=y
+CONFIG_MSM_IPC_ROUTER_GLINK_XPRT=y
+CONFIG_MSM_QMI_INTERFACE=y
+CONFIG_MSM_GLINK_PKT=y
+CONFIG_MSM_SUBSYSTEM_RESTART=y
+CONFIG_MSM_PIL=y
+CONFIG_MSM_PIL_SSR_GENERIC=y
+CONFIG_MSM_PIL_MSS_QDSP6V5=y
+CONFIG_ICNSS=y
+CONFIG_MSM_PERFORMANCE=y
+CONFIG_MSM_EVENT_TIMER=y
+CONFIG_MSM_PM=y
+CONFIG_QTI_RPM_STATS_LOG=y
+CONFIG_QCOM_FORCE_WDOG_BITE_ON_PANIC=y
+CONFIG_PWM=y
+CONFIG_PWM_QPNP=y
+CONFIG_ARM_GIC_V3_ACL=y
+CONFIG_ANDROID=y
+CONFIG_ANDROID_BINDER_IPC=y
+CONFIG_SENSORS_SSC=y
+CONFIG_MSM_TZ_LOG=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT3_FS=y
+CONFIG_EXT4_FS_SECURITY=y
+CONFIG_QUOTA=y
+CONFIG_QUOTA_NETLINK_INTERFACE=y
+CONFIG_FUSE_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_ECRYPT_FS=y
+CONFIG_ECRYPT_FS_MESSAGING=y
+# CONFIG_NETWORK_FILESYSTEMS is not set
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_PRINTK_TIME=y
+CONFIG_DYNAMIC_DEBUG=y
+CONFIG_DEBUG_INFO=y
+CONFIG_PAGE_OWNER=y
+CONFIG_PAGE_OWNER_ENABLE_DEFAULT=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_PAGEALLOC=y
+CONFIG_SLUB_DEBUG_PANIC_ON=y
+CONFIG_DEBUG_PAGEALLOC_ENABLE_DEFAULT=y
+CONFIG_PAGE_POISONING=y
+CONFIG_DEBUG_OBJECTS=y
+CONFIG_DEBUG_OBJECTS_FREE=y
+CONFIG_DEBUG_OBJECTS_TIMERS=y
+CONFIG_DEBUG_OBJECTS_WORK=y
+CONFIG_DEBUG_OBJECTS_RCU_HEAD=y
+CONFIG_DEBUG_OBJECTS_PERCPU_COUNTER=y
+CONFIG_SLUB_DEBUG_ON=y
+CONFIG_DEBUG_KMEMLEAK=y
+CONFIG_DEBUG_KMEMLEAK_EARLY_LOG_SIZE=4000
+CONFIG_DEBUG_KMEMLEAK_DEFAULT_OFF=y
+CONFIG_DEBUG_STACK_USAGE=y
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_LOCKUP_DETECTOR=y
+CONFIG_WQ_WATCHDOG=y
+CONFIG_PANIC_TIMEOUT=5
+CONFIG_PANIC_ON_SCHED_BUG=y
+CONFIG_PANIC_ON_RT_THROTTLING=y
+CONFIG_SCHEDSTATS=y
+CONFIG_SCHED_STACK_END_CHECK=y
+# CONFIG_DEBUG_PREEMPT is not set
+CONFIG_DEBUG_SPINLOCK=y
+CONFIG_DEBUG_MUTEXES=y
+CONFIG_DEBUG_ATOMIC_SLEEP=y
+CONFIG_DEBUG_LIST=y
+CONFIG_FAULT_INJECTION=y
+CONFIG_FAIL_PAGE_ALLOC=y
+CONFIG_FAULT_INJECTION_DEBUG_FS=y
+CONFIG_FAULT_INJECTION_STACKTRACE_FILTER=y
+CONFIG_IPC_LOGGING=y
+CONFIG_QCOM_RTB=y
+CONFIG_QCOM_RTB_SEPARATE_CPUS=y
+CONFIG_FUNCTION_TRACER=y
+CONFIG_IRQSOFF_TRACER=y
+CONFIG_PREEMPT_TRACER=y
+CONFIG_BLK_DEV_IO_TRACE=y
+CONFIG_CPU_FREQ_SWITCH_PROFILER=y
+CONFIG_LKDTM=y
+CONFIG_MEMTEST=y
+CONFIG_PANIC_ON_DATA_CORRUPTION=y
+CONFIG_ARM64_PTDUMP=y
+CONFIG_PID_IN_CONTEXTIDR=y
+CONFIG_CORESIGHT=y
+CONFIG_CORESIGHT_REMOTE_ETM=y
+CONFIG_CORESIGHT_REMOTE_ETM_DEFAULT_ENABLE=0
+CONFIG_CORESIGHT_STM=y
+CONFIG_CORESIGHT_TPDA=y
+CONFIG_CORESIGHT_TPDM=y
+CONFIG_CORESIGHT_CTI=y
+CONFIG_CORESIGHT_EVENT=y
+CONFIG_CORESIGHT_HWEVENT=y
+CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y
+CONFIG_SECURITY=y
+CONFIG_HARDENED_USERCOPY=y
+CONFIG_SECURITY_SELINUX=y
+CONFIG_SECURITY_SMACK=y
+CONFIG_CRYPTO_CTR=y
+CONFIG_CRYPTO_XCBC=y
+CONFIG_CRYPTO_MD4=y
+CONFIG_CRYPTO_TWOFISH=y
+CONFIG_CRYPTO_ANSI_CPRNG=y
+CONFIG_CRYPTO_DEV_QCOM_MSM_QCE=y
+CONFIG_CRYPTO_DEV_QCRYPTO=y
+CONFIG_CRYPTO_DEV_QCEDEV=y
+CONFIG_CRYPTO_DEV_QCOM_ICE=y
+CONFIG_ARM64_CRYPTO=y
+CONFIG_CRYPTO_SHA1_ARM64_CE=y
+CONFIG_CRYPTO_SHA2_ARM64_CE=y
+CONFIG_CRYPTO_GHASH_ARM64_CE=y
+CONFIG_CRYPTO_AES_ARM64_CE_CCM=y
+CONFIG_CRYPTO_AES_ARM64_CE_BLK=y
+CONFIG_CRYPTO_AES_ARM64_NEON_BLK=y
+CONFIG_CRYPTO_CRC32_ARM64=y
+CONFIG_QMI_ENCDEC=y
diff --git a/arch/arm64/configs/sdm670-perf_defconfig b/arch/arm64/configs/sdm670-perf_defconfig
index dc09f04..cd393c2 100644
--- a/arch/arm64/configs/sdm670-perf_defconfig
+++ b/arch/arm64/configs/sdm670-perf_defconfig
@@ -335,6 +335,7 @@
CONFIG_REGULATOR_QPNP_LCDB=y
CONFIG_REGULATOR_QPNP_OLEDB=y
CONFIG_REGULATOR_QPNP=y
+CONFIG_REGULATOR_REFGEN=y
CONFIG_REGULATOR_RPMH=y
CONFIG_REGULATOR_STUB=y
CONFIG_MEDIA_SUPPORT=y
diff --git a/arch/arm64/configs/sdm670_defconfig b/arch/arm64/configs/sdm670_defconfig
index 79bb308..17231c7 100644
--- a/arch/arm64/configs/sdm670_defconfig
+++ b/arch/arm64/configs/sdm670_defconfig
@@ -342,6 +342,7 @@
CONFIG_REGULATOR_QPNP_LCDB=y
CONFIG_REGULATOR_QPNP_OLEDB=y
CONFIG_REGULATOR_QPNP=y
+CONFIG_REGULATOR_REFGEN=y
CONFIG_REGULATOR_RPMH=y
CONFIG_REGULATOR_STUB=y
CONFIG_MEDIA_SUPPORT=y
diff --git a/arch/arm64/configs/sdm845_defconfig b/arch/arm64/configs/sdm845_defconfig
index 7655c91..edf67c7 100644
--- a/arch/arm64/configs/sdm845_defconfig
+++ b/arch/arm64/configs/sdm845_defconfig
@@ -455,9 +455,6 @@
CONFIG_EDAC_KRYO3XX_ARM64=y
CONFIG_EDAC_KRYO3XX_ARM64_PANIC_ON_CE=y
CONFIG_EDAC_KRYO3XX_ARM64_PANIC_ON_UE=y
-CONFIG_EDAC_QCOM_LLCC=y
-CONFIG_EDAC_QCOM_LLCC_PANIC_ON_CE=y
-CONFIG_EDAC_QCOM_LLCC_PANIC_ON_UE=y
CONFIG_RTC_CLASS=y
CONFIG_RTC_DRV_QPNP=y
CONFIG_DMADEVICES=y
diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
index 5edb6ed..f3a142e 100644
--- a/arch/arm64/include/asm/memory.h
+++ b/arch/arm64/include/asm/memory.h
@@ -165,6 +165,11 @@
/* the offset between the kernel virtual and physical mappings */
extern u64 kimage_voffset;
+static inline unsigned long kaslr_offset(void)
+{
+ return kimage_vaddr - KIMAGE_VADDR;
+}
+
/*
* Allow all memory at the discovery stage. We will clip it later.
*/
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index ba29095..a58fb92 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -356,11 +356,11 @@
static int dump_kernel_offset(struct notifier_block *self, unsigned long v,
void *p)
{
- u64 const kaslr_offset = kimage_vaddr - KIMAGE_VADDR;
+ const unsigned long offset = kaslr_offset();
- if (IS_ENABLED(CONFIG_RANDOMIZE_BASE) && kaslr_offset > 0) {
- pr_emerg("Kernel Offset: 0x%llx from 0x%lx\n",
- kaslr_offset, KIMAGE_VADDR);
+ if (IS_ENABLED(CONFIG_RANDOMIZE_BASE) && offset > 0) {
+ pr_emerg("Kernel Offset: 0x%lx from 0x%lx\n",
+ offset, KIMAGE_VADDR);
} else {
pr_emerg("Kernel Offset: disabled\n");
}
diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h
index 0cea702..d33f245 100644
--- a/arch/s390/include/asm/pgtable.h
+++ b/arch/s390/include/asm/pgtable.h
@@ -480,7 +480,7 @@
* In the case that a guest uses storage keys
* faults should no longer be backed by zero pages
*/
-#define mm_forbids_zeropage mm_use_skey
+#define mm_forbids_zeropage mm_has_pgste
static inline int mm_use_skey(struct mm_struct *mm)
{
#ifdef CONFIG_PGSTE
diff --git a/arch/s390/mm/gmap.c b/arch/s390/mm/gmap.c
index 3ba6227..cb2cd04 100644
--- a/arch/s390/mm/gmap.c
+++ b/arch/s390/mm/gmap.c
@@ -2125,6 +2125,37 @@
}
/*
+ * Remove all empty zero pages from the mapping for lazy refaulting
+ * - This must be called after mm->context.has_pgste is set, to avoid
+ * future creation of zero pages
+ * - This must be called after THP was enabled
+ */
+static int __zap_zero_pages(pmd_t *pmd, unsigned long start,
+ unsigned long end, struct mm_walk *walk)
+{
+ unsigned long addr;
+
+ for (addr = start; addr != end; addr += PAGE_SIZE) {
+ pte_t *ptep;
+ spinlock_t *ptl;
+
+ ptep = pte_offset_map_lock(walk->mm, pmd, addr, &ptl);
+ if (is_zero_pfn(pte_pfn(*ptep)))
+ ptep_xchg_direct(walk->mm, addr, ptep, __pte(_PAGE_INVALID));
+ pte_unmap_unlock(ptep, ptl);
+ }
+ return 0;
+}
+
+static inline void zap_zero_pages(struct mm_struct *mm)
+{
+ struct mm_walk walk = { .pmd_entry = __zap_zero_pages };
+
+ walk.mm = mm;
+ walk_page_range(0, TASK_SIZE, &walk);
+}
+
+/*
* switch on pgstes for its userspace process (for kvm)
*/
int s390_enable_sie(void)
@@ -2141,6 +2172,7 @@
mm->context.has_pgste = 1;
/* split thp mappings and disable thp for future mappings */
thp_split_mm(mm);
+ zap_zero_pages(mm);
up_write(&mm->mmap_sem);
return 0;
}
@@ -2153,13 +2185,6 @@
static int __s390_enable_skey(pte_t *pte, unsigned long addr,
unsigned long next, struct mm_walk *walk)
{
- /*
- * Remove all zero page mappings,
- * after establishing a policy to forbid zero page mappings
- * following faults for that page will get fresh anonymous pages
- */
- if (is_zero_pfn(pte_pfn(*pte)))
- ptep_xchg_direct(walk->mm, addr, pte, __pte(_PAGE_INVALID));
/* Clear storage key */
ptep_zap_key(walk->mm, addr, pte);
return 0;
diff --git a/drivers/ata/pata_amd.c b/drivers/ata/pata_amd.c
index 8d4d959..8706533 100644
--- a/drivers/ata/pata_amd.c
+++ b/drivers/ata/pata_amd.c
@@ -616,6 +616,7 @@
{ PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP73_IDE), 8 },
{ PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP77_IDE), 8 },
{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_CS5536_IDE), 9 },
+ { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_CS5536_DEV_IDE), 9 },
{ },
};
diff --git a/drivers/ata/pata_cs5536.c b/drivers/ata/pata_cs5536.c
index 6c15a55..dc12552 100644
--- a/drivers/ata/pata_cs5536.c
+++ b/drivers/ata/pata_cs5536.c
@@ -289,6 +289,7 @@
static const struct pci_device_id cs5536[] = {
{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_CS5536_IDE), },
+ { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_CS5536_DEV_IDE), },
{ },
};
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index 6470eb8..e32a74e 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -736,7 +736,7 @@
out_unregister:
kobject_put(&priv->kobj);
- kfree(drv->p);
+ /* drv->p is freed in driver_release() */
drv->p = NULL;
out_put_bus:
bus_put(bus);
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index b0beb52..914433f 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -958,7 +958,7 @@
timeout = MAX_JIFFY_OFFSET;
}
- timeout = wait_for_completion_interruptible_timeout(&buf->completion,
+ timeout = wait_for_completion_killable_timeout(&buf->completion,
timeout);
if (timeout == -ERESTARTSYS || !timeout) {
retval = timeout;
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index dd220fa..74e677a 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -342,6 +342,7 @@
{ USB_DEVICE(0x13d3, 0x3410), .driver_info = BTUSB_REALTEK },
{ USB_DEVICE(0x13d3, 0x3416), .driver_info = BTUSB_REALTEK },
{ USB_DEVICE(0x13d3, 0x3459), .driver_info = BTUSB_REALTEK },
+ { USB_DEVICE(0x13d3, 0x3494), .driver_info = BTUSB_REALTEK },
/* Additional Realtek 8821AE Bluetooth devices */
{ USB_DEVICE(0x0b05, 0x17dc), .driver_info = BTUSB_REALTEK },
diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c
index 874639f..89bf7c6 100644
--- a/drivers/char/adsprpc.c
+++ b/drivers/char/adsprpc.c
@@ -1822,18 +1822,62 @@
{
}
+static int fastrpc_search_ctx(uint64_t rctx)
+{
+ struct fastrpc_apps *me = &gfa;
+ struct fastrpc_file *fl;
+ struct hlist_node *n, *m;
+ struct smq_invoke_ctx *ictx = NULL;
+ struct smq_invoke_ctx *ctx;
+ int bfound = 0;
+
+ ctx = (struct smq_invoke_ctx *)(uint64_to_ptr(rctx));
+ if (!ctx)
+ return bfound;
+
+ spin_lock(&me->hlock);
+ hlist_for_each_entry_safe(fl, n, &me->drivers, hn) {
+ if (ctx->fl != fl)
+ continue;
+ spin_lock(&fl->hlock);
+ hlist_for_each_entry_safe(ictx, m, &fl->clst.pending, hn) {
+ if (ptr_to_uint64(ictx) == rctx) {
+ bfound = 1;
+ break;
+ }
+ }
+ hlist_for_each_entry_safe(ictx, m, &fl->clst.interrupted, hn) {
+ if (ptr_to_uint64(ictx) == rctx) {
+ bfound = 1;
+ break;
+ }
+ }
+ spin_unlock(&fl->hlock);
+ if (bfound)
+ break;
+ }
+ spin_unlock(&me->hlock);
+ return bfound;
+}
+
void fastrpc_glink_notify_rx(void *handle, const void *priv,
const void *pkt_priv, const void *ptr, size_t size)
{
struct smq_invoke_rsp *rsp = (struct smq_invoke_rsp *)ptr;
- int len = size;
+ int bfound = 0;
- while (len >= sizeof(*rsp) && rsp) {
- rsp->ctx = rsp->ctx & ~1;
- context_notify_user(uint64_to_ptr(rsp->ctx), rsp->retval);
- rsp++;
- len = len - sizeof(*rsp);
+ if (!rsp || (size < sizeof(*rsp)))
+ goto bail;
+
+ bfound = fastrpc_search_ctx((uint64_t)(rsp->ctx & ~1));
+ if (!bfound) {
+ pr_err("adsprpc: invalid context %pK\n", (void *)rsp->ctx);
+ goto bail;
}
+
+ rsp->ctx = rsp->ctx & ~1;
+ context_notify_user(uint64_to_ptr(rsp->ctx), rsp->retval);
+bail:
glink_rx_done(handle, ptr, true);
}
@@ -1899,6 +1943,8 @@
return 0;
cid = fl->cid;
+ (void)fastrpc_release_current_dsp_process(fl);
+
spin_lock(&fl->apps->hlock);
hlist_del_init(&fl->hn);
spin_unlock(&fl->apps->hlock);
@@ -1907,7 +1953,6 @@
kfree(fl);
return 0;
}
- (void)fastrpc_release_current_dsp_process(fl);
spin_lock(&fl->hlock);
fl->file_close = 1;
spin_unlock(&fl->hlock);
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 5638333..4f2fb77 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -2712,9 +2712,10 @@
struct clk_core *core;
int cnt = 0;
- clock_debug_output(s, 0, "Enabled clocks:\n");
+ if (!mutex_trylock(&clk_debug_lock))
+ return;
- mutex_lock(&clk_debug_lock);
+ clock_debug_output(s, 0, "Enabled clocks:\n");
hlist_for_each_entry(core, &clk_debug_list, debug_node)
cnt += clock_debug_print_clock(core, s);
@@ -3037,14 +3038,19 @@
/*
* Print the names of all enabled clocks and their parents if
- * debug_suspend is set from debugfs.
+ * debug_suspend is set from debugfs along with print_parent flag set to 1.
+ * Otherwise if print_parent set to 0, print only enabled clocks
+ *
*/
-void clock_debug_print_enabled(void)
+void clock_debug_print_enabled(bool print_parent)
{
if (likely(!debug_suspend))
return;
- clock_debug_print_enabled_debug_suspend(NULL);
+ if (print_parent)
+ clock_debug_print_enabled_clocks(NULL);
+ else
+ clock_debug_print_enabled_debug_suspend(NULL);
}
EXPORT_SYMBOL_GPL(clock_debug_print_enabled);
diff --git a/drivers/clk/clk.h b/drivers/clk/clk.h
index b52aa25..a7d0981 100644
--- a/drivers/clk/clk.h
+++ b/drivers/clk/clk.h
@@ -23,7 +23,7 @@
void __clk_free_clk(struct clk *clk);
/* Debugfs API to print the enabled clocks */
-void clock_debug_print_enabled(void);
+void clock_debug_print_enabled(bool print_parent);
void clk_debug_print_hw(struct clk_core *clk, struct seq_file *f);
#else
diff --git a/drivers/cpuidle/lpm-levels.c b/drivers/cpuidle/lpm-levels.c
index 5d2e918..746cdc0 100644
--- a/drivers/cpuidle/lpm-levels.c
+++ b/drivers/cpuidle/lpm-levels.c
@@ -1606,7 +1606,7 @@
* clocks that are enabled and preventing the system level
* LPMs(XO and Vmin).
*/
- clock_debug_print_enabled();
+ clock_debug_print_enabled(true);
psci_enter_sleep(lpm_cpu, idx, false);
diff --git a/drivers/crypto/msm/qcedev.c b/drivers/crypto/msm/qcedev.c
index 2cf303e..94b3c17 100644
--- a/drivers/crypto/msm/qcedev.c
+++ b/drivers/crypto/msm/qcedev.c
@@ -340,8 +340,6 @@
if (authdata) {
handle->sha_ctxt.auth_data[0] = auth32[0];
handle->sha_ctxt.auth_data[1] = auth32[1];
- handle->sha_ctxt.auth_data[2] = auth32[2];
- handle->sha_ctxt.auth_data[3] = auth32[3];
}
tasklet_schedule(&pdev->done_tasklet);
diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h b/drivers/gpu/drm/bridge/adv7511/adv7511.h
index 161c923..3e74e1a 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511.h
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h
@@ -315,6 +315,8 @@
bool edid_read;
wait_queue_head_t wq;
+ struct work_struct hpd_work;
+
struct drm_bridge bridge;
struct drm_connector connector;
diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
index 8ed3906..213d892 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
@@ -402,6 +402,27 @@
return false;
}
+static void adv7511_hpd_work(struct work_struct *work)
+{
+ struct adv7511 *adv7511 = container_of(work, struct adv7511, hpd_work);
+ enum drm_connector_status status;
+ unsigned int val;
+ int ret;
+
+ ret = regmap_read(adv7511->regmap, ADV7511_REG_STATUS, &val);
+ if (ret < 0)
+ status = connector_status_disconnected;
+ else if (val & ADV7511_STATUS_HPD)
+ status = connector_status_connected;
+ else
+ status = connector_status_disconnected;
+
+ if (adv7511->connector.status != status) {
+ adv7511->connector.status = status;
+ drm_kms_helper_hotplug_event(adv7511->connector.dev);
+ }
+}
+
static int adv7511_irq_process(struct adv7511 *adv7511, bool process_hpd)
{
unsigned int irq0, irq1;
@@ -419,7 +440,7 @@
regmap_write(adv7511->regmap, ADV7511_REG_INT(1), irq1);
if (process_hpd && irq0 & ADV7511_INT0_HPD && adv7511->bridge.encoder)
- drm_helper_hpd_irq_event(adv7511->connector.dev);
+ schedule_work(&adv7511->hpd_work);
if (irq0 & ADV7511_INT0_EDID_READY || irq1 & ADV7511_INT1_DDC_ERROR) {
adv7511->edid_read = true;
@@ -1006,6 +1027,8 @@
goto err_i2c_unregister_edid;
}
+ INIT_WORK(&adv7511->hpd_work, adv7511_hpd_work);
+
if (i2c->irq) {
init_waitqueue_head(&adv7511->wq);
diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
index ac5437e..6394109 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -358,20 +358,13 @@
*/
int drm_dp_link_power_up(struct drm_dp_aux *aux, struct drm_dp_link *link)
{
- u8 value;
+ u8 value = DP_SET_POWER_D0;
int err;
/* DP_SET_POWER register is only available on DPCD v1.1 and later */
if (link->revision < 0x11)
return 0;
- err = drm_dp_dpcd_readb(aux, DP_SET_POWER, &value);
- if (err < 0)
- return err;
-
- value &= ~DP_SET_POWER_MASK;
- value |= DP_SET_POWER_D0;
-
err = drm_dp_dpcd_writeb(aux, DP_SET_POWER, value);
if (err < 0)
return err;
diff --git a/drivers/gpu/drm/msm/sde/sde_encoder.c b/drivers/gpu/drm/msm/sde/sde_encoder.c
index 270e677..e50bac1 100644
--- a/drivers/gpu/drm/msm/sde/sde_encoder.c
+++ b/drivers/gpu/drm/msm/sde/sde_encoder.c
@@ -1291,7 +1291,7 @@
}
break;
default:
- SDE_ERROR_ENC(sde_enc, "Unexpected topology:%d\n", topology);
+ SDE_DEBUG_ENC(sde_enc, "Unexpected topology:%d\n", topology);
return -EINVAL;
};
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c
index eb9b278..a4cb824 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c
@@ -192,6 +192,10 @@
}
}
+#ifdef __BIG_ENDIAN
+ pci->msi = false;
+#endif
+
pci->msi = nvkm_boolopt(device->cfgopt, "NvMSI", pci->msi);
if (pci->msi && func->msi_rearm) {
pci->msi = pci_enable_msi(pci->pdev) == 0;
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index 780cefe..7943745 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -2870,7 +2870,7 @@
gpu_busy += adj;
}
- if (kgsl_gmu_isenabled(device)) {
+ if (adreno_is_a6xx(adreno_dev)) {
/* clock sourced from XO */
stats->busy_time = gpu_busy * 10 / 192;
} else {
@@ -3091,6 +3091,7 @@
.irq_handler = adreno_irq_handler,
.drain = adreno_drain,
/* Optional functions */
+ .snapshot_gmu = adreno_snapshot_gmu,
.drawctxt_create = adreno_drawctxt_create,
.drawctxt_detach = adreno_drawctxt_detach,
.drawctxt_destroy = adreno_drawctxt_destroy,
diff --git a/drivers/gpu/msm/adreno.h b/drivers/gpu/msm/adreno.h
index 49dc5ed..8349a9f 100644
--- a/drivers/gpu/msm/adreno.h
+++ b/drivers/gpu/msm/adreno.h
@@ -621,6 +621,8 @@
ADRENO_REG_RBBM_RBBM_CTL,
ADRENO_REG_UCHE_INVALIDATE0,
ADRENO_REG_UCHE_INVALIDATE1,
+ ADRENO_REG_RBBM_PERFCTR_RBBM_0_LO,
+ ADRENO_REG_RBBM_PERFCTR_RBBM_0_HI,
ADRENO_REG_RBBM_PERFCTR_LOAD_VALUE_LO,
ADRENO_REG_RBBM_PERFCTR_LOAD_VALUE_HI,
ADRENO_REG_RBBM_SECVID_TRUST_CONTROL,
@@ -832,6 +834,7 @@
/* GPU specific function hooks */
void (*irq_trace)(struct adreno_device *, unsigned int status);
void (*snapshot)(struct adreno_device *, struct kgsl_snapshot *);
+ void (*snapshot_gmu)(struct adreno_device *, struct kgsl_snapshot *);
void (*platform_setup)(struct adreno_device *);
void (*init)(struct adreno_device *);
void (*remove)(struct adreno_device *);
@@ -1006,6 +1009,9 @@
struct kgsl_snapshot *snapshot,
struct kgsl_context *context);
+void adreno_snapshot_gmu(struct kgsl_device *device,
+ struct kgsl_snapshot *snapshot);
+
int adreno_reset(struct kgsl_device *device, int fault);
void adreno_fault_skipcmd_detached(struct adreno_device *adreno_dev,
@@ -1697,21 +1703,60 @@
spin_unlock_irqrestore(&rb->preempt_lock, flags);
}
+static inline bool is_power_counter_overflow(struct adreno_device *adreno_dev,
+ unsigned int reg, unsigned int prev_val, unsigned int *perfctr_pwr_hi)
+{
+ unsigned int val;
+ bool ret = false;
+
+ /*
+ * If prev_val is zero, it is first read after perf counter reset.
+ * So set perfctr_pwr_hi register to zero.
+ */
+ if (prev_val == 0) {
+ *perfctr_pwr_hi = 0;
+ return ret;
+ }
+ adreno_readreg(adreno_dev, ADRENO_REG_RBBM_PERFCTR_RBBM_0_HI, &val);
+ if (val != *perfctr_pwr_hi) {
+ *perfctr_pwr_hi = val;
+ ret = true;
+ }
+ return ret;
+}
+
static inline unsigned int counter_delta(struct kgsl_device *device,
unsigned int reg, unsigned int *counter)
{
+ struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
unsigned int val;
unsigned int ret = 0;
+ bool overflow = true;
+ static unsigned int perfctr_pwr_hi;
/* Read the value */
kgsl_regread(device, reg, &val);
+ if (adreno_is_a5xx(adreno_dev) && reg == adreno_getreg
+ (adreno_dev, ADRENO_REG_RBBM_PERFCTR_RBBM_0_LO))
+ overflow = is_power_counter_overflow(adreno_dev, reg,
+ *counter, &perfctr_pwr_hi);
+
/* Return 0 for the first read */
if (*counter != 0) {
- if (val < *counter)
- ret = (0xFFFFFFFF - *counter) + val;
- else
+ if (val >= *counter) {
ret = val - *counter;
+ } else if (overflow == true) {
+ ret = (0xFFFFFFFF - *counter) + val;
+ } else {
+ /*
+ * Since KGSL got abnormal value from the counter,
+ * We will drop the value from being accumulated.
+ */
+ pr_warn_once("KGSL: Abnormal value :0x%x (0x%x) from perf counter : 0x%x\n",
+ val, *counter, reg);
+ return 0;
+ }
}
*counter = val;
diff --git a/drivers/gpu/msm/adreno_a3xx.c b/drivers/gpu/msm/adreno_a3xx.c
index 356d7c2..b2cdf56 100644
--- a/drivers/gpu/msm/adreno_a3xx.c
+++ b/drivers/gpu/msm/adreno_a3xx.c
@@ -1533,6 +1533,10 @@
A3XX_UCHE_CACHE_INVALIDATE0_REG),
ADRENO_REG_DEFINE(ADRENO_REG_UCHE_INVALIDATE1,
A3XX_UCHE_CACHE_INVALIDATE1_REG),
+ ADRENO_REG_DEFINE(ADRENO_REG_RBBM_PERFCTR_RBBM_0_LO,
+ A3XX_RBBM_PERFCTR_RBBM_0_LO),
+ ADRENO_REG_DEFINE(ADRENO_REG_RBBM_PERFCTR_RBBM_0_HI,
+ A3XX_RBBM_PERFCTR_RBBM_0_HI),
ADRENO_REG_DEFINE(ADRENO_REG_RBBM_PERFCTR_LOAD_VALUE_LO,
A3XX_RBBM_PERFCTR_LOAD_VALUE_LO),
ADRENO_REG_DEFINE(ADRENO_REG_RBBM_PERFCTR_LOAD_VALUE_HI,
diff --git a/drivers/gpu/msm/adreno_a4xx.c b/drivers/gpu/msm/adreno_a4xx.c
index 0cf909e..80ceabd 100644
--- a/drivers/gpu/msm/adreno_a4xx.c
+++ b/drivers/gpu/msm/adreno_a4xx.c
@@ -808,6 +808,10 @@
ADRENO_REG_DEFINE(ADRENO_REG_RBBM_SW_RESET_CMD, A4XX_RBBM_SW_RESET_CMD),
ADRENO_REG_DEFINE(ADRENO_REG_UCHE_INVALIDATE0, A4XX_UCHE_INVALIDATE0),
ADRENO_REG_DEFINE(ADRENO_REG_UCHE_INVALIDATE1, A4XX_UCHE_INVALIDATE1),
+ ADRENO_REG_DEFINE(ADRENO_REG_RBBM_PERFCTR_RBBM_0_LO,
+ A4XX_RBBM_PERFCTR_RBBM_0_LO),
+ ADRENO_REG_DEFINE(ADRENO_REG_RBBM_PERFCTR_RBBM_0_HI,
+ A4XX_RBBM_PERFCTR_RBBM_0_HI),
ADRENO_REG_DEFINE(ADRENO_REG_RBBM_PERFCTR_LOAD_VALUE_LO,
A4XX_RBBM_PERFCTR_LOAD_VALUE_LO),
ADRENO_REG_DEFINE(ADRENO_REG_RBBM_PERFCTR_LOAD_VALUE_HI,
diff --git a/drivers/gpu/msm/adreno_a5xx.c b/drivers/gpu/msm/adreno_a5xx.c
index 6cddd08..2d078ba 100644
--- a/drivers/gpu/msm/adreno_a5xx.c
+++ b/drivers/gpu/msm/adreno_a5xx.c
@@ -2998,6 +2998,10 @@
ADRENO_REG_DEFINE(ADRENO_REG_RBBM_BLOCK_SW_RESET_CMD2,
A5XX_RBBM_BLOCK_SW_RESET_CMD2),
ADRENO_REG_DEFINE(ADRENO_REG_UCHE_INVALIDATE0, A5XX_UCHE_INVALIDATE0),
+ ADRENO_REG_DEFINE(ADRENO_REG_RBBM_PERFCTR_RBBM_0_LO,
+ A5XX_RBBM_PERFCTR_RBBM_0_LO),
+ ADRENO_REG_DEFINE(ADRENO_REG_RBBM_PERFCTR_RBBM_0_HI,
+ A5XX_RBBM_PERFCTR_RBBM_0_HI),
ADRENO_REG_DEFINE(ADRENO_REG_RBBM_PERFCTR_LOAD_VALUE_LO,
A5XX_RBBM_PERFCTR_LOAD_VALUE_LO),
ADRENO_REG_DEFINE(ADRENO_REG_RBBM_PERFCTR_LOAD_VALUE_HI,
diff --git a/drivers/gpu/msm/adreno_a5xx_snapshot.c b/drivers/gpu/msm/adreno_a5xx_snapshot.c
index 78b56bc..6dc62866 100644
--- a/drivers/gpu/msm/adreno_a5xx_snapshot.c
+++ b/drivers/gpu/msm/adreno_a5xx_snapshot.c
@@ -767,6 +767,8 @@
crash_dump_valid = false;
+ if (!device->snapshot_crashdumper)
+ return;
if (capturescript.gpuaddr == 0 || registers.gpuaddr == 0)
return;
@@ -872,8 +874,7 @@
ARRAY_SIZE(a5xx_vbif_snapshot_registers));
/* Try to run the crash dumper */
- if (device->snapshot_crashdumper)
- _a5xx_do_crashdump(device);
+ _a5xx_do_crashdump(device);
kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_REGS,
snapshot, a5xx_snapshot_registers, NULL);
diff --git a/drivers/gpu/msm/adreno_a6xx.c b/drivers/gpu/msm/adreno_a6xx.c
index b9df4ec..88c15eb 100644
--- a/drivers/gpu/msm/adreno_a6xx.c
+++ b/drivers/gpu/msm/adreno_a6xx.c
@@ -2915,6 +2915,7 @@
.reg_offsets = &a6xx_reg_offsets,
.start = a6xx_start,
.snapshot = a6xx_snapshot,
+ .snapshot_gmu = a6xx_snapshot_gmu,
.irq = &a6xx_irq,
.snapshot_data = &a6xx_snapshot_data,
.irq_trace = trace_kgsl_a5xx_irq_status,
diff --git a/drivers/gpu/msm/adreno_a6xx.h b/drivers/gpu/msm/adreno_a6xx.h
index ee2fd71..dd8af80 100644
--- a/drivers/gpu/msm/adreno_a6xx.h
+++ b/drivers/gpu/msm/adreno_a6xx.h
@@ -110,6 +110,8 @@
void a6xx_snapshot(struct adreno_device *adreno_dev,
struct kgsl_snapshot *snapshot);
+void a6xx_snapshot_gmu(struct adreno_device *adreno_dev,
+ struct kgsl_snapshot *snapshot);
void a6xx_crashdump_init(struct adreno_device *adreno_dev);
#endif
diff --git a/drivers/gpu/msm/adreno_a6xx_preempt.c b/drivers/gpu/msm/adreno_a6xx_preempt.c
index 1d5f4a5..ca011e4 100644
--- a/drivers/gpu/msm/adreno_a6xx_preempt.c
+++ b/drivers/gpu/msm/adreno_a6xx_preempt.c
@@ -635,6 +635,9 @@
return;
gpumem_free_entry(context->user_ctxt_record);
+
+ /* Put the extra ref from gpumem_alloc_entry() */
+ kgsl_mem_entry_put(context->user_ctxt_record);
}
int a6xx_preemption_context_init(struct kgsl_context *context)
@@ -645,6 +648,10 @@
if (!adreno_is_preemption_setup_enabled(adreno_dev))
return 0;
+ /*
+ * gpumem_alloc_entry takes an extra refcount. Put it only when
+ * destroying the context to keep the context record valid
+ */
context->user_ctxt_record = gpumem_alloc_entry(context->dev_priv,
A6XX_CP_CTXRECORD_USER_RESTORE_SIZE, 0);
if (IS_ERR(context->user_ctxt_record)) {
diff --git a/drivers/gpu/msm/adreno_a6xx_snapshot.c b/drivers/gpu/msm/adreno_a6xx_snapshot.c
index 80c9a61..880ee13 100644
--- a/drivers/gpu/msm/adreno_a6xx_snapshot.c
+++ b/drivers/gpu/msm/adreno_a6xx_snapshot.c
@@ -569,38 +569,33 @@
(((_a)[(2 * (_i)) + 1] - (_a)[2 * (_i)]) + 1)
static size_t a6xx_legacy_snapshot_registers(struct kgsl_device *device,
- u8 *buf, size_t remain)
+ u8 *buf, size_t remain, struct reg_list *regs)
{
- unsigned int i;
- size_t used = 0;
+ struct kgsl_snapshot_registers snapshot_regs = {
+ .regs = regs->regs,
+ .count = regs->count,
+ };
- for (i = 0; i < ARRAY_SIZE(a6xx_reg_list); i++) {
- struct reg_list *regs = &a6xx_reg_list[i];
- struct kgsl_snapshot_registers snapshot_regs = {
- .regs = regs->regs,
- .count = regs->count,
- };
+ if (regs->sel)
+ kgsl_regwrite(device, regs->sel->host_reg, regs->sel->val);
- if (regs->sel)
- kgsl_regwrite(device, regs->sel->host_reg,
- regs->sel->val);
- used += kgsl_snapshot_dump_registers(device, buf + used,
- remain - used, &snapshot_regs);
- }
- return used;
+ return kgsl_snapshot_dump_registers(device, buf, remain,
+ &snapshot_regs);
}
static size_t a6xx_snapshot_registers(struct kgsl_device *device, u8 *buf,
size_t remain, void *priv)
{
struct kgsl_snapshot_regs *header = (struct kgsl_snapshot_regs *)buf;
+ struct reg_list *regs = (struct reg_list *)priv;
unsigned int *data = (unsigned int *)(buf + sizeof(*header));
unsigned int *src = (unsigned int *)a6xx_crashdump_registers.hostptr;
- unsigned int i, j, k;
+ unsigned int j, k;
unsigned int count = 0;
if (crash_dump_valid == false)
- return a6xx_legacy_snapshot_registers(device, buf, remain);
+ return a6xx_legacy_snapshot_registers(device, buf, remain,
+ regs);
if (remain < sizeof(*header)) {
SNAPSHOT_ERR_NOMEM(device, "REGISTERS");
@@ -609,24 +604,20 @@
remain -= sizeof(*header);
- for (i = 0; i < ARRAY_SIZE(a6xx_reg_list); i++) {
- struct reg_list *regs = &a6xx_reg_list[i];
+ for (j = 0; j < regs->count; j++) {
+ unsigned int start = regs->regs[2 * j];
+ unsigned int end = regs->regs[(2 * j) + 1];
- for (j = 0; j < regs->count; j++) {
- unsigned int start = regs->regs[2 * j];
- unsigned int end = regs->regs[(2 * j) + 1];
+ if (remain < ((end - start) + 1) * 8) {
+ SNAPSHOT_ERR_NOMEM(device, "REGISTERS");
+ goto out;
+ }
- if (remain < ((end - start) + 1) * 8) {
- SNAPSHOT_ERR_NOMEM(device, "REGISTERS");
- goto out;
- }
+ remain -= ((end - start) + 1) * 8;
- remain -= ((end - start) + 1) * 8;
-
- for (k = start; k <= end; k++, count++) {
- *data++ = k;
- *data++ = *src++;
- }
+ for (k = start; k <= end; k++, count++) {
+ *data++ = k;
+ *data++ = *src++;
}
}
@@ -1471,10 +1462,18 @@
}
}
-static void a6xx_snapshot_gmu(struct kgsl_device *device,
+/*
+ * a6xx_snapshot_gmu() - A6XX GMU snapshot function
+ * @adreno_dev: Device being snapshotted
+ * @snapshot: Pointer to the snapshot instance
+ *
+ * This is where all of the A6XX GMU specific bits and pieces are grabbed
+ * into the snapshot memory
+ */
+void a6xx_snapshot_gmu(struct adreno_device *adreno_dev,
struct kgsl_snapshot *snapshot)
{
- struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
+ struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev);
if (!kgsl_gmu_isenabled(device))
@@ -1519,6 +1518,8 @@
crash_dump_valid = false;
+ if (!device->snapshot_crashdumper)
+ return;
if (a6xx_capturescript.gpuaddr == 0 ||
a6xx_crashdump_registers.gpuaddr == 0)
return;
@@ -1570,17 +1571,13 @@
struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev);
struct adreno_snapshot_data *snap_data = gpudev->snapshot_data;
bool sptprac_on;
-
- /* GMU TCM data dumped through AHB */
- a6xx_snapshot_gmu(device, snapshot);
+ unsigned int i;
sptprac_on = gpudev->sptprac_is_on(adreno_dev);
/* Return if the GX is off */
- if (!gpudev->gx_is_on(adreno_dev)) {
- pr_err("GX is off. Only dumping GMU data in snapshot\n");
+ if (!gpudev->gx_is_on(adreno_dev))
return;
- }
/* Dump the registers which get affected by crash dumper trigger */
kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_REGS,
@@ -1595,8 +1592,10 @@
if (sptprac_on)
_a6xx_do_crashdump(device);
- kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_REGS,
- snapshot, a6xx_snapshot_registers, NULL);
+ for (i = 0; i < ARRAY_SIZE(a6xx_reg_list); i++) {
+ kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_REGS,
+ snapshot, a6xx_snapshot_registers, &a6xx_reg_list[i]);
+ }
/* CP_SQE indexed registers */
kgsl_snapshot_indexed_registers(device, snapshot,
diff --git a/drivers/gpu/msm/adreno_snapshot.c b/drivers/gpu/msm/adreno_snapshot.c
index f608927..b5999e6 100644
--- a/drivers/gpu/msm/adreno_snapshot.c
+++ b/drivers/gpu/msm/adreno_snapshot.c
@@ -837,8 +837,7 @@
snapshot_frozen_objsize = 0;
- if (!IS_ERR(context))
- setup_fault_process(device, snapshot,
+ setup_fault_process(device, snapshot,
context ? context->proc_priv : NULL);
/* Add GPU specific sections - registers mainly, but other stuff too */
@@ -946,6 +945,24 @@
}
+/* adreno_snapshot_gmu - Snapshot the Adreno GMU state
+ * @device - KGSL device to snapshot
+ * @snapshot - Pointer to the snapshot instance
+ * This is a hook function called by kgsl_snapshot to snapshot the
+ * Adreno specific information for the GMU snapshot. In turn, this function
+ * calls the GMU specific snapshot function to get core specific information.
+ */
+void adreno_snapshot_gmu(struct kgsl_device *device,
+ struct kgsl_snapshot *snapshot)
+{
+ struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
+ struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev);
+
+ /* Add GMU specific sections */
+ if (gpudev->snapshot_gmu)
+ gpudev->snapshot_gmu(adreno_dev, snapshot);
+}
+
/*
* adreno_snapshot_cp_roq - Dump CP merciu data in snapshot
* @device: Device being snapshotted
diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c
index 7dff251..0a7d165 100644
--- a/drivers/gpu/msm/kgsl.c
+++ b/drivers/gpu/msm/kgsl.c
@@ -2280,7 +2280,7 @@
struct kgsl_mem_entry *entry,
struct kgsl_gpuobj_import *param)
{
- struct kgsl_gpuobj_import_useraddr useraddr;
+ struct kgsl_gpuobj_import_useraddr useraddr = {0};
int ret;
param->flags &= KGSL_MEMFLAGS_GPUREADONLY
diff --git a/drivers/gpu/msm/kgsl_device.h b/drivers/gpu/msm/kgsl_device.h
index f8d5f5b..0ab775a 100644
--- a/drivers/gpu/msm/kgsl_device.h
+++ b/drivers/gpu/msm/kgsl_device.h
@@ -151,6 +151,8 @@
unsigned int (*gpuid)(struct kgsl_device *device, unsigned int *chipid);
void (*snapshot)(struct kgsl_device *device,
struct kgsl_snapshot *snapshot, struct kgsl_context *context);
+ void (*snapshot_gmu)(struct kgsl_device *device,
+ struct kgsl_snapshot *snapshot);
irqreturn_t (*irq_handler)(struct kgsl_device *device);
int (*drain)(struct kgsl_device *device);
/*
@@ -706,7 +708,6 @@
void kgsl_device_snapshot(struct kgsl_device *device,
struct kgsl_context *context, bool gmu_fault);
void kgsl_device_snapshot_close(struct kgsl_device *device);
-void kgsl_snapshot_save_frozen_objs(struct work_struct *work);
void kgsl_events_init(void);
void kgsl_events_exit(void);
diff --git a/drivers/gpu/msm/kgsl_gmu.c b/drivers/gpu/msm/kgsl_gmu.c
index 3bd7cf3..7ea2255 100644
--- a/drivers/gpu/msm/kgsl_gmu.c
+++ b/drivers/gpu/msm/kgsl_gmu.c
@@ -1366,7 +1366,7 @@
/* Wait for the NMI to be handled */
wmb();
udelay(100);
- kgsl_device_snapshot(device, ERR_PTR(-EINVAL), true);
+ kgsl_device_snapshot(device, NULL, true);
adreno_write_gmureg(adreno_dev,
ADRENO_REG_GMU_GMU2HOST_INTR_CLR, 0xFFFFFFFF);
diff --git a/drivers/gpu/msm/kgsl_snapshot.c b/drivers/gpu/msm/kgsl_snapshot.c
index f9494a4..f710d8f 100644
--- a/drivers/gpu/msm/kgsl_snapshot.c
+++ b/drivers/gpu/msm/kgsl_snapshot.c
@@ -24,6 +24,8 @@
#include "kgsl_snapshot.h"
#include "adreno_cp_parser.h"
+static void kgsl_snapshot_save_frozen_objs(struct work_struct *work);
+
/* Placeholder for list of ib objects that contain all objects in that IB */
struct kgsl_snapshot_cp_obj {
@@ -182,8 +184,7 @@
context = kgsl_context_get(device, header->current_context);
/* Get the current PT base */
- if (!IS_ERR(priv))
- header->ptbase = kgsl_mmu_get_current_ttbr0(&device->mmu);
+ header->ptbase = kgsl_mmu_get_current_ttbr0(&device->mmu);
/* And the PID for the task leader */
if (context) {
@@ -207,6 +208,44 @@
return size;
}
+/* Snapshot the Linux specific information */
+static size_t snapshot_os_no_ctxt(struct kgsl_device *device,
+ u8 *buf, size_t remain, void *priv)
+{
+ struct kgsl_snapshot_linux_v2 *header =
+ (struct kgsl_snapshot_linux_v2 *)buf;
+ struct kgsl_pwrctrl *pwr = &device->pwrctrl;
+ size_t size = sizeof(*header);
+
+ /* Make sure there is enough room for the data */
+ if (remain < size) {
+ SNAPSHOT_ERR_NOMEM(device, "OS");
+ return 0;
+ }
+
+ memset(header, 0, sizeof(*header));
+
+ header->osid = KGSL_SNAPSHOT_OS_LINUX_V3;
+
+ /* Get the kernel build information */
+ strlcpy(header->release, init_utsname()->release,
+ sizeof(header->release));
+ strlcpy(header->version, init_utsname()->version,
+ sizeof(header->version));
+
+ /* Get the Unix time for the timestamp */
+ header->seconds = get_seconds();
+
+ /* Remember the power information */
+ header->power_flags = pwr->power_flags;
+ header->power_level = pwr->active_pwrlevel;
+ header->power_interval_timeout = pwr->interval_timeout;
+ header->grpclk = kgsl_get_clkrate(pwr->grp_clks[0]);
+
+ /* Return the size of the data segment */
+ return size;
+}
+
static void kgsl_snapshot_put_object(struct kgsl_snapshot_object *obj)
{
list_del(&obj->node);
@@ -663,14 +702,24 @@
snapshot->size += sizeof(*header);
/* Build the Linux specific header */
- /* Context err is implied a GMU fault, so limit dump */
- kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_OS,
- snapshot, snapshot_os,
- IS_ERR(context) ? context : NULL);
+ /* We either want to only dump GMU, or we want to dump GPU and GMU */
+ if (gmu_fault) {
+ /* Dump only the GMU */
+ kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_OS,
+ snapshot, snapshot_os_no_ctxt, NULL);
- /* Get the device specific sections */
- if (device->ftbl->snapshot)
- device->ftbl->snapshot(device, snapshot, context);
+ if (device->ftbl->snapshot_gmu)
+ device->ftbl->snapshot_gmu(device, snapshot);
+ } else {
+ /* Dump GPU and GMU */
+ kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_OS,
+ snapshot, snapshot_os, NULL);
+
+ if (device->ftbl->snapshot)
+ device->ftbl->snapshot(device, snapshot, context);
+ if (device->ftbl->snapshot_gmu)
+ device->ftbl->snapshot_gmu(device, snapshot);
+ }
/*
* The timestamp is the seconds since boot so it is easier to match to
@@ -1193,7 +1242,7 @@
* is taken
* @work: The work item that scheduled this work
*/
-void kgsl_snapshot_save_frozen_objs(struct work_struct *work)
+static void kgsl_snapshot_save_frozen_objs(struct work_struct *work)
{
struct kgsl_snapshot *snapshot = container_of(work,
struct kgsl_snapshot, work);
@@ -1205,6 +1254,9 @@
if (IS_ERR_OR_NULL(device))
return;
+ if (snapshot->gmu_fault)
+ goto gmu_only;
+
kgsl_snapshot_process_ib_obj_list(snapshot);
list_for_each_entry(obj, &snapshot->obj_list, node) {
@@ -1251,6 +1303,7 @@
"snapshot: Active IB2:%016llx not dumped\n",
snapshot->ib2base);
+gmu_only:
complete_all(&snapshot->dump_gate);
BUG_ON(device->force_panic);
}
diff --git a/drivers/hwtracing/coresight/coresight-priv.h b/drivers/hwtracing/coresight/coresight-priv.h
index 3af358a..9caac56 100644
--- a/drivers/hwtracing/coresight/coresight-priv.h
+++ b/drivers/hwtracing/coresight/coresight-priv.h
@@ -157,7 +157,7 @@
static inline void msm_qdss_csr_enable_bam_to_usb(void) {}
static inline void msm_qdss_csr_disable_bam_to_usb(void) {}
static inline void msm_qdss_csr_disable_flush(void) {}
-static inline int coresight_csr_hwctrl_set(uint64_t addr, 95
+static inline int coresight_csr_hwctrl_set(uint64_t addr,
uint32_t val) { return -EINVAL; }
#endif
diff --git a/drivers/hwtracing/intel_th/pci.c b/drivers/hwtracing/intel_th/pci.c
index 0bba384..63b5db4 100644
--- a/drivers/hwtracing/intel_th/pci.c
+++ b/drivers/hwtracing/intel_th/pci.c
@@ -85,6 +85,16 @@
PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa2a6),
.driver_data = (kernel_ulong_t)0,
},
+ {
+ /* Cannon Lake H */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa326),
+ .driver_data = (kernel_ulong_t)0,
+ },
+ {
+ /* Cannon Lake LP */
+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x9da6),
+ .driver_data = (kernel_ulong_t)0,
+ },
{ 0 },
};
diff --git a/drivers/i2c/busses/i2c-qcom-geni.c b/drivers/i2c/busses/i2c-qcom-geni.c
index f70dbf2..7264381 100644
--- a/drivers/i2c/busses/i2c-qcom-geni.c
+++ b/drivers/i2c/busses/i2c-qcom-geni.c
@@ -191,13 +191,6 @@
static void geni_i2c_err(struct geni_i2c_dev *gi2c, int err)
{
- u32 m_cmd = readl_relaxed(gi2c->base + SE_GENI_M_CMD0);
- u32 m_stat = readl_relaxed(gi2c->base + SE_GENI_M_IRQ_STATUS);
- u32 geni_s = readl_relaxed(gi2c->base + SE_GENI_STATUS);
- u32 geni_ios = readl_relaxed(gi2c->base + SE_GENI_IOS);
- u32 dma = readl_relaxed(gi2c->base + SE_GENI_DMA_MODE_EN);
- u32 rx_st, tx_st;
-
if (gi2c->cur)
GENI_SE_DBG(gi2c->ipcl, false, gi2c->dev,
"len:%d, slv-addr:0x%x, RD/WR:%d\n", gi2c->cur->len,
@@ -211,23 +204,9 @@
GENI_SE_ERR(gi2c->ipcl, true, gi2c->dev, "%s\n",
gi2c_log[err].msg);
}
- if (gi2c->se_mode == GSI_ONLY)
- goto err_out;
-
- if (dma) {
- rx_st = readl_relaxed(gi2c->base + SE_DMA_RX_IRQ_STAT);
- tx_st = readl_relaxed(gi2c->base + SE_DMA_TX_IRQ_STAT);
- } else {
- rx_st = readl_relaxed(gi2c->base + SE_GENI_RX_FIFO_STATUS);
- tx_st = readl_relaxed(gi2c->base + SE_GENI_TX_FIFO_STATUS);
- }
- GENI_SE_DBG(gi2c->ipcl, false, gi2c->dev,
- "DMA:%d tx_stat:0x%x, rx_stat:0x%x, irq-stat:0x%x\n",
- dma, tx_st, rx_st, m_stat);
-err_out:
- GENI_SE_DBG(gi2c->ipcl, false, gi2c->dev,
- "m_cmd:0x%x, geni_status:0x%x, geni_ios:0x%x\n",
- m_cmd, geni_s, geni_ios);
+ GENI_SE_DBG(gi2c->ipcl, false, gi2c->dev, "%s: se-mode:%d\n", __func__,
+ gi2c->se_mode);
+ geni_se_dump_dbg_regs(&gi2c->i2c_rsc, gi2c->base, gi2c->ipcl);
err_ret:
gi2c->err = gi2c_log[err].err;
}
diff --git a/drivers/iio/adc/ti-ads1015.c b/drivers/iio/adc/ti-ads1015.c
index cde6f13..472641f 100644
--- a/drivers/iio/adc/ti-ads1015.c
+++ b/drivers/iio/adc/ti-ads1015.c
@@ -80,18 +80,12 @@
8, 16, 32, 64, 128, 250, 475, 860
};
-static const struct {
- int scale;
- int uscale;
-} ads1015_scale[] = {
- {3, 0},
- {2, 0},
- {1, 0},
- {0, 500000},
- {0, 250000},
- {0, 125000},
- {0, 125000},
- {0, 125000},
+/*
+ * Translation from PGA bits to full-scale positive and negative input voltage
+ * range in mV
+ */
+static int ads1015_fullscale_range[] = {
+ 6144, 4096, 2048, 1024, 512, 256, 256, 256
};
#define ADS1015_V_CHAN(_chan, _addr) { \
@@ -182,6 +176,12 @@
struct ads1015_channel_data channel_data[ADS1015_CHANNELS];
unsigned int *data_rate;
+ /*
+ * Set to true when the ADC is switched to the continuous-conversion
+ * mode and exits from a power-down state. This flag is used to avoid
+ * getting the stale result from the conversion register.
+ */
+ bool conv_invalid;
};
static bool ads1015_is_writeable_reg(struct device *dev, unsigned int reg)
@@ -234,33 +234,43 @@
ret = pm_runtime_put_autosuspend(dev);
}
- return ret;
+ return ret < 0 ? ret : 0;
}
static
int ads1015_get_adc_result(struct ads1015_data *data, int chan, int *val)
{
int ret, pga, dr, conv_time;
- bool change;
+ unsigned int old, mask, cfg;
if (chan < 0 || chan >= ADS1015_CHANNELS)
return -EINVAL;
- pga = data->channel_data[chan].pga;
- dr = data->channel_data[chan].data_rate;
-
- ret = regmap_update_bits_check(data->regmap, ADS1015_CFG_REG,
- ADS1015_CFG_MUX_MASK |
- ADS1015_CFG_PGA_MASK,
- chan << ADS1015_CFG_MUX_SHIFT |
- pga << ADS1015_CFG_PGA_SHIFT,
- &change);
- if (ret < 0)
+ ret = regmap_read(data->regmap, ADS1015_CFG_REG, &old);
+ if (ret)
return ret;
- if (change) {
- conv_time = DIV_ROUND_UP(USEC_PER_SEC, data->data_rate[dr]);
+ pga = data->channel_data[chan].pga;
+ dr = data->channel_data[chan].data_rate;
+ mask = ADS1015_CFG_MUX_MASK | ADS1015_CFG_PGA_MASK |
+ ADS1015_CFG_DR_MASK;
+ cfg = chan << ADS1015_CFG_MUX_SHIFT | pga << ADS1015_CFG_PGA_SHIFT |
+ dr << ADS1015_CFG_DR_SHIFT;
+
+ cfg = (old & ~mask) | (cfg & mask);
+
+ ret = regmap_write(data->regmap, ADS1015_CFG_REG, cfg);
+ if (ret)
+ return ret;
+
+ if (old != cfg || data->conv_invalid) {
+ int dr_old = (old & ADS1015_CFG_DR_MASK) >>
+ ADS1015_CFG_DR_SHIFT;
+
+ conv_time = DIV_ROUND_UP(USEC_PER_SEC, data->data_rate[dr_old]);
+ conv_time += DIV_ROUND_UP(USEC_PER_SEC, data->data_rate[dr]);
usleep_range(conv_time, conv_time + 1);
+ data->conv_invalid = false;
}
return regmap_read(data->regmap, ADS1015_CONV_REG, val);
@@ -297,17 +307,20 @@
return IRQ_HANDLED;
}
-static int ads1015_set_scale(struct ads1015_data *data, int chan,
+static int ads1015_set_scale(struct ads1015_data *data,
+ struct iio_chan_spec const *chan,
int scale, int uscale)
{
int i, ret, rindex = -1;
+ int fullscale = div_s64((scale * 1000000LL + uscale) <<
+ (chan->scan_type.realbits - 1), 1000000);
- for (i = 0; i < ARRAY_SIZE(ads1015_scale); i++)
- if (ads1015_scale[i].scale == scale &&
- ads1015_scale[i].uscale == uscale) {
+ for (i = 0; i < ARRAY_SIZE(ads1015_fullscale_range); i++) {
+ if (ads1015_fullscale_range[i] == fullscale) {
rindex = i;
break;
}
+ }
if (rindex < 0)
return -EINVAL;
@@ -317,32 +330,23 @@
if (ret < 0)
return ret;
- data->channel_data[chan].pga = rindex;
+ data->channel_data[chan->address].pga = rindex;
return 0;
}
static int ads1015_set_data_rate(struct ads1015_data *data, int chan, int rate)
{
- int i, ret, rindex = -1;
+ int i;
- for (i = 0; i < ARRAY_SIZE(ads1015_data_rate); i++)
+ for (i = 0; i < ARRAY_SIZE(ads1015_data_rate); i++) {
if (data->data_rate[i] == rate) {
- rindex = i;
- break;
+ data->channel_data[chan].data_rate = i;
+ return 0;
}
- if (rindex < 0)
- return -EINVAL;
+ }
- ret = regmap_update_bits(data->regmap, ADS1015_CFG_REG,
- ADS1015_CFG_DR_MASK,
- rindex << ADS1015_CFG_DR_SHIFT);
- if (ret < 0)
- return ret;
-
- data->channel_data[chan].data_rate = rindex;
-
- return 0;
+ return -EINVAL;
}
static int ads1015_read_raw(struct iio_dev *indio_dev,
@@ -384,9 +388,9 @@
}
case IIO_CHAN_INFO_SCALE:
idx = data->channel_data[chan->address].pga;
- *val = ads1015_scale[idx].scale;
- *val2 = ads1015_scale[idx].uscale;
- ret = IIO_VAL_INT_PLUS_MICRO;
+ *val = ads1015_fullscale_range[idx];
+ *val2 = chan->scan_type.realbits - 1;
+ ret = IIO_VAL_FRACTIONAL_LOG2;
break;
case IIO_CHAN_INFO_SAMP_FREQ:
idx = data->channel_data[chan->address].data_rate;
@@ -413,7 +417,7 @@
mutex_lock(&data->lock);
switch (mask) {
case IIO_CHAN_INFO_SCALE:
- ret = ads1015_set_scale(data, chan->address, val, val2);
+ ret = ads1015_set_scale(data, chan, val, val2);
break;
case IIO_CHAN_INFO_SAMP_FREQ:
ret = ads1015_set_data_rate(data, chan->address, val);
@@ -445,7 +449,10 @@
.validate_scan_mask = &iio_validate_scan_mask_onehot,
};
-static IIO_CONST_ATTR(scale_available, "3 2 1 0.5 0.25 0.125");
+static IIO_CONST_ATTR_NAMED(ads1015_scale_available, scale_available,
+ "3 2 1 0.5 0.25 0.125");
+static IIO_CONST_ATTR_NAMED(ads1115_scale_available, scale_available,
+ "0.1875 0.125 0.0625 0.03125 0.015625 0.007813");
static IIO_CONST_ATTR_NAMED(ads1015_sampling_frequency_available,
sampling_frequency_available, "128 250 490 920 1600 2400 3300");
@@ -453,7 +460,7 @@
sampling_frequency_available, "8 16 32 64 128 250 475 860");
static struct attribute *ads1015_attributes[] = {
- &iio_const_attr_scale_available.dev_attr.attr,
+ &iio_const_attr_ads1015_scale_available.dev_attr.attr,
&iio_const_attr_ads1015_sampling_frequency_available.dev_attr.attr,
NULL,
};
@@ -463,7 +470,7 @@
};
static struct attribute *ads1115_attributes[] = {
- &iio_const_attr_scale_available.dev_attr.attr,
+ &iio_const_attr_ads1115_scale_available.dev_attr.attr,
&iio_const_attr_ads1115_sampling_frequency_available.dev_attr.attr,
NULL,
};
@@ -624,6 +631,15 @@
dev_err(&client->dev, "iio triggered buffer setup failed\n");
return ret;
}
+
+ ret = regmap_update_bits(data->regmap, ADS1015_CFG_REG,
+ ADS1015_CFG_MOD_MASK,
+ ADS1015_CONTINUOUS << ADS1015_CFG_MOD_SHIFT);
+ if (ret)
+ return ret;
+
+ data->conv_invalid = true;
+
ret = pm_runtime_set_active(&client->dev);
if (ret)
goto err_buffer_cleanup;
@@ -679,10 +695,15 @@
{
struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
struct ads1015_data *data = iio_priv(indio_dev);
+ int ret;
- return regmap_update_bits(data->regmap, ADS1015_CFG_REG,
+ ret = regmap_update_bits(data->regmap, ADS1015_CFG_REG,
ADS1015_CFG_MOD_MASK,
ADS1015_CONTINUOUS << ADS1015_CFG_MOD_SHIFT);
+ if (!ret)
+ data->conv_invalid = true;
+
+ return ret;
}
#endif
diff --git a/drivers/input/mouse/trackpoint.c b/drivers/input/mouse/trackpoint.c
index ce6ff9b..7e2dc5e 100644
--- a/drivers/input/mouse/trackpoint.c
+++ b/drivers/input/mouse/trackpoint.c
@@ -381,8 +381,8 @@
return 0;
if (trackpoint_read(&psmouse->ps2dev, TP_EXT_BTN, &button_info)) {
- psmouse_warn(psmouse, "failed to get extended button data\n");
- button_info = 0;
+ psmouse_warn(psmouse, "failed to get extended button data, assuming 3 buttons\n");
+ button_info = 0x33;
}
psmouse->private = kzalloc(sizeof(struct trackpoint_data), GFP_KERNEL);
diff --git a/drivers/leds/leds-qpnp.c b/drivers/leds/leds-qpnp.c
index 817dfa3..e3cfffb 100644
--- a/drivers/leds/leds-qpnp.c
+++ b/drivers/leds/leds-qpnp.c
@@ -875,6 +875,14 @@
}
if (led->mpp_cfg->pwm_mode == PWM_MODE) {
/*config pwm for brightness scaling*/
+ rc = pwm_change_mode(led->mpp_cfg->pwm_cfg->pwm_dev,
+ PM_PWM_MODE_PWM);
+ if (rc < 0) {
+ dev_err(&led->pdev->dev,
+ "Failed to set PWM mode, rc = %d\n",
+ rc);
+ return rc;
+ }
period_us = led->mpp_cfg->pwm_cfg->pwm_period_us;
if (period_us > INT_MAX / NSEC_PER_USEC) {
duty_us = (period_us * led->cdev.brightness) /
@@ -1213,7 +1221,7 @@
static int qpnp_flash_set(struct qpnp_led_data *led)
{
- int rc, error;
+ int rc = 0, error;
int val = led->cdev.brightness;
if (led->flash_cfg->torch_enable)
@@ -1251,7 +1259,8 @@
}
}
- qpnp_led_masked_write(led, FLASH_MAX_CURR(led->base),
+ rc = qpnp_led_masked_write(led,
+ FLASH_MAX_CURR(led->base),
FLASH_CURRENT_MASK,
TORCH_MAX_LEVEL);
if (rc) {
@@ -1261,7 +1270,7 @@
goto error_reg_write;
}
- qpnp_led_masked_write(led,
+ rc = qpnp_led_masked_write(led,
FLASH_LED_TMR_CTRL(led->base),
FLASH_TMR_MASK,
FLASH_TMR_WATCHDOG);
@@ -1293,7 +1302,7 @@
goto error_reg_write;
}
- qpnp_led_masked_write(led,
+ rc = qpnp_led_masked_write(led,
FLASH_WATCHDOG_TMR(led->base),
FLASH_WATCHDOG_MASK,
led->flash_cfg->duration);
@@ -1341,7 +1350,7 @@
goto error_flash_set;
}
- qpnp_led_masked_write(led,
+ rc = qpnp_led_masked_write(led,
FLASH_LED_TMR_CTRL(led->base),
FLASH_TMR_MASK,
FLASH_TMR_SAFETY);
@@ -1580,6 +1589,14 @@
}
if (led->kpdbl_cfg->pwm_cfg->mode == PWM_MODE) {
+ rc = pwm_change_mode(led->kpdbl_cfg->pwm_cfg->pwm_dev,
+ PM_PWM_MODE_PWM);
+ if (rc < 0) {
+ dev_err(&led->pdev->dev,
+ "Failed to set PWM mode, rc = %d\n",
+ rc);
+ return rc;
+ }
period_us = led->kpdbl_cfg->pwm_cfg->pwm_period_us;
if (period_us > INT_MAX / NSEC_PER_USEC) {
duty_us = (period_us * led->cdev.brightness) /
@@ -1701,6 +1718,14 @@
led->rgb_cfg->pwm_cfg->mode =
led->rgb_cfg->pwm_cfg->default_mode;
if (led->rgb_cfg->pwm_cfg->mode == PWM_MODE) {
+ rc = pwm_change_mode(led->rgb_cfg->pwm_cfg->pwm_dev,
+ PM_PWM_MODE_PWM);
+ if (rc < 0) {
+ dev_err(&led->pdev->dev,
+ "Failed to set PWM mode, rc = %d\n",
+ rc);
+ return rc;
+ }
period_us = led->rgb_cfg->pwm_cfg->pwm_period_us;
if (period_us > INT_MAX / NSEC_PER_USEC) {
duty_us = (period_us * led->cdev.brightness) /
@@ -2135,6 +2160,11 @@
dev_err(&pdev->dev, "Failed to configure pwm LUT\n");
return rc;
}
+ rc = pwm_change_mode(pwm_cfg->pwm_dev, PM_PWM_MODE_LPG);
+ if (rc < 0) {
+ dev_err(&pdev->dev, "Failed to set LPG mode\n");
+ return rc;
+ }
}
} else {
dev_err(&pdev->dev, "Invalid PWM device\n");
diff --git a/drivers/mailbox/msm_qmp.c b/drivers/mailbox/msm_qmp.c
index f0bb0bc..3b07c47 100644
--- a/drivers/mailbox/msm_qmp.c
+++ b/drivers/mailbox/msm_qmp.c
@@ -27,7 +27,7 @@
#define QMP_VERSION 0x1
#define QMP_FEATURES 0x0
#define QMP_TOUT_MS 5000
-#define QMP_TX_TOUT_MS 2000
+#define QMP_TX_TOUT_MS 1000
#define QMP_MBOX_LINK_DOWN 0xFFFF0000
#define QMP_MBOX_LINK_UP 0x0000FFFF
@@ -229,7 +229,7 @@
}
/**
- * qmp_notify_timeout() - Notify client of tx timeout with -EIO
+ * qmp_notify_timeout() - Notify client of tx timeout with -ETIME
* @work: Structure for work that was scheduled.
*/
static void qmp_notify_timeout(struct work_struct *work)
@@ -237,7 +237,7 @@
struct delayed_work *dwork = to_delayed_work(work);
struct qmp_mbox *mbox = container_of(dwork, struct qmp_mbox, dwork);
struct mbox_chan *chan = &mbox->ctrl.chans[mbox->idx_in_flight];
- int err = -EIO;
+ int err = -ETIME;
unsigned long flags;
spin_lock_irqsave(&mbox->tx_lock, flags);
@@ -246,6 +246,7 @@
return;
}
pr_err("%s: qmp tx timeout for %d\n", __func__, mbox->idx_in_flight);
+ iowrite32(0, mbox->mdev->msgram + mbox->mcore_mbox_offset);
mbox->tx_sent = false;
spin_unlock_irqrestore(&mbox->tx_lock, flags);
mbox_chan_txdone(chan, err);
diff --git a/drivers/mcb/mcb-lpc.c b/drivers/mcb/mcb-lpc.c
index d072c08..945091a 100644
--- a/drivers/mcb/mcb-lpc.c
+++ b/drivers/mcb/mcb-lpc.c
@@ -114,6 +114,12 @@
.flags = IORESOURCE_MEM,
};
+static struct resource sc31_fpga_resource = {
+ .start = 0xf000e000,
+ .end = 0xf000e000 + CHAM_HEADER_SIZE,
+ .flags = IORESOURCE_MEM,
+};
+
static struct platform_driver mcb_lpc_driver = {
.driver = {
.name = "mcb-lpc",
@@ -132,6 +138,15 @@
.driver_data = (void *)&sc24_fpga_resource,
.callback = mcb_lpc_create_platform_device,
},
+ {
+ .ident = "SC31",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "MEN"),
+ DMI_MATCH(DMI_PRODUCT_VERSION, "14SC31"),
+ },
+ .driver_data = (void *)&sc31_fpga_resource,
+ .callback = mcb_lpc_create_platform_device,
+ },
{}
};
MODULE_DEVICE_TABLE(dmi, mcb_lpc_dmi_table);
diff --git a/drivers/md/dm-rq.c b/drivers/md/dm-rq.c
index bca4c0e..e289aae 100644
--- a/drivers/md/dm-rq.c
+++ b/drivers/md/dm-rq.c
@@ -848,8 +848,12 @@
tio = tio_from_request(rq);
/* Establish tio->ti before queuing work (map_tio_request) */
tio->ti = ti;
- kthread_queue_work(&md->kworker, &tio->work);
+ spin_unlock(q->queue_lock);
+ if (map_request(tio) == DM_MAPIO_REQUEUE)
+ dm_requeue_original_request(tio, false);
+
BUG_ON(!irqs_disabled());
+ spin_lock(q->queue_lock);
}
}
diff --git a/drivers/media/platform/msm/vidc/msm_smem.c b/drivers/media/platform/msm/vidc/msm_smem.c
index 9b23376..7688f89 100644
--- a/drivers/media/platform/msm/vidc/msm_smem.c
+++ b/drivers/media/platform/msm/vidc/msm_smem.c
@@ -603,22 +603,25 @@
__func__, mem->handle, mem->device_addr, mem->size,
mem->kvaddr, mem->buffer_type);
- if (mem->device_addr)
+ if (mem->device_addr) {
msm_ion_put_device_address(client, mem->handle, mem->flags,
&mem->mapping_info, mem->buffer_type);
+ mem->device_addr = 0x0;
+ }
- if (mem->kvaddr)
+ if (mem->kvaddr) {
ion_unmap_kernel(client->clnt, mem->handle);
+ mem->kvaddr = NULL;
+ }
if (mem->handle) {
trace_msm_smem_buffer_ion_op_start("FREE",
(u32)mem->buffer_type, -1, mem->size, -1,
mem->flags, -1);
ion_free(client->clnt, mem->handle);
+ mem->handle = NULL;
trace_msm_smem_buffer_ion_op_end("FREE", (u32)mem->buffer_type,
-1, mem->size, -1, mem->flags, -1);
- } else {
- dprintk(VIDC_ERR, "%s: invalid ion_handle\n", __func__);
}
return rc;
diff --git a/drivers/media/platform/msm/vidc/msm_vdec.c b/drivers/media/platform/msm/vidc/msm_vdec.c
index a527717..286a67e 100644
--- a/drivers/media/platform/msm/vidc/msm_vdec.c
+++ b/drivers/media/platform/msm/vidc/msm_vdec.c
@@ -537,7 +537,7 @@
.name = "VP8",
.description = "VP8 compressed format",
.fourcc = V4L2_PIX_FMT_VP8,
- .get_frame_size = get_frame_size_compressed,
+ .get_frame_size = get_frame_size_compressed_full_yuv,
.type = OUTPUT_PORT,
.defer_outputs = false,
},
diff --git a/drivers/media/platform/msm/vidc/msm_vidc.c b/drivers/media/platform/msm/vidc/msm_vidc.c
index b4c0ab9..ae2a2c6 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc.c
@@ -280,6 +280,7 @@
break;
case V4L2_PIX_FMT_NV12_TP10_UBWC:
color_format = COLOR_FMT_NV12_BPP10_UBWC;
+ break;
case V4L2_PIX_FMT_SDE_Y_CBCR_H2V2_P010:
color_format = COLOR_FMT_P010;
break;
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_clocks.c b/drivers/media/platform/msm/vidc/msm_vidc_clocks.c
index 1ef1282..c6d31f7 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_clocks.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_clocks.c
@@ -553,7 +553,8 @@
static int msm_vidc_set_clocks(struct msm_vidc_core *core)
{
struct hfi_device *hdev;
- unsigned long freq = 0, rate = 0;
+ unsigned long freq_core_1 = 0, freq_core_2 = 0, rate = 0;
+ unsigned long freq_core_max = 0;
struct msm_vidc_inst *temp = NULL;
int rc = 0, i = 0;
struct allowed_clock_rates_table *allowed_clks_tbl = NULL;
@@ -568,20 +569,33 @@
mutex_lock(&core->lock);
list_for_each_entry(temp, &core->instances, list) {
- freq += temp->clk_data.curr_freq;
+
+ if (temp->clk_data.core_id == VIDC_CORE_ID_1)
+ freq_core_1 += temp->clk_data.min_freq;
+ else if (temp->clk_data.core_id == VIDC_CORE_ID_2)
+ freq_core_2 += temp->clk_data.min_freq;
+ else if (temp->clk_data.core_id == VIDC_CORE_ID_3) {
+ freq_core_1 += temp->clk_data.min_freq / 2;
+ freq_core_2 += temp->clk_data.min_freq / 2;
+ }
+
+ freq_core_max = max_t(unsigned long, freq_core_1, freq_core_2);
+
if (temp->clk_data.turbo_mode) {
dprintk(VIDC_PROF,
"Found an instance with Turbo request\n");
- freq = msm_vidc_max_freq(core);
+ freq_core_max = msm_vidc_max_freq(core);
break;
}
}
+
for (i = core->resources.allowed_clks_tbl_size - 1; i >= 0; i--) {
rate = allowed_clks_tbl[i].clock_rate;
- if (rate >= freq)
+ if (rate >= freq_core_max)
break;
}
- core->min_freq = freq;
+
+ core->min_freq = freq_core_max;
core->curr_freq = rate;
mutex_unlock(&core->lock);
@@ -1018,17 +1032,21 @@
}
static u32 get_core_load(struct msm_vidc_core *core,
- u32 core_id, bool lp_mode)
+ u32 core_id, bool lp_mode, bool real_time)
{
struct msm_vidc_inst *inst = NULL;
u32 current_inst_mbs_per_sec = 0, load = 0;
+ bool real_time_mode = false;
mutex_lock(&core->lock);
list_for_each_entry(inst, &core->instances, list) {
u32 cycles, lp_cycles;
+ real_time_mode = inst->flags & VIDC_REALTIME ? true : false;
if (!(inst->clk_data.core_id & core_id))
continue;
+ if (real_time_mode != real_time)
+ continue;
if (inst->session_type == MSM_VIDC_DECODER) {
cycles = lp_cycles = inst->clk_data.entry->vpp_cycles;
} else if (inst->session_type == MSM_VIDC_ENCODER) {
@@ -1073,10 +1091,10 @@
max_freq = msm_vidc_max_freq(inst->core);
inst->clk_data.core_id = 0;
- core0_load = get_core_load(core, VIDC_CORE_ID_1, false);
- core1_load = get_core_load(core, VIDC_CORE_ID_2, false);
- core0_lp_load = get_core_load(core, VIDC_CORE_ID_1, true);
- core1_lp_load = get_core_load(core, VIDC_CORE_ID_2, true);
+ core0_load = get_core_load(core, VIDC_CORE_ID_1, false, true);
+ core1_load = get_core_load(core, VIDC_CORE_ID_2, false, true);
+ core0_lp_load = get_core_load(core, VIDC_CORE_ID_1, true, true);
+ core1_lp_load = get_core_load(core, VIDC_CORE_ID_2, true, true);
min_load = min(core0_load, core1_load);
min_core_id = core0_load < core1_load ?
@@ -1095,9 +1113,9 @@
current_inst_lp_load = msm_comm_get_inst_load(inst,
LOAD_CALC_NO_QUIRKS) * lp_cycles;
- dprintk(VIDC_DBG, "Core 0 Load = %d Core 1 Load = %d\n",
+ dprintk(VIDC_DBG, "Core 0 RT Load = %d Core 1 RT Load = %d\n",
core0_load, core1_load);
- dprintk(VIDC_DBG, "Core 0 LP Load = %d Core 1 LP Load = %d\n",
+ dprintk(VIDC_DBG, "Core 0 RT LP Load = %d Core 1 RT LP Load = %d\n",
core0_lp_load, core1_lp_load);
dprintk(VIDC_DBG, "Max Load = %lu\n", max_freq);
dprintk(VIDC_DBG, "Current Load = %d Current LP Load = %d\n",
@@ -1191,12 +1209,12 @@
mutex_lock(&core->lock);
list_for_each_entry(inst, &core->instances, list) {
- if (!((inst->clk_data.core_id & core_id) ||
- (inst->clk_data.core_id & VIDC_CORE_ID_3)))
+ if ((inst->clk_data.core_id != core_id) &&
+ (inst->clk_data.core_id != VIDC_CORE_ID_3))
continue;
dprintk(VIDC_PROF,
- "inst %pK (%4ux%4u) to (%4ux%4u) %3u %s %s %s %s\n",
+ "inst %pK (%4ux%4u) to (%4ux%4u) %3u %s %s %s %s %lu\n",
inst,
inst->prop.width[OUTPUT_PORT],
inst->prop.height[OUTPUT_PORT],
@@ -1207,7 +1225,8 @@
inst->clk_data.work_mode == VIDC_WORK_MODE_1 ?
"WORK_MODE_1" : "WORK_MODE_2",
inst->flags & VIDC_LOW_POWER ? "LP" : "HQ",
- inst->flags & VIDC_REALTIME ? "RealTime" : "NonRTime");
+ inst->flags & VIDC_REALTIME ? "RealTime" : "NonRTime",
+ inst->clk_data.min_freq);
}
mutex_unlock(&core->lock);
}
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.c b/drivers/media/platform/msm/vidc/msm_vidc_common.c
index 4238eda..2beb90c 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_common.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_common.c
@@ -2196,7 +2196,8 @@
"%s: Send sys error for inst %pK\n", __func__, inst);
change_inst_state(inst, MSM_VIDC_CORE_INVALID);
msm_vidc_queue_v4l2_event(inst, V4L2_EVENT_MSM_VIDC_SYS_ERROR);
- msm_comm_print_inst_info(inst);
+ if (!core->trigger_ssr)
+ msm_comm_print_inst_info(inst);
}
dprintk(VIDC_DBG, "Calling core_release\n");
rc = call_hfi_op(hdev, core_release, hdev->hfi_device_data);
@@ -4776,6 +4777,7 @@
mutex_lock(&inst->eosbufs.lock);
list_for_each_entry_safe(buf, next, &inst->eosbufs.list, list) {
list_del(&buf->list);
+ msm_comm_smem_free(inst, &buf->smem);
kfree(buf);
}
INIT_LIST_HEAD(&inst->eosbufs.list);
@@ -5323,8 +5325,7 @@
LOAD_CALC_IGNORE_NON_REALTIME_LOAD;
if (inst->state == MSM_VIDC_OPEN_DONE) {
- max_load_adj = inst->core->resources.max_load +
- inst->capability.mbs_per_frame.max;
+ max_load_adj = inst->core->resources.max_load;
num_mbs_per_sec = msm_comm_get_load(inst->core,
MSM_VIDC_DECODER, quirks);
num_mbs_per_sec += msm_comm_get_load(inst->core,
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_debug.h b/drivers/media/platform/msm/vidc/msm_vidc_debug.h
index c1828b3..dbebe5d 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_debug.h
+++ b/drivers/media/platform/msm/vidc/msm_vidc_debug.h
@@ -113,7 +113,6 @@
#define MSM_VIDC_ERROR(value) \
do { \
- dprintk(VIDC_DBG, "Fatal Level = %d\n", value);\
BUG_ON(value); \
} while (0)
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_platform.c b/drivers/media/platform/msm/vidc/msm_vidc_platform.c
index 3aaee84..a82b598 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_platform.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_platform.c
@@ -119,7 +119,7 @@
},
{
.key = "qcom,max-hw-load",
- .value = 2563200,
+ .value = 3110400, /* 4096x2160@90 */
},
{
.key = "qcom,max-hq-mbs-per-frame",
diff --git a/drivers/media/platform/msm/vidc/venus_hfi.c b/drivers/media/platform/msm/vidc/venus_hfi.c
index dde6029..0fbc96e 100644
--- a/drivers/media/platform/msm/vidc/venus_hfi.c
+++ b/drivers/media/platform/msm/vidc/venus_hfi.c
@@ -4282,10 +4282,65 @@
return rc;
}
+static void __noc_error_info(struct venus_hfi_device *device, u32 core_num)
+{
+ u32 vcodec_core_video_noc_base_offs, val;
+
+ if (!device) {
+ dprintk(VIDC_ERR, "%s: null device\n", __func__);
+ return;
+ }
+ if (!core_num) {
+ vcodec_core_video_noc_base_offs =
+ VCODEC_CORE0_VIDEO_NOC_BASE_OFFS;
+ } else if (core_num == 1) {
+ vcodec_core_video_noc_base_offs =
+ VCODEC_CORE1_VIDEO_NOC_BASE_OFFS;
+ } else {
+ dprintk(VIDC_ERR, "%s: invalid core_num %u\n",
+ __func__, core_num);
+ return;
+ }
+
+ val = __read_register(device, vcodec_core_video_noc_base_offs +
+ VCODEC_COREX_VIDEO_NOC_ERR_SWID_LOW_OFFS);
+ dprintk(VIDC_ERR, "CORE%d_NOC_ERR_SWID_LOW: %#x\n", core_num, val);
+ val = __read_register(device, vcodec_core_video_noc_base_offs +
+ VCODEC_COREX_VIDEO_NOC_ERR_SWID_HIGH_OFFS);
+ dprintk(VIDC_ERR, "CORE%d_NOC_ERR_SWID_HIGH: %#x\n", core_num, val);
+ val = __read_register(device, vcodec_core_video_noc_base_offs +
+ VCODEC_COREX_VIDEO_NOC_ERR_MAINCTL_LOW_OFFS);
+ dprintk(VIDC_ERR, "CORE%d_NOC_ERR_MAINCTL_LOW: %#x\n", core_num, val);
+ val = __read_register(device, vcodec_core_video_noc_base_offs +
+ VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG0_LOW_OFFS);
+ dprintk(VIDC_ERR, "CORE%d_NOC_ERR_ERRLOG0_LOW: %#x\n", core_num, val);
+ val = __read_register(device, vcodec_core_video_noc_base_offs +
+ VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG0_HIGH_OFFS);
+ dprintk(VIDC_ERR, "CORE%d_NOC_ERR_ERRLOG0_HIGH: %#x\n", core_num, val);
+ val = __read_register(device, vcodec_core_video_noc_base_offs +
+ VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG1_LOW_OFFS);
+ dprintk(VIDC_ERR, "CORE%d_NOC_ERR_ERRLOG1_LOW: %#x\n", core_num, val);
+ val = __read_register(device, vcodec_core_video_noc_base_offs +
+ VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG1_HIGH_OFFS);
+ dprintk(VIDC_ERR, "CORE%d_NOC_ERR_ERRLOG1_HIGH: %#x\n", core_num, val);
+ val = __read_register(device, vcodec_core_video_noc_base_offs +
+ VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG2_LOW_OFFS);
+ dprintk(VIDC_ERR, "CORE%d_NOC_ERR_ERRLOG2_LOW: %#x\n", core_num, val);
+ val = __read_register(device, vcodec_core_video_noc_base_offs +
+ VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG2_HIGH_OFFS);
+ dprintk(VIDC_ERR, "CORE%d_NOC_ERR_ERRLOG2_HIGH: %#x\n", core_num, val);
+ val = __read_register(device, vcodec_core_video_noc_base_offs +
+ VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG3_LOW_OFFS);
+ dprintk(VIDC_ERR, "CORE%d_NOC_ERR_ERRLOG3_LOW: %#x\n", core_num, val);
+ val = __read_register(device, vcodec_core_video_noc_base_offs +
+ VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG3_HIGH_OFFS);
+ dprintk(VIDC_ERR, "CORE%d_NOC_ERR_ERRLOG3_HIGH: %#x\n", core_num, val);
+}
+
static int venus_hfi_noc_error_info(void *dev)
{
struct venus_hfi_device *device;
- u32 val = 0;
+ const u32 core0 = 0, core1 = 1;
if (!dev) {
dprintk(VIDC_ERR, "%s: null device\n", __func__);
@@ -4296,44 +4351,13 @@
mutex_lock(&device->lock);
dprintk(VIDC_ERR, "%s: non error information\n", __func__);
- val = __read_register(device, 0x0C500);
- dprintk(VIDC_ERR, "NOC_ERR_SWID_LOW(0x00AA0C500): %#x\n", val);
+ if (__read_register(device, VCODEC_CORE0_VIDEO_NOC_BASE_OFFS +
+ VCODEC_COREX_VIDEO_NOC_ERR_ERRVLD_LOW_OFFS))
+ __noc_error_info(device, core0);
- val = __read_register(device, 0x0C504);
- dprintk(VIDC_ERR, "NOC_ERR_SWID_HIGH(0x00AA0C504): %#x\n", val);
-
- val = __read_register(device, 0x0C508);
- dprintk(VIDC_ERR, "NOC_ERR_MAINCTL_LOW(0x00AA0C508): %#x\n", val);
-
- val = __read_register(device, 0x0C510);
- dprintk(VIDC_ERR, "NOC_ERR_ERRVLD_LOW(0x00AA0C510): %#x\n", val);
-
- val = __read_register(device, 0x0C518);
- dprintk(VIDC_ERR, "NOC_ERR_ERRCLR_LOW(0x00AA0C518): %#x\n", val);
-
- val = __read_register(device, 0x0C520);
- dprintk(VIDC_ERR, "NOC_ERR_ERRLOG0_LOW(0x00AA0C520): %#x\n", val);
-
- val = __read_register(device, 0x0C524);
- dprintk(VIDC_ERR, "NOC_ERR_ERRLOG0_HIGH(0x00AA0C524): %#x\n", val);
-
- val = __read_register(device, 0x0C528);
- dprintk(VIDC_ERR, "NOC_ERR_ERRLOG1_LOW(0x00AA0C528): %#x\n", val);
-
- val = __read_register(device, 0x0C52C);
- dprintk(VIDC_ERR, "NOC_ERR_ERRLOG1_HIGH(0x00AA0C52C): %#x\n", val);
-
- val = __read_register(device, 0x0C530);
- dprintk(VIDC_ERR, "NOC_ERR_ERRLOG2_LOW(0x00AA0C530): %#x\n", val);
-
- val = __read_register(device, 0x0C534);
- dprintk(VIDC_ERR, "NOC_ERR_ERRLOG2_HIGH(0x00AA0C534): %#x\n", val);
-
- val = __read_register(device, 0x0C538);
- dprintk(VIDC_ERR, "NOC_ERR_ERRLOG3_LOW(0x00AA0C538): %#x\n", val);
-
- val = __read_register(device, 0x0C53C);
- dprintk(VIDC_ERR, "NOC_ERR_ERRLOG3_HIGH(0x00AA0C53C): %#x\n", val);
+ if (__read_register(device, VCODEC_CORE1_VIDEO_NOC_BASE_OFFS +
+ VCODEC_COREX_VIDEO_NOC_ERR_ERRVLD_LOW_OFFS))
+ __noc_error_info(device, core1);
mutex_unlock(&device->lock);
diff --git a/drivers/media/platform/msm/vidc/vidc_hfi_io.h b/drivers/media/platform/msm/vidc/vidc_hfi_io.h
index fc32d73..3433483 100644
--- a/drivers/media/platform/msm/vidc/vidc_hfi_io.h
+++ b/drivers/media/platform/msm/vidc/vidc_hfi_io.h
@@ -190,4 +190,25 @@
#define VIDC_UC_REGION_ADDR 0x000D2064
#define VIDC_UC_REGION_SIZE 0x000D2068
+/*
+ * --------------------------------------------------------------------------
+ * MODULE: vcodec noc error log registers
+ * --------------------------------------------------------------------------
+ */
+#define VCODEC_CORE0_VIDEO_NOC_BASE_OFFS 0x00004000
+#define VCODEC_CORE1_VIDEO_NOC_BASE_OFFS 0x0000C000
+#define VCODEC_COREX_VIDEO_NOC_ERR_SWID_LOW_OFFS 0x0500
+#define VCODEC_COREX_VIDEO_NOC_ERR_SWID_HIGH_OFFS 0x0504
+#define VCODEC_COREX_VIDEO_NOC_ERR_MAINCTL_LOW_OFFS 0x0508
+#define VCODEC_COREX_VIDEO_NOC_ERR_ERRVLD_LOW_OFFS 0x0510
+#define VCODEC_COREX_VIDEO_NOC_ERR_ERRCLR_LOW_OFFS 0x0518
+#define VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG0_LOW_OFFS 0x0520
+#define VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG0_HIGH_OFFS 0x0524
+#define VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG1_LOW_OFFS 0x0528
+#define VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG1_HIGH_OFFS 0x052C
+#define VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG2_LOW_OFFS 0x0530
+#define VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG2_HIGH_OFFS 0x0534
+#define VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG3_LOW_OFFS 0x0538
+#define VCODEC_COREX_VIDEO_NOC_ERR_ERRLOG3_HIGH_OFFS 0x053C
+
#endif
diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c
index 7077b30..7567f86 100644
--- a/drivers/misc/qseecom.c
+++ b/drivers/misc/qseecom.c
@@ -3126,6 +3126,7 @@
struct qseecom_send_cmd_req *req)
{
int ret = 0;
+ int ret2 = 0;
u32 reqd_len_sb_in = 0;
struct qseecom_client_send_data_ireq send_data_req = {0};
struct qseecom_client_send_data_64bit_ireq send_data_req_64bit = {0};
@@ -3224,32 +3225,38 @@
if (ret) {
pr_err("scm_call() failed with err: %d (app_id = %d)\n",
ret, data->client.app_id);
- return ret;
+ goto exit;
}
if (qseecom.qsee_reentrancy_support) {
ret = __qseecom_process_reentrancy(&resp, ptr_app, data);
+ if (ret)
+ goto exit;
} else {
if (resp.result == QSEOS_RESULT_INCOMPLETE) {
ret = __qseecom_process_incomplete_cmd(data, &resp);
if (ret) {
pr_err("process_incomplete_cmd failed err: %d\n",
ret);
- return ret;
+ goto exit;
}
} else {
if (resp.result != QSEOS_RESULT_SUCCESS) {
pr_err("Response result %d not supported\n",
resp.result);
ret = -EINVAL;
+ goto exit;
}
}
}
- ret = msm_ion_do_cache_op(qseecom.ion_clnt, data->client.ihandle,
+exit:
+ ret2 = msm_ion_do_cache_op(qseecom.ion_clnt, data->client.ihandle,
data->client.sb_virt, data->client.sb_length,
ION_IOC_INV_CACHES);
- if (ret)
- pr_err("cache operation failed %d\n", ret);
+ if (ret2) {
+ pr_err("cache operation failed %d\n", ret2);
+ return ret2;
+ }
return ret;
}
@@ -6575,6 +6582,7 @@
bool found_app = false;
unsigned long flags;
int ret = 0;
+ int ret2 = 0;
uint32_t reqd_len_sb_in = 0;
void *cmd_buf = NULL;
size_t cmd_len;
@@ -6684,43 +6692,47 @@
if (ret) {
pr_err("scm_call() failed with err: %d (app_id = %d)\n",
ret, data->client.app_id);
- return ret;
+ goto exit;
}
if (qseecom.qsee_reentrancy_support) {
ret = __qseecom_process_reentrancy(&resp, ptr_app, data);
+ if (ret)
+ goto exit;
} else {
if (resp.result == QSEOS_RESULT_INCOMPLETE) {
ret = __qseecom_process_incomplete_cmd(data, &resp);
if (ret) {
pr_err("process_incomplete_cmd failed err: %d\n",
ret);
- return ret;
+ goto exit;
}
} else {
if (resp.result != QSEOS_RESULT_SUCCESS) {
pr_err("Response result %d not supported\n",
resp.result);
ret = -EINVAL;
+ goto exit;
}
}
}
- ret = msm_ion_do_cache_op(qseecom.ion_clnt, data->client.ihandle,
+exit:
+ ret2 = msm_ion_do_cache_op(qseecom.ion_clnt, data->client.ihandle,
data->client.sb_virt, data->client.sb_length,
ION_IOC_INV_CACHES);
- if (ret) {
+ if (ret2) {
pr_err("cache operation failed %d\n", ret);
- return ret;
+ return ret2;
}
if ((cmd_id == QSEOS_TEE_OPEN_SESSION) ||
(cmd_id == QSEOS_TEE_REQUEST_CANCELLATION)) {
- ret = __qseecom_update_qteec_req_buf(
+ ret2 = __qseecom_update_qteec_req_buf(
(struct qseecom_qteec_modfd_req *)req, data, true);
- if (ret)
- return ret;
+ if (ret2)
+ return ret2;
}
- return 0;
+ return ret;
}
static int qseecom_qteec_open_session(struct qseecom_dev_handle *data,
diff --git a/drivers/mmc/host/cmdq_hci.c b/drivers/mmc/host/cmdq_hci.c
index 82ff1a5..591d6b2 100644
--- a/drivers/mmc/host/cmdq_hci.c
+++ b/drivers/mmc/host/cmdq_hci.c
@@ -220,6 +220,10 @@
static void cmdq_dumpregs(struct cmdq_host *cq_host)
{
struct mmc_host *mmc = cq_host->mmc;
+ int offset = 0;
+
+ if (cq_host->offset_changed)
+ offset = CQ_V5_VENDOR_CFG;
MMC_TRACE(mmc,
"%s: 0x0C=0x%08x 0x10=0x%08x 0x14=0x%08x 0x18=0x%08x 0x28=0x%08x 0x2C=0x%08x 0x30=0x%08x 0x34=0x%08x 0x54=0x%08x 0x58=0x%08x 0x5C=0x%08x 0x48=0x%08x\n",
@@ -266,7 +270,7 @@
cmdq_readl(cq_host, CQCRI),
cmdq_readl(cq_host, CQCRA));
pr_err(DRV_NAME": Vendor cfg 0x%08x\n",
- cmdq_readl(cq_host, CQ_VENDOR_CFG));
+ cmdq_readl(cq_host, CQ_VENDOR_CFG + offset));
pr_err(DRV_NAME ": ===========================================\n");
cmdq_dump_task_history(cq_host);
@@ -407,6 +411,12 @@
cq_host->caps |= CMDQ_CAP_CRYPTO_SUPPORT |
CMDQ_TASK_DESC_SZ_128;
cqcfg |= CQ_ICE_ENABLE;
+ /*
+ * For SDHC v5.0 onwards, ICE 3.0 specific registers are added
+ * in CQ register space, due to which few CQ registers are
+ * shifted. Set offset_changed boolean to use updated address.
+ */
+ cq_host->offset_changed = true;
}
cmdq_writel(cq_host, cqcfg, CQCFG);
@@ -841,16 +851,29 @@
{
struct mmc_request *mrq;
struct cmdq_host *cq_host = (struct cmdq_host *)mmc_cmdq_private(mmc);
+ int offset = 0;
+ int err = 0;
+ if (cq_host->offset_changed)
+ offset = CQ_V5_VENDOR_CFG;
mrq = get_req_by_tag(cq_host, tag);
if (tag == cq_host->dcmd_slot)
mrq->cmd->resp[0] = cmdq_readl(cq_host, CQCRDCT);
if (mrq->cmdq_req->cmdq_req_flags & DCMD)
- cmdq_writel(cq_host, cmdq_readl(cq_host, CQ_VENDOR_CFG) |
- CMDQ_SEND_STATUS_TRIGGER, CQ_VENDOR_CFG);
+ cmdq_writel(cq_host,
+ cmdq_readl(cq_host, CQ_VENDOR_CFG + offset) |
+ CMDQ_SEND_STATUS_TRIGGER, CQ_VENDOR_CFG + offset);
cmdq_runtime_pm_put(cq_host);
+
+ if (cq_host->ops->crypto_cfg_end) {
+ err = cq_host->ops->crypto_cfg_end(mmc, mrq);
+ if (err) {
+ pr_err("%s: failed to end ice config: err %d tag %d\n",
+ mmc_hostname(mmc), err, tag);
+ }
+ }
if (!(cq_host->caps & CMDQ_CAP_CRYPTO_SUPPORT) &&
cq_host->ops->crypto_cfg_reset)
cq_host->ops->crypto_cfg_reset(mmc, tag);
diff --git a/drivers/mmc/host/cmdq_hci.h b/drivers/mmc/host/cmdq_hci.h
index 551a7c5..1aabce9 100644
--- a/drivers/mmc/host/cmdq_hci.h
+++ b/drivers/mmc/host/cmdq_hci.h
@@ -145,6 +145,11 @@
#define DAT_ADDR_LO(x) ((x & 0xFFFFFFFF) << 32)
#define DAT_ADDR_HI(x) ((x & 0xFFFFFFFF) << 0)
+/*
+ * Add new macro for updated CQ vendor specific
+ * register address for SDHC v5.0 onwards.
+ */
+#define CQ_V5_VENDOR_CFG 0x900
#define CQ_VENDOR_CFG 0x100
#define CMDQ_SEND_STATUS_TRIGGER (1 << 31)
@@ -177,6 +182,7 @@
bool enabled;
bool halted;
bool init_done;
+ bool offset_changed;
u8 *desc_base;
@@ -218,6 +224,7 @@
void (*post_cqe_halt)(struct mmc_host *mmc);
int (*crypto_cfg)(struct mmc_host *mmc, struct mmc_request *mrq,
u32 slot, u64 *ice_ctx);
+ int (*crypto_cfg_end)(struct mmc_host *mmc, struct mmc_request *mrq);
void (*crypto_cfg_reset)(struct mmc_host *mmc, unsigned int slot);
};
diff --git a/drivers/mmc/host/sdhci-msm-ice.c b/drivers/mmc/host/sdhci-msm-ice.c
index 29eaff4..f86ce5b 100644
--- a/drivers/mmc/host/sdhci-msm-ice.c
+++ b/drivers/mmc/host/sdhci-msm-ice.c
@@ -377,7 +377,7 @@
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
struct sdhci_msm_host *msm_host = pltfm_host->priv;
int err = 0;
- short key_index;
+ short key_index = 0;
sector_t lba = 0;
unsigned int bypass = SDHCI_MSM_ICE_ENABLE_BYPASS;
struct request *req;
@@ -414,6 +414,37 @@
return 0;
}
+int sdhci_msm_ice_cfg_end(struct sdhci_host *host, struct mmc_request *mrq)
+{
+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+ struct sdhci_msm_host *msm_host = pltfm_host->priv;
+ int err = 0;
+ struct request *req;
+
+ if (!host->is_crypto_en)
+ return 0;
+
+ if (msm_host->ice.state != SDHCI_MSM_ICE_STATE_ACTIVE) {
+ pr_err("%s: ice is in invalid state %d\n",
+ mmc_hostname(host->mmc), msm_host->ice.state);
+ return -EINVAL;
+ }
+
+ req = mrq->req;
+ if (req) {
+ if (msm_host->ice.vops->config_end) {
+ err = msm_host->ice.vops->config_end(req);
+ if (err) {
+ pr_err("%s: ice config end failed %d\n",
+ mmc_hostname(host->mmc), err);
+ return err;
+ }
+ }
+ }
+
+ return 0;
+}
+
int sdhci_msm_ice_reset(struct sdhci_host *host)
{
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
diff --git a/drivers/mmc/host/sdhci-msm-ice.h b/drivers/mmc/host/sdhci-msm-ice.h
index 1afd1a9..6296174 100644
--- a/drivers/mmc/host/sdhci-msm-ice.h
+++ b/drivers/mmc/host/sdhci-msm-ice.h
@@ -107,6 +107,7 @@
u32 slot);
int sdhci_msm_ice_cmdq_cfg(struct sdhci_host *host,
struct mmc_request *mrq, u32 slot, u64 *ice_ctx);
+int sdhci_msm_ice_cfg_end(struct sdhci_host *host, struct mmc_request *mrq);
int sdhci_msm_ice_reset(struct sdhci_host *host);
int sdhci_msm_ice_resume(struct sdhci_host *host);
int sdhci_msm_ice_suspend(struct sdhci_host *host);
@@ -143,6 +144,11 @@
{
return 0;
}
+static inline int sdhci_msm_ice_cfg_end(struct sdhci_host *host,
+ struct mmc_request *mrq)
+{
+ return 0;
+}
inline int sdhci_msm_ice_reset(struct sdhci_host *host)
{
return 0;
diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
index d93de2e..55d9cf5 100644
--- a/drivers/mmc/host/sdhci-msm.c
+++ b/drivers/mmc/host/sdhci-msm.c
@@ -1902,8 +1902,16 @@
dev_err(dev, "Invalid clock table\n");
goto out;
}
+ if (ice_clk_table_len != 2) {
+ dev_err(dev, "Need max and min frequencies in the table\n");
+ goto out;
+ }
pdata->sup_ice_clk_table = ice_clk_table;
pdata->sup_ice_clk_cnt = ice_clk_table_len;
+ pdata->ice_clk_max = pdata->sup_ice_clk_table[0];
+ pdata->ice_clk_min = pdata->sup_ice_clk_table[1];
+ dev_dbg(dev, "supported ICE clock rates (Hz): max: %u min: %u\n",
+ pdata->ice_clk_max, pdata->ice_clk_min);
}
pdata->vreg_data = devm_kzalloc(dev, sizeof(struct
@@ -3408,6 +3416,8 @@
/* registers offset changed starting from 4.2.0 */
int offset = minor >= SDHCI_MSM_VER_420 ? 0 : 0x48;
+ if (cq_host->offset_changed)
+ offset += CQ_V5_VENDOR_CFG;
pr_err("---- Debug RAM dump ----\n");
pr_err(DRV_NAME ": Debug RAM wrap-around: 0x%08x | Debug RAM overlap: 0x%08x\n",
cmdq_readl(cq_host, CQ_CMD_DBG_RAM_WA + offset),
@@ -4113,9 +4123,36 @@
return max_curr;
}
+static int sdhci_msm_notify_load(struct sdhci_host *host, enum mmc_load state)
+{
+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+ struct sdhci_msm_host *msm_host = pltfm_host->priv;
+ int ret = 0;
+ u32 clk_rate = 0;
+
+ if (!IS_ERR(msm_host->ice_clk)) {
+ clk_rate = (state == MMC_LOAD_LOW) ?
+ msm_host->pdata->ice_clk_min :
+ msm_host->pdata->ice_clk_max;
+ if (msm_host->ice_clk_rate == clk_rate)
+ return 0;
+ pr_debug("%s: changing ICE clk rate to %u\n",
+ mmc_hostname(host->mmc), clk_rate);
+ ret = clk_set_rate(msm_host->ice_clk, clk_rate);
+ if (ret) {
+ pr_err("%s: ICE_CLK rate set failed (%d) for %u\n",
+ mmc_hostname(host->mmc), ret, clk_rate);
+ return ret;
+ }
+ msm_host->ice_clk_rate = clk_rate;
+ }
+ return 0;
+}
+
static struct sdhci_ops sdhci_msm_ops = {
.crypto_engine_cfg = sdhci_msm_ice_cfg,
.crypto_engine_cmdq_cfg = sdhci_msm_ice_cmdq_cfg,
+ .crypto_engine_cfg_end = sdhci_msm_ice_cfg_end,
.crypto_cfg_reset = sdhci_msm_ice_cfg_reset,
.crypto_engine_reset = sdhci_msm_ice_reset,
.set_uhs_signaling = sdhci_msm_set_uhs_signaling,
@@ -4139,6 +4176,7 @@
.pre_req = sdhci_msm_pre_req,
.post_req = sdhci_msm_post_req,
.get_current_limit = sdhci_msm_get_current_limit,
+ .notify_load = sdhci_msm_notify_load,
};
static void sdhci_set_default_hw_caps(struct sdhci_msm_host *msm_host,
@@ -4351,7 +4389,7 @@
*/
dev_err(&pdev->dev, "%s: required ICE device not probed yet err = %d\n",
__func__, ret);
- goto out_host_free;
+ goto pltfm_free;
} else if (ret == -ENODEV) {
/*
@@ -4363,7 +4401,7 @@
} else if (ret) {
dev_err(&pdev->dev, "%s: sdhci_msm_ice_get_dev failed %d\n",
__func__, ret);
- goto out_host_free;
+ goto pltfm_free;
}
/* Extract platform data */
@@ -4436,11 +4474,11 @@
if (!IS_ERR(msm_host->ice_clk)) {
/* ICE core has only one clock frequency for now */
ret = clk_set_rate(msm_host->ice_clk,
- msm_host->pdata->sup_ice_clk_table[0]);
+ msm_host->pdata->ice_clk_max);
if (ret) {
dev_err(&pdev->dev, "ICE_CLK rate set failed (%d) for %u\n",
ret,
- msm_host->pdata->sup_ice_clk_table[0]);
+ msm_host->pdata->ice_clk_max);
goto pclk_disable;
}
ret = clk_prepare_enable(msm_host->ice_clk);
@@ -4448,7 +4486,7 @@
goto pclk_disable;
msm_host->ice_clk_rate =
- msm_host->pdata->sup_clk_table[0];
+ msm_host->pdata->ice_clk_max;
}
}
diff --git a/drivers/mmc/host/sdhci-msm.h b/drivers/mmc/host/sdhci-msm.h
index cdbaaa9..7c0b873 100644
--- a/drivers/mmc/host/sdhci-msm.h
+++ b/drivers/mmc/host/sdhci-msm.h
@@ -151,6 +151,8 @@
unsigned char sup_ice_clk_cnt;
struct sdhci_msm_pm_qos_data pm_qos_data;
bool sdr104_wa;
+ u32 ice_clk_max;
+ u32 ice_clk_min;
};
struct sdhci_msm_bus_vote {
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 7f13f07..4476e51 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -1785,6 +1785,22 @@
return err;
}
+static int sdhci_crypto_cfg_end(struct sdhci_host *host,
+ struct mmc_request *mrq)
+{
+ int err = 0;
+
+ if (host->ops->crypto_engine_cfg_end) {
+ err = host->ops->crypto_engine_cfg_end(host, mrq);
+ if (err) {
+ pr_err("%s: failed to configure crypto\n",
+ mmc_hostname(host->mmc));
+ return err;
+ }
+ }
+ return 0;
+}
+
static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
{
struct sdhci_host *host;
@@ -2876,6 +2892,7 @@
mmiowb();
spin_unlock_irqrestore(&host->lock, flags);
+ sdhci_crypto_cfg_end(host, mrq);
mmc_request_done(host->mmc, mrq);
return false;
@@ -3806,6 +3823,17 @@
return err;
}
+static int sdhci_cmdq_crypto_cfg_end(struct mmc_host *mmc,
+ struct mmc_request *mrq)
+{
+ struct sdhci_host *host = mmc_priv(mmc);
+
+ if (!host->is_crypto_en)
+ return 0;
+
+ return sdhci_crypto_cfg_end(host, mrq);
+}
+
static void sdhci_cmdq_crypto_cfg_reset(struct mmc_host *mmc, unsigned int slot)
{
struct sdhci_host *host = mmc_priv(mmc);
@@ -3868,6 +3896,12 @@
return 0;
}
+static int sdhci_cmdq_crypto_cfg_end(struct mmc_host *mmc,
+ struct mmc_request *mrq)
+{
+ return 0;
+}
+
static void sdhci_cmdq_crypto_cfg_reset(struct mmc_host *mmc, unsigned int slot)
{
@@ -3884,6 +3918,7 @@
.post_cqe_halt = sdhci_cmdq_post_cqe_halt,
.set_transfer_params = sdhci_cmdq_set_transfer_params,
.crypto_cfg = sdhci_cmdq_crypto_cfg,
+ .crypto_cfg_end = sdhci_cmdq_crypto_cfg_end,
.crypto_cfg_reset = sdhci_cmdq_crypto_cfg_reset,
};
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index a463e45..2b67d0a 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -673,6 +673,8 @@
struct mmc_request *mrq, u32 slot);
int (*crypto_engine_cmdq_cfg)(struct sdhci_host *host,
struct mmc_request *mrq, u32 slot, u64 *ice_ctx);
+ int (*crypto_engine_cfg_end)(struct sdhci_host *host,
+ struct mmc_request *mrq);
int (*crypto_engine_reset)(struct sdhci_host *host);
void (*crypto_cfg_reset)(struct sdhci_host *host, unsigned int slot);
void (*set_uhs_signaling)(struct sdhci_host *host, unsigned int uhs);
diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
index d7f724b..0c84ee8 100644
--- a/drivers/mtd/nand/mxc_nand.c
+++ b/drivers/mtd/nand/mxc_nand.c
@@ -877,6 +877,8 @@
}
}
+#define MXC_V1_ECCBYTES 5
+
static int mxc_v1_ooblayout_ecc(struct mtd_info *mtd, int section,
struct mtd_oob_region *oobregion)
{
@@ -886,7 +888,7 @@
return -ERANGE;
oobregion->offset = (section * 16) + 6;
- oobregion->length = nand_chip->ecc.bytes;
+ oobregion->length = MXC_V1_ECCBYTES;
return 0;
}
@@ -908,8 +910,7 @@
oobregion->length = 4;
}
} else {
- oobregion->offset = ((section - 1) * 16) +
- nand_chip->ecc.bytes + 6;
+ oobregion->offset = ((section - 1) * 16) + MXC_V1_ECCBYTES + 6;
if (section < nand_chip->ecc.steps)
oobregion->length = (section * 16) + 6 -
oobregion->offset;
diff --git a/drivers/mtd/nand/qcom_nandc.c b/drivers/mtd/nand/qcom_nandc.c
index 57d483a..6f0fd15 100644
--- a/drivers/mtd/nand/qcom_nandc.c
+++ b/drivers/mtd/nand/qcom_nandc.c
@@ -109,7 +109,11 @@
#define READ_ADDR 0
/* NAND_DEV_CMD_VLD bits */
-#define READ_START_VLD 0
+#define READ_START_VLD BIT(0)
+#define READ_STOP_VLD BIT(1)
+#define WRITE_START_VLD BIT(2)
+#define ERASE_START_VLD BIT(3)
+#define SEQ_READ_START_VLD BIT(4)
/* NAND_EBI2_ECC_BUF_CFG bits */
#define NUM_STEPS 0
@@ -148,6 +152,10 @@
#define FETCH_ID 0xb
#define RESET_DEVICE 0xd
+/* Default Value for NAND_DEV_CMD_VLD */
+#define NAND_DEV_CMD_VLD_VAL (READ_START_VLD | WRITE_START_VLD | \
+ ERASE_START_VLD | SEQ_READ_START_VLD)
+
/*
* the NAND controller performs reads/writes with ECC in 516 byte chunks.
* the driver calls the chunks 'step' or 'codeword' interchangeably
@@ -672,8 +680,7 @@
/* configure CMD1 and VLD for ONFI param probing */
nandc_set_reg(nandc, NAND_DEV_CMD_VLD,
- (nandc->vld & ~(1 << READ_START_VLD))
- | 0 << READ_START_VLD);
+ (nandc->vld & ~READ_START_VLD));
nandc_set_reg(nandc, NAND_DEV_CMD1,
(nandc->cmd1 & ~(0xFF << READ_ADDR))
| NAND_CMD_PARAM << READ_ADDR);
@@ -1893,7 +1900,7 @@
| wide_bus << WIDE_FLASH
| 1 << DEV0_CFG1_ECC_DISABLE;
- host->ecc_bch_cfg = host->bch_enabled << ECC_CFG_ECC_DISABLE
+ host->ecc_bch_cfg = !host->bch_enabled << ECC_CFG_ECC_DISABLE
| 0 << ECC_SW_RESET
| host->cw_data << ECC_NUM_DATA_BYTES
| 1 << ECC_FORCE_CLK_OPEN
@@ -1972,13 +1979,14 @@
{
/* kill onenand */
nandc_write(nandc, SFLASHC_BURST_CFG, 0);
+ nandc_write(nandc, NAND_DEV_CMD_VLD, NAND_DEV_CMD_VLD_VAL);
/* enable ADM DMA */
nandc_write(nandc, NAND_FLASH_CHIP_SELECT, DM_EN);
/* save the original values of these registers */
nandc->cmd1 = nandc_read(nandc, NAND_DEV_CMD1);
- nandc->vld = nandc_read(nandc, NAND_DEV_CMD_VLD);
+ nandc->vld = NAND_DEV_CMD_VLD_VAL;
return 0;
}
diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
index 972b5e2..366d3dc 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -1852,6 +1852,12 @@
goto err_wmi_detach;
}
+ /* If firmware indicates Full Rx Reorder support it must be used in a
+ * slightly different manner. Let HTT code know.
+ */
+ ar->htt.rx_ring.in_ord_rx = !!(test_bit(WMI_SERVICE_RX_FULL_REORDER,
+ ar->wmi.svc_map));
+
status = ath10k_htt_rx_alloc(&ar->htt);
if (status) {
ath10k_err(ar, "failed to alloc htt rx: %d\n", status);
@@ -1964,12 +1970,6 @@
}
}
- /* If firmware indicates Full Rx Reorder support it must be used in a
- * slightly different manner. Let HTT code know.
- */
- ar->htt.rx_ring.in_ord_rx = !!(test_bit(WMI_SERVICE_RX_FULL_REORDER,
- ar->wmi.svc_map));
-
status = ath10k_htt_rx_ring_refill(ar);
if (status) {
ath10k_err(ar, "failed to refill htt rx ring: %d\n", status);
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
index 2f8134b..177fd5b 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
@@ -429,6 +429,7 @@
{IWL_PCI_DEVICE(0x095B, 0x520A, iwl7265_2ac_cfg)},
{IWL_PCI_DEVICE(0x095A, 0x9000, iwl7265_2ac_cfg)},
{IWL_PCI_DEVICE(0x095A, 0x9400, iwl7265_2ac_cfg)},
+ {IWL_PCI_DEVICE(0x095A, 0x9E10, iwl7265_2ac_cfg)},
/* 8000 Series */
{IWL_PCI_DEVICE(0x24F3, 0x0010, iwl8260_2ac_cfg)},
diff --git a/drivers/net/wireless/marvell/mwifiex/cfg80211.c b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
index afdbbf5..8677a53 100644
--- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
@@ -4188,7 +4188,7 @@
if (adapter->config_bands & BAND_A)
n_channels_a = mwifiex_band_5ghz.n_channels;
- adapter->num_in_chan_stats = max_t(u32, n_channels_bg, n_channels_a);
+ adapter->num_in_chan_stats = n_channels_bg + n_channels_a;
adapter->chan_stats = vmalloc(sizeof(*adapter->chan_stats) *
adapter->num_in_chan_stats);
diff --git a/drivers/net/wireless/marvell/mwifiex/scan.c b/drivers/net/wireless/marvell/mwifiex/scan.c
index 97c9765..78d59a6 100644
--- a/drivers/net/wireless/marvell/mwifiex/scan.c
+++ b/drivers/net/wireless/marvell/mwifiex/scan.c
@@ -2479,6 +2479,12 @@
sizeof(struct mwifiex_chan_stats);
for (i = 0 ; i < num_chan; i++) {
+ if (adapter->survey_idx >= adapter->num_in_chan_stats) {
+ mwifiex_dbg(adapter, WARN,
+ "FW reported too many channel results (max %d)\n",
+ adapter->num_in_chan_stats);
+ return;
+ }
chan_stats.chan_num = fw_chan_stats->chan_num;
chan_stats.bandcfg = fw_chan_stats->bandcfg;
chan_stats.flags = fw_chan_stats->flags;
diff --git a/drivers/net/wireless/realtek/rtlwifi/pci.c b/drivers/net/wireless/realtek/rtlwifi/pci.c
index 5be4fc9..75ffeaa 100644
--- a/drivers/net/wireless/realtek/rtlwifi/pci.c
+++ b/drivers/net/wireless/realtek/rtlwifi/pci.c
@@ -2269,7 +2269,7 @@
/* find adapter */
if (!_rtl_pci_find_adapter(pdev, hw)) {
err = -ENODEV;
- goto fail3;
+ goto fail2;
}
/* Init IO handler */
@@ -2339,10 +2339,10 @@
pci_set_drvdata(pdev, NULL);
rtl_deinit_core(hw);
+fail2:
if (rtlpriv->io.pci_mem_start != 0)
pci_iounmap(pdev, (void __iomem *)rtlpriv->io.pci_mem_start);
-fail2:
pci_release_regions(pdev);
complete(&rtlpriv->firmware_loading_complete);
diff --git a/drivers/nvme/host/fabrics.c b/drivers/nvme/host/fabrics.c
index 5a3f008..eef1a68 100644
--- a/drivers/nvme/host/fabrics.c
+++ b/drivers/nvme/host/fabrics.c
@@ -77,7 +77,7 @@
kref_init(&host->ref);
uuid_be_gen(&host->id);
snprintf(host->nqn, NVMF_NQN_SIZE,
- "nqn.2014-08.org.nvmexpress:NVMf:uuid:%pUb", &host->id);
+ "nqn.2014-08.org.nvmexpress:uuid:%pUb", &host->id);
mutex_lock(&nvmf_hosts_mutex);
list_add_tail(&host->list, &nvmf_hosts);
diff --git a/drivers/pinctrl/qcom/Kconfig b/drivers/pinctrl/qcom/Kconfig
index 8da8571..d39a17f 100644
--- a/drivers/pinctrl/qcom/Kconfig
+++ b/drivers/pinctrl/qcom/Kconfig
@@ -79,6 +79,16 @@
This is the pinctrl, pinmux, pinconf and gpiolib driver for the
Qualcomm TLMM block found on the Qualcomm 8916 platform.
+config PINCTRL_MSM8953
+ tristate "Qualcomm Technologies Inc MSM8953 pin controller driver"
+ depends on GPIOLIB && OF
+ select PINCTRL_MSM
+ help
+ This is the pinctrl, pinmux, pinconf and gpiolib driver for the
+ Qualcomm Technologies Inc TLMM block found on the Qualcomm
+ Technologies Inc MSM8953 platform.
+ If unsure say N.
+
config PINCTRL_SDM845
tristate "Qualcomm Technologies Inc SDM845 pin controller driver"
depends on GPIOLIB && OF
diff --git a/drivers/pinctrl/qcom/Makefile b/drivers/pinctrl/qcom/Makefile
index 392ed2a..c9f5c11 100644
--- a/drivers/pinctrl/qcom/Makefile
+++ b/drivers/pinctrl/qcom/Makefile
@@ -11,6 +11,7 @@
obj-$(CONFIG_PINCTRL_MSM8996) += pinctrl-msm8996.o
obj-$(CONFIG_PINCTRL_QDF2XXX) += pinctrl-qdf2xxx.o
obj-$(CONFIG_PINCTRL_MDM9615) += pinctrl-mdm9615.o
+obj-$(CONFIG_PINCTRL_MSM8953) += pinctrl-msm8953.o
obj-$(CONFIG_PINCTRL_QCOM_SPMI_PMIC) += pinctrl-spmi-gpio.o
obj-$(CONFIG_PINCTRL_QCOM_SPMI_PMIC) += pinctrl-spmi-mpp.o
obj-$(CONFIG_PINCTRL_QCOM_SSBI_PMIC) += pinctrl-ssbi-gpio.o
diff --git a/drivers/pinctrl/qcom/pinctrl-msm8953.c b/drivers/pinctrl/qcom/pinctrl-msm8953.c
new file mode 100644
index 0000000..ba1cad0
--- /dev/null
+++ b/drivers/pinctrl/qcom/pinctrl-msm8953.c
@@ -0,0 +1,1686 @@
+/*
+ * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pinctrl/pinctrl.h>
+
+#include "pinctrl-msm.h"
+
+#define FUNCTION(fname) \
+ [msm_mux_##fname] = { \
+ .name = #fname, \
+ .groups = fname##_groups, \
+ .ngroups = ARRAY_SIZE(fname##_groups), \
+ }
+
+#define REG_SIZE 0x1000
+#define PINGROUP(id, f1, f2, f3, f4, f5, f6, f7, f8, f9) \
+ { \
+ .name = "gpio" #id, \
+ .pins = gpio##id##_pins, \
+ .npins = (unsigned int)ARRAY_SIZE(gpio##id##_pins), \
+ .funcs = (int[]){ \
+ msm_mux_gpio, /* gpio mode */ \
+ msm_mux_##f1, \
+ msm_mux_##f2, \
+ msm_mux_##f3, \
+ msm_mux_##f4, \
+ msm_mux_##f5, \
+ msm_mux_##f6, \
+ msm_mux_##f7, \
+ msm_mux_##f8, \
+ msm_mux_##f9 \
+ }, \
+ .nfuncs = 10, \
+ .ctl_reg = REG_SIZE * id, \
+ .io_reg = 0x4 + REG_SIZE * id, \
+ .intr_cfg_reg = 0x8 + REG_SIZE * id, \
+ .intr_status_reg = 0xc + REG_SIZE * id, \
+ .intr_target_reg = 0x8 + REG_SIZE * id, \
+ .mux_bit = 2, \
+ .pull_bit = 0, \
+ .drv_bit = 6, \
+ .oe_bit = 9, \
+ .in_bit = 0, \
+ .out_bit = 1, \
+ .intr_enable_bit = 0, \
+ .intr_status_bit = 0, \
+ .intr_target_bit = 5, \
+ .intr_target_kpss_val = 4, \
+ .intr_raw_status_bit = 4, \
+ .intr_polarity_bit = 1, \
+ .intr_detection_bit = 2, \
+ .intr_detection_width = 2, \
+ }
+
+#define SDC_QDSD_PINGROUP(pg_name, ctl, pull, drv) \
+ { \
+ .name = #pg_name, \
+ .pins = pg_name##_pins, \
+ .npins = (unsigned int)ARRAY_SIZE(pg_name##_pins), \
+ .ctl_reg = ctl, \
+ .io_reg = 0, \
+ .intr_cfg_reg = 0, \
+ .intr_status_reg = 0, \
+ .intr_target_reg = 0, \
+ .mux_bit = -1, \
+ .pull_bit = pull, \
+ .drv_bit = drv, \
+ .oe_bit = -1, \
+ .in_bit = -1, \
+ .out_bit = -1, \
+ .intr_enable_bit = -1, \
+ .intr_status_bit = -1, \
+ .intr_target_bit = -1, \
+ .intr_raw_status_bit = -1, \
+ .intr_polarity_bit = -1, \
+ .intr_detection_bit = -1, \
+ .intr_detection_width = -1, \
+ }
+static const struct pinctrl_pin_desc msm8953_pins[] = {
+ PINCTRL_PIN(0, "GPIO_0"),
+ PINCTRL_PIN(1, "GPIO_1"),
+ PINCTRL_PIN(2, "GPIO_2"),
+ PINCTRL_PIN(3, "GPIO_3"),
+ PINCTRL_PIN(4, "GPIO_4"),
+ PINCTRL_PIN(5, "GPIO_5"),
+ PINCTRL_PIN(6, "GPIO_6"),
+ PINCTRL_PIN(7, "GPIO_7"),
+ PINCTRL_PIN(8, "GPIO_8"),
+ PINCTRL_PIN(9, "GPIO_9"),
+ PINCTRL_PIN(10, "GPIO_10"),
+ PINCTRL_PIN(11, "GPIO_11"),
+ PINCTRL_PIN(12, "GPIO_12"),
+ PINCTRL_PIN(13, "GPIO_13"),
+ PINCTRL_PIN(14, "GPIO_14"),
+ PINCTRL_PIN(15, "GPIO_15"),
+ PINCTRL_PIN(16, "GPIO_16"),
+ PINCTRL_PIN(17, "GPIO_17"),
+ PINCTRL_PIN(18, "GPIO_18"),
+ PINCTRL_PIN(19, "GPIO_19"),
+ PINCTRL_PIN(20, "GPIO_20"),
+ PINCTRL_PIN(21, "GPIO_21"),
+ PINCTRL_PIN(22, "GPIO_22"),
+ PINCTRL_PIN(23, "GPIO_23"),
+ PINCTRL_PIN(24, "GPIO_24"),
+ PINCTRL_PIN(25, "GPIO_25"),
+ PINCTRL_PIN(26, "GPIO_26"),
+ PINCTRL_PIN(27, "GPIO_27"),
+ PINCTRL_PIN(28, "GPIO_28"),
+ PINCTRL_PIN(29, "GPIO_29"),
+ PINCTRL_PIN(30, "GPIO_30"),
+ PINCTRL_PIN(31, "GPIO_31"),
+ PINCTRL_PIN(32, "GPIO_32"),
+ PINCTRL_PIN(33, "GPIO_33"),
+ PINCTRL_PIN(34, "GPIO_34"),
+ PINCTRL_PIN(35, "GPIO_35"),
+ PINCTRL_PIN(36, "GPIO_36"),
+ PINCTRL_PIN(37, "GPIO_37"),
+ PINCTRL_PIN(38, "GPIO_38"),
+ PINCTRL_PIN(39, "GPIO_39"),
+ PINCTRL_PIN(40, "GPIO_40"),
+ PINCTRL_PIN(41, "GPIO_41"),
+ PINCTRL_PIN(42, "GPIO_42"),
+ PINCTRL_PIN(43, "GPIO_43"),
+ PINCTRL_PIN(44, "GPIO_44"),
+ PINCTRL_PIN(45, "GPIO_45"),
+ PINCTRL_PIN(46, "GPIO_46"),
+ PINCTRL_PIN(47, "GPIO_47"),
+ PINCTRL_PIN(48, "GPIO_48"),
+ PINCTRL_PIN(49, "GPIO_49"),
+ PINCTRL_PIN(50, "GPIO_50"),
+ PINCTRL_PIN(51, "GPIO_51"),
+ PINCTRL_PIN(52, "GPIO_52"),
+ PINCTRL_PIN(53, "GPIO_53"),
+ PINCTRL_PIN(54, "GPIO_54"),
+ PINCTRL_PIN(55, "GPIO_55"),
+ PINCTRL_PIN(56, "GPIO_56"),
+ PINCTRL_PIN(57, "GPIO_57"),
+ PINCTRL_PIN(58, "GPIO_58"),
+ PINCTRL_PIN(59, "GPIO_59"),
+ PINCTRL_PIN(60, "GPIO_60"),
+ PINCTRL_PIN(61, "GPIO_61"),
+ PINCTRL_PIN(62, "GPIO_62"),
+ PINCTRL_PIN(63, "GPIO_63"),
+ PINCTRL_PIN(64, "GPIO_64"),
+ PINCTRL_PIN(65, "GPIO_65"),
+ PINCTRL_PIN(66, "GPIO_66"),
+ PINCTRL_PIN(67, "GPIO_67"),
+ PINCTRL_PIN(68, "GPIO_68"),
+ PINCTRL_PIN(69, "GPIO_69"),
+ PINCTRL_PIN(70, "GPIO_70"),
+ PINCTRL_PIN(71, "GPIO_71"),
+ PINCTRL_PIN(72, "GPIO_72"),
+ PINCTRL_PIN(73, "GPIO_73"),
+ PINCTRL_PIN(74, "GPIO_74"),
+ PINCTRL_PIN(75, "GPIO_75"),
+ PINCTRL_PIN(76, "GPIO_76"),
+ PINCTRL_PIN(77, "GPIO_77"),
+ PINCTRL_PIN(78, "GPIO_78"),
+ PINCTRL_PIN(79, "GPIO_79"),
+ PINCTRL_PIN(80, "GPIO_80"),
+ PINCTRL_PIN(81, "GPIO_81"),
+ PINCTRL_PIN(82, "GPIO_82"),
+ PINCTRL_PIN(83, "GPIO_83"),
+ PINCTRL_PIN(84, "GPIO_84"),
+ PINCTRL_PIN(85, "GPIO_85"),
+ PINCTRL_PIN(86, "GPIO_86"),
+ PINCTRL_PIN(87, "GPIO_87"),
+ PINCTRL_PIN(88, "GPIO_88"),
+ PINCTRL_PIN(89, "GPIO_89"),
+ PINCTRL_PIN(90, "GPIO_90"),
+ PINCTRL_PIN(91, "GPIO_91"),
+ PINCTRL_PIN(92, "GPIO_92"),
+ PINCTRL_PIN(93, "GPIO_93"),
+ PINCTRL_PIN(94, "GPIO_94"),
+ PINCTRL_PIN(95, "GPIO_95"),
+ PINCTRL_PIN(96, "GPIO_96"),
+ PINCTRL_PIN(97, "GPIO_97"),
+ PINCTRL_PIN(98, "GPIO_98"),
+ PINCTRL_PIN(99, "GPIO_99"),
+ PINCTRL_PIN(100, "GPIO_100"),
+ PINCTRL_PIN(101, "GPIO_101"),
+ PINCTRL_PIN(102, "GPIO_102"),
+ PINCTRL_PIN(103, "GPIO_103"),
+ PINCTRL_PIN(104, "GPIO_104"),
+ PINCTRL_PIN(105, "GPIO_105"),
+ PINCTRL_PIN(106, "GPIO_106"),
+ PINCTRL_PIN(107, "GPIO_107"),
+ PINCTRL_PIN(108, "GPIO_108"),
+ PINCTRL_PIN(109, "GPIO_109"),
+ PINCTRL_PIN(110, "GPIO_110"),
+ PINCTRL_PIN(111, "GPIO_111"),
+ PINCTRL_PIN(112, "GPIO_112"),
+ PINCTRL_PIN(113, "GPIO_113"),
+ PINCTRL_PIN(114, "GPIO_114"),
+ PINCTRL_PIN(115, "GPIO_115"),
+ PINCTRL_PIN(116, "GPIO_116"),
+ PINCTRL_PIN(117, "GPIO_117"),
+ PINCTRL_PIN(118, "GPIO_118"),
+ PINCTRL_PIN(119, "GPIO_119"),
+ PINCTRL_PIN(120, "GPIO_120"),
+ PINCTRL_PIN(121, "GPIO_121"),
+ PINCTRL_PIN(122, "GPIO_122"),
+ PINCTRL_PIN(123, "GPIO_123"),
+ PINCTRL_PIN(124, "GPIO_124"),
+ PINCTRL_PIN(125, "GPIO_125"),
+ PINCTRL_PIN(126, "GPIO_126"),
+ PINCTRL_PIN(127, "GPIO_127"),
+ PINCTRL_PIN(128, "GPIO_128"),
+ PINCTRL_PIN(129, "GPIO_129"),
+ PINCTRL_PIN(130, "GPIO_130"),
+ PINCTRL_PIN(131, "GPIO_131"),
+ PINCTRL_PIN(132, "GPIO_132"),
+ PINCTRL_PIN(133, "GPIO_133"),
+ PINCTRL_PIN(134, "GPIO_134"),
+ PINCTRL_PIN(135, "GPIO_135"),
+ PINCTRL_PIN(136, "GPIO_136"),
+ PINCTRL_PIN(137, "GPIO_137"),
+ PINCTRL_PIN(138, "GPIO_138"),
+ PINCTRL_PIN(139, "GPIO_139"),
+ PINCTRL_PIN(140, "GPIO_140"),
+ PINCTRL_PIN(141, "GPIO_141"),
+ PINCTRL_PIN(142, "SDC1_CLK"),
+ PINCTRL_PIN(143, "SDC1_CMD"),
+ PINCTRL_PIN(144, "SDC1_DATA"),
+ PINCTRL_PIN(145, "SDC1_RCLK"),
+ PINCTRL_PIN(146, "SDC2_CLK"),
+ PINCTRL_PIN(147, "SDC2_CMD"),
+ PINCTRL_PIN(148, "SDC2_DATA"),
+ PINCTRL_PIN(149, "QDSD_CLK"),
+ PINCTRL_PIN(150, "QDSD_CMD"),
+ PINCTRL_PIN(151, "QDSD_DATA0"),
+ PINCTRL_PIN(152, "QDSD_DATA1"),
+ PINCTRL_PIN(153, "QDSD_DATA2"),
+ PINCTRL_PIN(154, "QDSD_DATA3"),
+};
+
+#define DECLARE_MSM_GPIO_PINS(pin) \
+ static const unsigned int gpio##pin##_pins[] = { pin }
+DECLARE_MSM_GPIO_PINS(0);
+DECLARE_MSM_GPIO_PINS(1);
+DECLARE_MSM_GPIO_PINS(2);
+DECLARE_MSM_GPIO_PINS(3);
+DECLARE_MSM_GPIO_PINS(4);
+DECLARE_MSM_GPIO_PINS(5);
+DECLARE_MSM_GPIO_PINS(6);
+DECLARE_MSM_GPIO_PINS(7);
+DECLARE_MSM_GPIO_PINS(8);
+DECLARE_MSM_GPIO_PINS(9);
+DECLARE_MSM_GPIO_PINS(10);
+DECLARE_MSM_GPIO_PINS(11);
+DECLARE_MSM_GPIO_PINS(12);
+DECLARE_MSM_GPIO_PINS(13);
+DECLARE_MSM_GPIO_PINS(14);
+DECLARE_MSM_GPIO_PINS(15);
+DECLARE_MSM_GPIO_PINS(16);
+DECLARE_MSM_GPIO_PINS(17);
+DECLARE_MSM_GPIO_PINS(18);
+DECLARE_MSM_GPIO_PINS(19);
+DECLARE_MSM_GPIO_PINS(20);
+DECLARE_MSM_GPIO_PINS(21);
+DECLARE_MSM_GPIO_PINS(22);
+DECLARE_MSM_GPIO_PINS(23);
+DECLARE_MSM_GPIO_PINS(24);
+DECLARE_MSM_GPIO_PINS(25);
+DECLARE_MSM_GPIO_PINS(26);
+DECLARE_MSM_GPIO_PINS(27);
+DECLARE_MSM_GPIO_PINS(28);
+DECLARE_MSM_GPIO_PINS(29);
+DECLARE_MSM_GPIO_PINS(30);
+DECLARE_MSM_GPIO_PINS(31);
+DECLARE_MSM_GPIO_PINS(32);
+DECLARE_MSM_GPIO_PINS(33);
+DECLARE_MSM_GPIO_PINS(34);
+DECLARE_MSM_GPIO_PINS(35);
+DECLARE_MSM_GPIO_PINS(36);
+DECLARE_MSM_GPIO_PINS(37);
+DECLARE_MSM_GPIO_PINS(38);
+DECLARE_MSM_GPIO_PINS(39);
+DECLARE_MSM_GPIO_PINS(40);
+DECLARE_MSM_GPIO_PINS(41);
+DECLARE_MSM_GPIO_PINS(42);
+DECLARE_MSM_GPIO_PINS(43);
+DECLARE_MSM_GPIO_PINS(44);
+DECLARE_MSM_GPIO_PINS(45);
+DECLARE_MSM_GPIO_PINS(46);
+DECLARE_MSM_GPIO_PINS(47);
+DECLARE_MSM_GPIO_PINS(48);
+DECLARE_MSM_GPIO_PINS(49);
+DECLARE_MSM_GPIO_PINS(50);
+DECLARE_MSM_GPIO_PINS(51);
+DECLARE_MSM_GPIO_PINS(52);
+DECLARE_MSM_GPIO_PINS(53);
+DECLARE_MSM_GPIO_PINS(54);
+DECLARE_MSM_GPIO_PINS(55);
+DECLARE_MSM_GPIO_PINS(56);
+DECLARE_MSM_GPIO_PINS(57);
+DECLARE_MSM_GPIO_PINS(58);
+DECLARE_MSM_GPIO_PINS(59);
+DECLARE_MSM_GPIO_PINS(60);
+DECLARE_MSM_GPIO_PINS(61);
+DECLARE_MSM_GPIO_PINS(62);
+DECLARE_MSM_GPIO_PINS(63);
+DECLARE_MSM_GPIO_PINS(64);
+DECLARE_MSM_GPIO_PINS(65);
+DECLARE_MSM_GPIO_PINS(66);
+DECLARE_MSM_GPIO_PINS(67);
+DECLARE_MSM_GPIO_PINS(68);
+DECLARE_MSM_GPIO_PINS(69);
+DECLARE_MSM_GPIO_PINS(70);
+DECLARE_MSM_GPIO_PINS(71);
+DECLARE_MSM_GPIO_PINS(72);
+DECLARE_MSM_GPIO_PINS(73);
+DECLARE_MSM_GPIO_PINS(74);
+DECLARE_MSM_GPIO_PINS(75);
+DECLARE_MSM_GPIO_PINS(76);
+DECLARE_MSM_GPIO_PINS(77);
+DECLARE_MSM_GPIO_PINS(78);
+DECLARE_MSM_GPIO_PINS(79);
+DECLARE_MSM_GPIO_PINS(80);
+DECLARE_MSM_GPIO_PINS(81);
+DECLARE_MSM_GPIO_PINS(82);
+DECLARE_MSM_GPIO_PINS(83);
+DECLARE_MSM_GPIO_PINS(84);
+DECLARE_MSM_GPIO_PINS(85);
+DECLARE_MSM_GPIO_PINS(86);
+DECLARE_MSM_GPIO_PINS(87);
+DECLARE_MSM_GPIO_PINS(88);
+DECLARE_MSM_GPIO_PINS(89);
+DECLARE_MSM_GPIO_PINS(90);
+DECLARE_MSM_GPIO_PINS(91);
+DECLARE_MSM_GPIO_PINS(92);
+DECLARE_MSM_GPIO_PINS(93);
+DECLARE_MSM_GPIO_PINS(94);
+DECLARE_MSM_GPIO_PINS(95);
+DECLARE_MSM_GPIO_PINS(96);
+DECLARE_MSM_GPIO_PINS(97);
+DECLARE_MSM_GPIO_PINS(98);
+DECLARE_MSM_GPIO_PINS(99);
+DECLARE_MSM_GPIO_PINS(100);
+DECLARE_MSM_GPIO_PINS(101);
+DECLARE_MSM_GPIO_PINS(102);
+DECLARE_MSM_GPIO_PINS(103);
+DECLARE_MSM_GPIO_PINS(104);
+DECLARE_MSM_GPIO_PINS(105);
+DECLARE_MSM_GPIO_PINS(106);
+DECLARE_MSM_GPIO_PINS(107);
+DECLARE_MSM_GPIO_PINS(108);
+DECLARE_MSM_GPIO_PINS(109);
+DECLARE_MSM_GPIO_PINS(110);
+DECLARE_MSM_GPIO_PINS(111);
+DECLARE_MSM_GPIO_PINS(112);
+DECLARE_MSM_GPIO_PINS(113);
+DECLARE_MSM_GPIO_PINS(114);
+DECLARE_MSM_GPIO_PINS(115);
+DECLARE_MSM_GPIO_PINS(116);
+DECLARE_MSM_GPIO_PINS(117);
+DECLARE_MSM_GPIO_PINS(118);
+DECLARE_MSM_GPIO_PINS(119);
+DECLARE_MSM_GPIO_PINS(120);
+DECLARE_MSM_GPIO_PINS(121);
+DECLARE_MSM_GPIO_PINS(122);
+DECLARE_MSM_GPIO_PINS(123);
+DECLARE_MSM_GPIO_PINS(124);
+DECLARE_MSM_GPIO_PINS(125);
+DECLARE_MSM_GPIO_PINS(126);
+DECLARE_MSM_GPIO_PINS(127);
+DECLARE_MSM_GPIO_PINS(128);
+DECLARE_MSM_GPIO_PINS(129);
+DECLARE_MSM_GPIO_PINS(130);
+DECLARE_MSM_GPIO_PINS(131);
+DECLARE_MSM_GPIO_PINS(132);
+DECLARE_MSM_GPIO_PINS(133);
+DECLARE_MSM_GPIO_PINS(134);
+DECLARE_MSM_GPIO_PINS(135);
+DECLARE_MSM_GPIO_PINS(136);
+DECLARE_MSM_GPIO_PINS(137);
+DECLARE_MSM_GPIO_PINS(138);
+DECLARE_MSM_GPIO_PINS(139);
+DECLARE_MSM_GPIO_PINS(140);
+DECLARE_MSM_GPIO_PINS(141);
+
+static const unsigned int sdc1_clk_pins[] = { 142 };
+static const unsigned int sdc1_cmd_pins[] = { 143 };
+static const unsigned int sdc1_data_pins[] = { 144 };
+static const unsigned int sdc1_rclk_pins[] = { 145 };
+static const unsigned int sdc2_clk_pins[] = { 146 };
+static const unsigned int sdc2_cmd_pins[] = { 147 };
+static const unsigned int sdc2_data_pins[] = { 148 };
+static const unsigned int qdsd_clk_pins[] = { 149 };
+static const unsigned int qdsd_cmd_pins[] = { 150 };
+static const unsigned int qdsd_data0_pins[] = { 151 };
+static const unsigned int qdsd_data1_pins[] = { 152 };
+static const unsigned int qdsd_data2_pins[] = { 153 };
+static const unsigned int qdsd_data3_pins[] = { 154 };
+
+enum msm8953_functions {
+ msm_mux_gpio,
+ msm_mux_blsp_spi1,
+ msm_mux_smb_int,
+ msm_mux_adsp_ext,
+ msm_mux_prng_rosc,
+ msm_mux_blsp_i2c1,
+ msm_mux_qdss_cti_trig_out_b0,
+ msm_mux_qdss_cti_trig_out_a1,
+ msm_mux_blsp_spi2,
+ msm_mux_blsp_uart2,
+ msm_mux_ldo_update,
+ msm_mux_dac_calib0,
+ msm_mux_ldo_en,
+ msm_mux_blsp_i2c2,
+ msm_mux_gcc_gp1_clk_b,
+ msm_mux_atest_gpsadc_dtest0_native,
+ msm_mux_blsp_spi3,
+ msm_mux_qdss_tracedata_b,
+ msm_mux_pwr_modem_enabled_b,
+ msm_mux_blsp_i2c3,
+ msm_mux_gcc_gp2_clk_b,
+ msm_mux_gcc_gp3_clk_b,
+ msm_mux_hall_int,
+ msm_mux_blsp_spi4,
+ msm_mux_blsp_uart4,
+ msm_mux_pwr_nav_enabled_b,
+ msm_mux_dac_calib1,
+ msm_mux_cap_int,
+ msm_mux_pwr_crypto_enabled_b,
+ msm_mux_dac_calib2,
+ msm_mux_blsp_i2c4,
+ msm_mux_nfc_disable,
+ msm_mux_blsp_spi5,
+ msm_mux_blsp_uart5,
+ msm_mux_qdss_traceclk_a,
+ msm_mux_atest_bbrx1,
+ msm_mux_nfc_irq,
+ msm_mux_m_voc,
+ msm_mux_qdss_cti_trig_in_a0,
+ msm_mux_atest_bbrx0,
+ msm_mux_blsp_i2c5,
+ msm_mux_qdss_tracectl_a,
+ msm_mux_atest_gpsadc_dtest1_native,
+ msm_mux_qdss_tracedata_a,
+ msm_mux_blsp_spi6,
+ msm_mux_blsp_uart6,
+ msm_mux_qdss_tracectl_b,
+ msm_mux_dac_calib15,
+ msm_mux_qdss_cti_trig_in_b0,
+ msm_mux_dac_calib16,
+ msm_mux_blsp_i2c6,
+ msm_mux_qdss_traceclk_b,
+ msm_mux_atest_wlan0,
+ msm_mux_atest_wlan1,
+ msm_mux_mdp_vsync,
+ msm_mux_pri_mi2s_mclk_a,
+ msm_mux_sec_mi2s_mclk_a,
+ msm_mux_qdss_cti_trig_out_b1,
+ msm_mux_cam_mclk,
+ msm_mux_dac_calib3,
+ msm_mux_cci_i2c,
+ msm_mux_pwr_modem_enabled_a,
+ msm_mux_dac_calib4,
+ msm_mux_dac_calib19,
+ msm_mux_flash_strobe,
+ msm_mux_cci_timer0,
+ msm_mux_cci_timer1,
+ msm_mux_cam_irq,
+ msm_mux_cci_timer2,
+ msm_mux_blsp1_spi,
+ msm_mux_pwr_nav_enabled_a,
+ msm_mux_ois_sync,
+ msm_mux_cci_timer3,
+ msm_mux_cci_timer4,
+ msm_mux_blsp3_spi,
+ msm_mux_qdss_cti_trig_out_a0,
+ msm_mux_dac_calib7,
+ msm_mux_accel_int,
+ msm_mux_gcc_gp1_clk_a,
+ msm_mux_dac_calib8,
+ msm_mux_alsp_int,
+ msm_mux_gcc_gp2_clk_a,
+ msm_mux_dac_calib9,
+ msm_mux_mag_int,
+ msm_mux_gcc_gp3_clk_a,
+ msm_mux_pwr_crypto_enabled_a,
+ msm_mux_cci_async,
+ msm_mux_cam1_standby,
+ msm_mux_dac_calib5,
+ msm_mux_cam1_rst,
+ msm_mux_dac_calib6,
+ msm_mux_dac_calib10,
+ msm_mux_gyro_int,
+ msm_mux_dac_calib11,
+ msm_mux_pressure_int,
+ msm_mux_dac_calib12,
+ msm_mux_blsp6_spi,
+ msm_mux_dac_calib13,
+ msm_mux_fp_int,
+ msm_mux_qdss_cti_trig_in_b1,
+ msm_mux_dac_calib14,
+ msm_mux_uim_batt,
+ msm_mux_cam0_ldo,
+ msm_mux_sd_write,
+ msm_mux_uim1_data,
+ msm_mux_uim1_clk,
+ msm_mux_uim1_reset,
+ msm_mux_uim1_present,
+ msm_mux_uim2_data,
+ msm_mux_uim2_clk,
+ msm_mux_uim2_reset,
+ msm_mux_uim2_present,
+ msm_mux_ts_xvdd,
+ msm_mux_mipi_dsi0,
+ msm_mux_nfc_dwl,
+ msm_mux_us_euro,
+ msm_mux_atest_char3,
+ msm_mux_dbg_out,
+ msm_mux_bimc_dte0,
+ msm_mux_ts_resout,
+ msm_mux_ts_sample,
+ msm_mux_sec_mi2s_mclk_b,
+ msm_mux_pri_mi2s,
+ msm_mux_codec_reset,
+ msm_mux_cdc_pdm0,
+ msm_mux_atest_char1,
+ msm_mux_ebi_cdc,
+ msm_mux_dac_calib17,
+ msm_mux_us_emitter,
+ msm_mux_atest_char0,
+ msm_mux_pri_mi2s_mclk_b,
+ msm_mux_lpass_slimbus,
+ msm_mux_lpass_slimbus0,
+ msm_mux_lpass_slimbus1,
+ msm_mux_codec_int1,
+ msm_mux_codec_int2,
+ msm_mux_wcss_bt,
+ msm_mux_atest_char2,
+ msm_mux_ebi_ch0,
+ msm_mux_wcss_wlan2,
+ msm_mux_wcss_wlan1,
+ msm_mux_wcss_wlan0,
+ msm_mux_wcss_wlan,
+ msm_mux_wcss_fm,
+ msm_mux_ext_lpass,
+ msm_mux_mss_lte,
+ msm_mux_key_volp,
+ msm_mux_pbs0,
+ msm_mux_cri_trng0,
+ msm_mux_key_snapshot,
+ msm_mux_pbs1,
+ msm_mux_cri_trng1,
+ msm_mux_key_focus,
+ msm_mux_pbs2,
+ msm_mux_cri_trng,
+ msm_mux_gcc_tlmm,
+ msm_mux_key_home,
+ msm_mux_pwr_down,
+ msm_mux_dmic0_clk,
+ msm_mux_blsp7_spi,
+ msm_mux_hdmi_int,
+ msm_mux_dmic0_data,
+ msm_mux_qdss_cti_trig_in_a1,
+ msm_mux_pri_mi2s_ws,
+ msm_mux_wsa_io,
+ msm_mux_wsa_en,
+ msm_mux_blsp_spi8,
+ msm_mux_wsa_irq,
+ msm_mux_blsp_i2c8,
+ msm_mux_gcc_plltest,
+ msm_mux_nav_pps_in_a,
+ msm_mux_pa_indicator,
+ msm_mux_nav_pps_in_b,
+ msm_mux_nav_pps,
+ msm_mux_modem_tsync,
+ msm_mux_nav_tsync,
+ msm_mux_ssbi_wtr1,
+ msm_mux_gsm1_tx,
+ msm_mux_dac_calib18,
+ msm_mux_gsm0_tx,
+ msm_mux_atest_char,
+ msm_mux_atest_tsens,
+ msm_mux_bimc_dte1,
+ msm_mux_dac_calib20,
+ msm_mux_cam2_rst,
+ msm_mux_ddr_bist,
+ msm_mux_dac_calib21,
+ msm_mux_cam2_standby,
+ msm_mux_dac_calib22,
+ msm_mux_cam3_rst,
+ msm_mux_dac_calib23,
+ msm_mux_cam3_standby,
+ msm_mux_dac_calib24,
+ msm_mux_sdcard_det,
+ msm_mux_dac_calib25,
+ msm_mux_cam1_ldo,
+ msm_mux_sec_mi2s,
+ msm_mux_blsp_spi7,
+ msm_mux_blsp_i2c7,
+ msm_mux_ss_switch,
+ msm_mux_tsens_max,
+ msm_mux_NA,
+};
+
+static const char * const gpio_groups[] = {
+ "gpio0", "gpio1", "gpio2", "gpio3", "gpio4", "gpio5", "gpio6", "gpio7",
+ "gpio8", "gpio9", "gpio10", "gpio11", "gpio12", "gpio13", "gpio14",
+ "gpio15", "gpio16", "gpio17", "gpio18", "gpio19", "gpio20", "gpio21",
+ "gpio22", "gpio23", "gpio24", "gpio25", "gpio26", "gpio27", "gpio28",
+ "gpio29", "gpio30", "gpio31", "gpio32", "gpio33", "gpio34", "gpio35",
+ "gpio36", "gpio37", "gpio38", "gpio39", "gpio40", "gpio41", "gpio42",
+ "gpio43", "gpio44", "gpio45", "gpio46", "gpio47", "gpio48", "gpio49",
+ "gpio50", "gpio51", "gpio52", "gpio53", "gpio54", "gpio55", "gpio56",
+ "gpio57", "gpio58", "gpio59", "gpio60", "gpio61", "gpio62", "gpio63",
+ "gpio64", "gpio65", "gpio66", "gpio67", "gpio68", "gpio69", "gpio70",
+ "gpio71", "gpio72", "gpio73", "gpio74", "gpio75", "gpio76", "gpio77",
+ "gpio78", "gpio79", "gpio80", "gpio81", "gpio82", "gpio83", "gpio84",
+ "gpio85", "gpio86", "gpio87", "gpio88", "gpio89", "gpio90", "gpio91",
+ "gpio92", "gpio93", "gpio94", "gpio95", "gpio96", "gpio97", "gpio98",
+ "gpio99", "gpio100", "gpio101", "gpio102", "gpio103", "gpio104",
+ "gpio105", "gpio106", "gpio107", "gpio108", "gpio109", "gpio110",
+ "gpio111", "gpio112", "gpio113", "gpio114", "gpio115", "gpio116",
+ "gpio117", "gpio118", "gpio119", "gpio120", "gpio121", "gpio122",
+ "gpio123", "gpio124", "gpio125", "gpio126", "gpio127", "gpio128",
+ "gpio129", "gpio130", "gpio131", "gpio132", "gpio133", "gpio134",
+ "gpio135", "gpio136", "gpio137", "gpio138", "gpio139", "gpio140",
+ "gpio141",
+};
+static const char * const blsp_spi1_groups[] = {
+ "gpio0", "gpio1", "gpio2", "gpio3",
+};
+static const char * const smb_int_groups[] = {
+ "gpio1",
+};
+static const char * const adsp_ext_groups[] = {
+ "gpio1",
+};
+static const char * const prng_rosc_groups[] = {
+ "gpio2",
+};
+static const char * const blsp_i2c1_groups[] = {
+ "gpio2", "gpio3",
+};
+static const char * const qdss_cti_trig_out_b0_groups[] = {
+ "gpio2",
+};
+static const char * const qdss_cti_trig_out_a1_groups[] = {
+ "gpio3",
+};
+static const char * const blsp_spi2_groups[] = {
+ "gpio4", "gpio5", "gpio6", "gpio7",
+};
+static const char * const blsp_uart2_groups[] = {
+ "gpio4", "gpio5", "gpio6", "gpio7",
+};
+static const char * const ldo_update_groups[] = {
+ "gpio4",
+};
+static const char * const dac_calib0_groups[] = {
+ "gpio4",
+};
+static const char * const ldo_en_groups[] = {
+ "gpio5",
+};
+static const char * const blsp_i2c2_groups[] = {
+ "gpio6", "gpio7",
+};
+static const char * const gcc_gp1_clk_b_groups[] = {
+ "gpio6", "gpio41",
+};
+static const char * const atest_gpsadc_dtest0_native_groups[] = {
+ "gpio7",
+};
+static const char * const blsp_spi3_groups[] = {
+ "gpio8", "gpio9", "gpio10", "gpio11",
+};
+static const char * const qdss_tracedata_b_groups[] = {
+ "gpio8", "gpio9", "gpio12", "gpio13", "gpio23", "gpio42", "gpio43",
+ "gpio44", "gpio45", "gpio46", "gpio47", "gpio66", "gpio86", "gpio87",
+ "gpio88", "gpio92",
+};
+static const char * const pwr_modem_enabled_b_groups[] = {
+ "gpio9",
+};
+static const char * const blsp_i2c3_groups[] = {
+ "gpio10", "gpio11",
+};
+static const char * const gcc_gp2_clk_b_groups[] = {
+ "gpio10",
+};
+static const char * const gcc_gp3_clk_b_groups[] = {
+ "gpio11",
+};
+static const char * const hall_int_groups[] = {
+ "gpio12",
+};
+static const char * const blsp_spi4_groups[] = {
+ "gpio12", "gpio13", "gpio14", "gpio15",
+};
+static const char * const blsp_uart4_groups[] = {
+ "gpio12", "gpio13", "gpio14", "gpio15",
+};
+static const char * const pwr_nav_enabled_b_groups[] = {
+ "gpio12",
+};
+static const char * const dac_calib1_groups[] = {
+ "gpio12",
+};
+static const char * const cap_int_groups[] = {
+ "gpio13",
+};
+static const char * const pwr_crypto_enabled_b_groups[] = {
+ "gpio13",
+};
+static const char * const dac_calib2_groups[] = {
+ "gpio13",
+};
+static const char * const blsp_i2c4_groups[] = {
+ "gpio14", "gpio15",
+};
+static const char * const nfc_disable_groups[] = {
+ "gpio16",
+};
+static const char * const blsp_spi5_groups[] = {
+ "gpio16", "gpio17", "gpio18", "gpio19",
+};
+static const char * const blsp_uart5_groups[] = {
+ "gpio16", "gpio17", "gpio18", "gpio19",
+};
+static const char * const qdss_traceclk_a_groups[] = {
+ "gpio16",
+};
+static const char * const atest_bbrx1_groups[] = {
+ "gpio16",
+};
+static const char * const nfc_irq_groups[] = {
+ "gpio17",
+};
+static const char * const m_voc_groups[] = {
+ "gpio17", "gpio21",
+};
+static const char * const qdss_cti_trig_in_a0_groups[] = {
+ "gpio17",
+};
+static const char * const atest_bbrx0_groups[] = {
+ "gpio17",
+};
+static const char * const blsp_i2c5_groups[] = {
+ "gpio18", "gpio19",
+};
+static const char * const qdss_tracectl_a_groups[] = {
+ "gpio18",
+};
+static const char * const atest_gpsadc_dtest1_native_groups[] = {
+ "gpio18",
+};
+static const char * const qdss_tracedata_a_groups[] = {
+ "gpio19", "gpio26", "gpio27", "gpio28", "gpio29", "gpio30", "gpio31",
+ "gpio32", "gpio33", "gpio34", "gpio35", "gpio36", "gpio38", "gpio39",
+ "gpio40", "gpio50",
+};
+static const char * const blsp_spi6_groups[] = {
+ "gpio20", "gpio21", "gpio22", "gpio23",
+};
+static const char * const blsp_uart6_groups[] = {
+ "gpio20", "gpio21", "gpio22", "gpio23",
+};
+static const char * const qdss_tracectl_b_groups[] = {
+ "gpio20",
+};
+static const char * const dac_calib15_groups[] = {
+ "gpio20",
+};
+static const char * const qdss_cti_trig_in_b0_groups[] = {
+ "gpio21",
+};
+static const char * const dac_calib16_groups[] = {
+ "gpio21",
+};
+static const char * const blsp_i2c6_groups[] = {
+ "gpio22", "gpio23",
+};
+static const char * const qdss_traceclk_b_groups[] = {
+ "gpio22",
+};
+static const char * const atest_wlan0_groups[] = {
+ "gpio22",
+};
+static const char * const atest_wlan1_groups[] = {
+ "gpio23",
+};
+static const char * const mdp_vsync_groups[] = {
+ "gpio24", "gpio25",
+};
+static const char * const pri_mi2s_mclk_a_groups[] = {
+ "gpio25",
+};
+static const char * const sec_mi2s_mclk_a_groups[] = {
+ "gpio25",
+};
+static const char * const qdss_cti_trig_out_b1_groups[] = {
+ "gpio25",
+};
+static const char * const cam_mclk_groups[] = {
+ "gpio26", "gpio27", "gpio28", "gpio128",
+};
+static const char * const dac_calib3_groups[] = {
+ "gpio28",
+};
+static const char * const cci_i2c_groups[] = {
+ "gpio29", "gpio30", "gpio31", "gpio32",
+};
+static const char * const pwr_modem_enabled_a_groups[] = {
+ "gpio29",
+};
+static const char * const dac_calib4_groups[] = {
+ "gpio29",
+};
+static const char * const dac_calib19_groups[] = {
+ "gpio30",
+};
+static const char * const flash_strobe_groups[] = {
+ "gpio33", "gpio34",
+};
+static const char * const cci_timer0_groups[] = {
+ "gpio33",
+};
+static const char * const cci_timer1_groups[] = {
+ "gpio34",
+};
+static const char * const cam_irq_groups[] = {
+ "gpio35",
+};
+static const char * const cci_timer2_groups[] = {
+ "gpio35",
+};
+static const char * const blsp1_spi_groups[] = {
+ "gpio35", "gpio36",
+};
+static const char * const pwr_nav_enabled_a_groups[] = {
+ "gpio35",
+};
+static const char * const ois_sync_groups[] = {
+ "gpio36",
+};
+static const char * const cci_timer3_groups[] = {
+ "gpio36",
+};
+static const char * const cci_timer4_groups[] = {
+ "gpio41",
+};
+static const char * const blsp3_spi_groups[] = {
+ "gpio41", "gpio50",
+};
+static const char * const qdss_cti_trig_out_a0_groups[] = {
+ "gpio41",
+};
+static const char * const dac_calib7_groups[] = {
+ "gpio41",
+};
+static const char * const accel_int_groups[] = {
+ "gpio42",
+};
+static const char * const gcc_gp1_clk_a_groups[] = {
+ "gpio42",
+};
+static const char * const dac_calib8_groups[] = {
+ "gpio42",
+};
+static const char * const alsp_int_groups[] = {
+ "gpio43",
+};
+static const char * const gcc_gp2_clk_a_groups[] = {
+ "gpio43",
+};
+static const char * const dac_calib9_groups[] = {
+ "gpio43",
+};
+static const char * const mag_int_groups[] = {
+ "gpio44",
+};
+static const char * const gcc_gp3_clk_a_groups[] = {
+ "gpio44",
+};
+static const char * const pwr_crypto_enabled_a_groups[] = {
+ "gpio36",
+};
+static const char * const cci_async_groups[] = {
+ "gpio38",
+};
+static const char * const cam1_standby_groups[] = {
+ "gpio39",
+};
+static const char * const dac_calib5_groups[] = {
+ "gpio39",
+};
+static const char * const cam1_rst_groups[] = {
+ "gpio40",
+};
+static const char * const dac_calib6_groups[] = {
+ "gpio40",
+};
+static const char * const dac_calib10_groups[] = {
+ "gpio44",
+};
+static const char * const gyro_int_groups[] = {
+ "gpio45",
+};
+static const char * const dac_calib11_groups[] = {
+ "gpio45",
+};
+static const char * const pressure_int_groups[] = {
+ "gpio46",
+};
+static const char * const dac_calib12_groups[] = {
+ "gpio46",
+};
+static const char * const blsp6_spi_groups[] = {
+ "gpio47", "gpio48",
+};
+static const char * const dac_calib13_groups[] = {
+ "gpio47",
+};
+static const char * const fp_int_groups[] = {
+ "gpio48",
+};
+static const char * const qdss_cti_trig_in_b1_groups[] = {
+ "gpio48",
+};
+static const char * const dac_calib14_groups[] = {
+ "gpio48",
+};
+static const char * const uim_batt_groups[] = {
+ "gpio49",
+};
+static const char * const cam0_ldo_groups[] = {
+ "gpio50",
+};
+static const char * const sd_write_groups[] = {
+ "gpio50",
+};
+static const char * const uim1_data_groups[] = {
+ "gpio51",
+};
+static const char * const uim1_clk_groups[] = {
+ "gpio52",
+};
+static const char * const uim1_reset_groups[] = {
+ "gpio53",
+};
+static const char * const uim1_present_groups[] = {
+ "gpio54",
+};
+static const char * const uim2_data_groups[] = {
+ "gpio55",
+};
+static const char * const uim2_clk_groups[] = {
+ "gpio56",
+};
+static const char * const uim2_reset_groups[] = {
+ "gpio57",
+};
+static const char * const uim2_present_groups[] = {
+ "gpio58",
+};
+static const char * const ts_xvdd_groups[] = {
+ "gpio60",
+};
+static const char * const mipi_dsi0_groups[] = {
+ "gpio61",
+};
+static const char * const nfc_dwl_groups[] = {
+ "gpio62",
+};
+static const char * const us_euro_groups[] = {
+ "gpio63",
+};
+static const char * const atest_char3_groups[] = {
+ "gpio63",
+};
+static const char * const dbg_out_groups[] = {
+ "gpio63",
+};
+static const char * const bimc_dte0_groups[] = {
+ "gpio63", "gpio65",
+};
+static const char * const ts_resout_groups[] = {
+ "gpio64",
+};
+static const char * const ts_sample_groups[] = {
+ "gpio65",
+};
+static const char * const sec_mi2s_mclk_b_groups[] = {
+ "gpio66",
+};
+static const char * const pri_mi2s_groups[] = {
+ "gpio66", "gpio88", "gpio91", "gpio93", "gpio94", "gpio95",
+};
+static const char * const codec_reset_groups[] = {
+ "gpio67",
+};
+static const char * const cdc_pdm0_groups[] = {
+ "gpio67", "gpio68", "gpio69", "gpio70", "gpio71", "gpio72", "gpio73",
+ "gpio74",
+};
+static const char * const atest_char1_groups[] = {
+ "gpio67",
+};
+static const char * const ebi_cdc_groups[] = {
+ "gpio67", "gpio69", "gpio118", "gpio119", "gpio120", "gpio123",
+};
+static const char * const dac_calib17_groups[] = {
+ "gpio67",
+};
+static const char * const us_emitter_groups[] = {
+ "gpio68",
+};
+static const char * const atest_char0_groups[] = {
+ "gpio68",
+};
+static const char * const pri_mi2s_mclk_b_groups[] = {
+ "gpio69",
+};
+static const char * const lpass_slimbus_groups[] = {
+ "gpio70",
+};
+static const char * const lpass_slimbus0_groups[] = {
+ "gpio71",
+};
+static const char * const lpass_slimbus1_groups[] = {
+ "gpio72",
+};
+static const char * const codec_int1_groups[] = {
+ "gpio73",
+};
+static const char * const codec_int2_groups[] = {
+ "gpio74",
+};
+static const char * const wcss_bt_groups[] = {
+ "gpio75", "gpio83", "gpio84",
+};
+static const char * const atest_char2_groups[] = {
+ "gpio75",
+};
+static const char * const ebi_ch0_groups[] = {
+ "gpio75",
+};
+static const char * const wcss_wlan2_groups[] = {
+ "gpio76",
+};
+static const char * const wcss_wlan1_groups[] = {
+ "gpio77",
+};
+static const char * const wcss_wlan0_groups[] = {
+ "gpio78",
+};
+static const char * const wcss_wlan_groups[] = {
+ "gpio79", "gpio80",
+};
+static const char * const wcss_fm_groups[] = {
+ "gpio81", "gpio82",
+};
+static const char * const ext_lpass_groups[] = {
+ "gpio81",
+};
+static const char * const mss_lte_groups[] = {
+ "gpio82", "gpio83",
+};
+static const char * const key_volp_groups[] = {
+ "gpio85",
+};
+static const char * const pbs0_groups[] = {
+ "gpio85",
+};
+static const char * const cri_trng0_groups[] = {
+ "gpio85",
+};
+static const char * const key_snapshot_groups[] = {
+ "gpio86",
+};
+static const char * const pbs1_groups[] = {
+ "gpio86",
+};
+static const char * const cri_trng1_groups[] = {
+ "gpio86",
+};
+static const char * const key_focus_groups[] = {
+ "gpio87",
+};
+static const char * const pbs2_groups[] = {
+ "gpio87",
+};
+static const char * const cri_trng_groups[] = {
+ "gpio87",
+};
+static const char * const gcc_tlmm_groups[] = {
+ "gpio87",
+};
+static const char * const key_home_groups[] = {
+ "gpio88",
+};
+static const char * const pwr_down_groups[] = {
+ "gpio89",
+};
+static const char * const dmic0_clk_groups[] = {
+ "gpio89",
+};
+static const char * const blsp7_spi_groups[] = {
+ "gpio89", "gpio90",
+};
+static const char * const hdmi_int_groups[] = {
+ "gpio90",
+};
+static const char * const dmic0_data_groups[] = {
+ "gpio90",
+};
+static const char * const qdss_cti_trig_in_a1_groups[] = {
+ "gpio91",
+};
+static const char * const pri_mi2s_ws_groups[] = {
+ "gpio92",
+};
+static const char * const wsa_io_groups[] = {
+ "gpio94", "gpio95",
+};
+static const char * const wsa_en_groups[] = {
+ "gpio96",
+};
+static const char * const blsp_spi8_groups[] = {
+ "gpio96", "gpio97", "gpio98", "gpio99",
+};
+static const char * const wsa_irq_groups[] = {
+ "gpio97",
+};
+static const char * const blsp_i2c8_groups[] = {
+ "gpio98", "gpio99",
+};
+static const char * const gcc_plltest_groups[] = {
+ "gpio98", "gpio99",
+};
+static const char * const nav_pps_in_a_groups[] = {
+ "gpio111",
+};
+static const char * const pa_indicator_groups[] = {
+ "gpio112",
+};
+static const char * const nav_pps_in_b_groups[] = {
+ "gpio113",
+};
+static const char * const nav_pps_groups[] = {
+ "gpio113",
+};
+static const char * const modem_tsync_groups[] = {
+ "gpio113",
+};
+static const char * const nav_tsync_groups[] = {
+ "gpio113",
+};
+static const char * const ssbi_wtr1_groups[] = {
+ "gpio114", "gpio123",
+};
+static const char * const gsm1_tx_groups[] = {
+ "gpio115",
+};
+static const char * const dac_calib18_groups[] = {
+ "gpio115",
+};
+static const char * const gsm0_tx_groups[] = {
+ "gpio117",
+};
+static const char * const atest_char_groups[] = {
+ "gpio120",
+};
+static const char * const atest_tsens_groups[] = {
+ "gpio120",
+};
+static const char * const bimc_dte1_groups[] = {
+ "gpio121", "gpio122",
+};
+static const char * const dac_calib20_groups[] = {
+ "gpio128",
+};
+static const char * const cam2_rst_groups[] = {
+ "gpio129",
+};
+static const char * const ddr_bist_groups[] = {
+ "gpio129", "gpio130", "gpio131", "gpio132",
+};
+static const char * const dac_calib21_groups[] = {
+ "gpio129",
+};
+static const char * const cam2_standby_groups[] = {
+ "gpio130",
+};
+static const char * const dac_calib22_groups[] = {
+ "gpio130",
+};
+static const char * const cam3_rst_groups[] = {
+ "gpio131",
+};
+static const char * const dac_calib23_groups[] = {
+ "gpio131",
+};
+static const char * const cam3_standby_groups[] = {
+ "gpio132",
+};
+static const char * const dac_calib24_groups[] = {
+ "gpio132",
+};
+static const char * const sdcard_det_groups[] = {
+ "gpio133",
+};
+static const char * const dac_calib25_groups[] = {
+ "gpio133",
+};
+static const char * const cam1_ldo_groups[] = {
+ "gpio134",
+};
+static const char * const sec_mi2s_groups[] = {
+ "gpio135", "gpio136", "gpio137", "gpio138",
+};
+static const char * const blsp_spi7_groups[] = {
+ "gpio135", "gpio136", "gpio137", "gpio138",
+};
+static const char * const blsp_i2c7_groups[] = {
+ "gpio135", "gpio136",
+};
+static const char * const ss_switch_groups[] = {
+ "gpio139",
+};
+static const char * const tsens_max_groups[] = {
+ "gpio139",
+};
+
+static const struct msm_function msm8953_functions[] = {
+ FUNCTION(gpio),
+ FUNCTION(blsp_spi1),
+ FUNCTION(smb_int),
+ FUNCTION(adsp_ext),
+ FUNCTION(prng_rosc),
+ FUNCTION(blsp_i2c1),
+ FUNCTION(qdss_cti_trig_out_b0),
+ FUNCTION(qdss_cti_trig_out_a1),
+ FUNCTION(blsp_spi2),
+ FUNCTION(blsp_uart2),
+ FUNCTION(ldo_update),
+ FUNCTION(dac_calib0),
+ FUNCTION(ldo_en),
+ FUNCTION(blsp_i2c2),
+ FUNCTION(gcc_gp1_clk_b),
+ FUNCTION(atest_gpsadc_dtest0_native),
+ FUNCTION(blsp_spi3),
+ FUNCTION(qdss_tracedata_b),
+ FUNCTION(pwr_modem_enabled_b),
+ FUNCTION(blsp_i2c3),
+ FUNCTION(gcc_gp2_clk_b),
+ FUNCTION(gcc_gp3_clk_b),
+ FUNCTION(hall_int),
+ FUNCTION(blsp_spi4),
+ FUNCTION(blsp_uart4),
+ FUNCTION(pwr_nav_enabled_b),
+ FUNCTION(dac_calib1),
+ FUNCTION(cap_int),
+ FUNCTION(pwr_crypto_enabled_b),
+ FUNCTION(dac_calib2),
+ FUNCTION(blsp_i2c4),
+ FUNCTION(nfc_disable),
+ FUNCTION(blsp_spi5),
+ FUNCTION(blsp_uart5),
+ FUNCTION(qdss_traceclk_a),
+ FUNCTION(atest_bbrx1),
+ FUNCTION(nfc_irq),
+ FUNCTION(m_voc),
+ FUNCTION(qdss_cti_trig_in_a0),
+ FUNCTION(atest_bbrx0),
+ FUNCTION(blsp_i2c5),
+ FUNCTION(qdss_tracectl_a),
+ FUNCTION(atest_gpsadc_dtest1_native),
+ FUNCTION(qdss_tracedata_a),
+ FUNCTION(blsp_spi6),
+ FUNCTION(blsp_uart6),
+ FUNCTION(qdss_tracectl_b),
+ FUNCTION(dac_calib15),
+ FUNCTION(qdss_cti_trig_in_b0),
+ FUNCTION(dac_calib16),
+ FUNCTION(blsp_i2c6),
+ FUNCTION(qdss_traceclk_b),
+ FUNCTION(atest_wlan0),
+ FUNCTION(atest_wlan1),
+ FUNCTION(mdp_vsync),
+ FUNCTION(pri_mi2s_mclk_a),
+ FUNCTION(sec_mi2s_mclk_a),
+ FUNCTION(qdss_cti_trig_out_b1),
+ FUNCTION(cam_mclk),
+ FUNCTION(dac_calib3),
+ FUNCTION(cci_i2c),
+ FUNCTION(pwr_modem_enabled_a),
+ FUNCTION(dac_calib4),
+ FUNCTION(dac_calib19),
+ FUNCTION(flash_strobe),
+ FUNCTION(cci_timer0),
+ FUNCTION(cci_timer1),
+ FUNCTION(cam_irq),
+ FUNCTION(cci_timer2),
+ FUNCTION(blsp1_spi),
+ FUNCTION(pwr_nav_enabled_a),
+ FUNCTION(ois_sync),
+ FUNCTION(cci_timer3),
+ FUNCTION(cci_timer4),
+ FUNCTION(blsp3_spi),
+ FUNCTION(qdss_cti_trig_out_a0),
+ FUNCTION(dac_calib7),
+ FUNCTION(accel_int),
+ FUNCTION(gcc_gp1_clk_a),
+ FUNCTION(dac_calib8),
+ FUNCTION(alsp_int),
+ FUNCTION(gcc_gp2_clk_a),
+ FUNCTION(dac_calib9),
+ FUNCTION(mag_int),
+ FUNCTION(gcc_gp3_clk_a),
+ FUNCTION(pwr_crypto_enabled_a),
+ FUNCTION(cci_async),
+ FUNCTION(cam1_standby),
+ FUNCTION(dac_calib5),
+ FUNCTION(cam1_rst),
+ FUNCTION(dac_calib6),
+ FUNCTION(dac_calib10),
+ FUNCTION(gyro_int),
+ FUNCTION(dac_calib11),
+ FUNCTION(pressure_int),
+ FUNCTION(dac_calib12),
+ FUNCTION(blsp6_spi),
+ FUNCTION(dac_calib13),
+ FUNCTION(fp_int),
+ FUNCTION(qdss_cti_trig_in_b1),
+ FUNCTION(dac_calib14),
+ FUNCTION(uim_batt),
+ FUNCTION(cam0_ldo),
+ FUNCTION(sd_write),
+ FUNCTION(uim1_data),
+ FUNCTION(uim1_clk),
+ FUNCTION(uim1_reset),
+ FUNCTION(uim1_present),
+ FUNCTION(uim2_data),
+ FUNCTION(uim2_clk),
+ FUNCTION(uim2_reset),
+ FUNCTION(uim2_present),
+ FUNCTION(ts_xvdd),
+ FUNCTION(mipi_dsi0),
+ FUNCTION(nfc_dwl),
+ FUNCTION(us_euro),
+ FUNCTION(atest_char3),
+ FUNCTION(dbg_out),
+ FUNCTION(bimc_dte0),
+ FUNCTION(ts_resout),
+ FUNCTION(ts_sample),
+ FUNCTION(sec_mi2s_mclk_b),
+ FUNCTION(pri_mi2s),
+ FUNCTION(codec_reset),
+ FUNCTION(cdc_pdm0),
+ FUNCTION(atest_char1),
+ FUNCTION(ebi_cdc),
+ FUNCTION(dac_calib17),
+ FUNCTION(us_emitter),
+ FUNCTION(atest_char0),
+ FUNCTION(pri_mi2s_mclk_b),
+ FUNCTION(lpass_slimbus),
+ FUNCTION(lpass_slimbus0),
+ FUNCTION(lpass_slimbus1),
+ FUNCTION(codec_int1),
+ FUNCTION(codec_int2),
+ FUNCTION(wcss_bt),
+ FUNCTION(atest_char2),
+ FUNCTION(ebi_ch0),
+ FUNCTION(wcss_wlan2),
+ FUNCTION(wcss_wlan1),
+ FUNCTION(wcss_wlan0),
+ FUNCTION(wcss_wlan),
+ FUNCTION(wcss_fm),
+ FUNCTION(ext_lpass),
+ FUNCTION(mss_lte),
+ FUNCTION(key_volp),
+ FUNCTION(pbs0),
+ FUNCTION(cri_trng0),
+ FUNCTION(key_snapshot),
+ FUNCTION(pbs1),
+ FUNCTION(cri_trng1),
+ FUNCTION(key_focus),
+ FUNCTION(pbs2),
+ FUNCTION(cri_trng),
+ FUNCTION(gcc_tlmm),
+ FUNCTION(key_home),
+ FUNCTION(pwr_down),
+ FUNCTION(dmic0_clk),
+ FUNCTION(blsp7_spi),
+ FUNCTION(hdmi_int),
+ FUNCTION(dmic0_data),
+ FUNCTION(qdss_cti_trig_in_a1),
+ FUNCTION(pri_mi2s_ws),
+ FUNCTION(wsa_io),
+ FUNCTION(wsa_en),
+ FUNCTION(blsp_spi8),
+ FUNCTION(wsa_irq),
+ FUNCTION(blsp_i2c8),
+ FUNCTION(gcc_plltest),
+ FUNCTION(nav_pps_in_a),
+ FUNCTION(pa_indicator),
+ FUNCTION(nav_pps_in_b),
+ FUNCTION(nav_pps),
+ FUNCTION(modem_tsync),
+ FUNCTION(nav_tsync),
+ FUNCTION(ssbi_wtr1),
+ FUNCTION(gsm1_tx),
+ FUNCTION(dac_calib18),
+ FUNCTION(gsm0_tx),
+ FUNCTION(atest_char),
+ FUNCTION(atest_tsens),
+ FUNCTION(bimc_dte1),
+ FUNCTION(dac_calib20),
+ FUNCTION(cam2_rst),
+ FUNCTION(ddr_bist),
+ FUNCTION(dac_calib21),
+ FUNCTION(cam2_standby),
+ FUNCTION(dac_calib22),
+ FUNCTION(cam3_rst),
+ FUNCTION(dac_calib23),
+ FUNCTION(cam3_standby),
+ FUNCTION(dac_calib24),
+ FUNCTION(sdcard_det),
+ FUNCTION(dac_calib25),
+ FUNCTION(cam1_ldo),
+ FUNCTION(sec_mi2s),
+ FUNCTION(blsp_spi7),
+ FUNCTION(blsp_i2c7),
+ FUNCTION(ss_switch),
+ FUNCTION(tsens_max),
+};
+
+static const struct msm_pingroup msm8953_groups[] = {
+ PINGROUP(0, blsp_spi1, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(1, blsp_spi1, adsp_ext, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(2, blsp_spi1, blsp_i2c1, prng_rosc, NA, NA, NA,
+ qdss_cti_trig_out_b0, NA, NA),
+ PINGROUP(3, blsp_spi1, blsp_i2c1, NA, NA, NA, qdss_cti_trig_out_a1, NA,
+ NA, NA),
+ PINGROUP(4, blsp_spi2, blsp_uart2, ldo_update, NA, dac_calib0, NA, NA,
+ NA, NA),
+ PINGROUP(5, blsp_spi2, blsp_uart2, ldo_en, NA, NA, NA, NA, NA, NA),
+ PINGROUP(6, blsp_spi2, blsp_uart2, blsp_i2c2, gcc_gp1_clk_b, NA, NA,
+ NA, NA, NA),
+ PINGROUP(7, blsp_spi2, blsp_uart2, blsp_i2c2, NA,
+ atest_gpsadc_dtest0_native, NA, NA, NA, NA),
+ PINGROUP(8, blsp_spi3, NA, NA, qdss_tracedata_b, NA, NA, NA, NA, NA),
+ PINGROUP(9, blsp_spi3, pwr_modem_enabled_b, NA, NA, qdss_tracedata_b,
+ NA, NA, NA, NA),
+ PINGROUP(10, blsp_spi3, blsp_i2c3, gcc_gp2_clk_b, NA, NA, NA, NA, NA,
+ NA),
+ PINGROUP(11, blsp_spi3, blsp_i2c3, gcc_gp3_clk_b, NA, NA, NA, NA, NA,
+ NA),
+ PINGROUP(12, blsp_spi4, blsp_uart4, pwr_nav_enabled_b, NA, NA,
+ qdss_tracedata_b, NA, dac_calib1, NA),
+ PINGROUP(13, blsp_spi4, blsp_uart4, pwr_crypto_enabled_b, NA, NA, NA,
+ qdss_tracedata_b, NA, dac_calib2),
+ PINGROUP(14, blsp_spi4, blsp_uart4, blsp_i2c4, NA, NA, NA, NA, NA, NA),
+ PINGROUP(15, blsp_spi4, blsp_uart4, blsp_i2c4, NA, NA, NA, NA, NA, NA),
+ PINGROUP(16, blsp_spi5, blsp_uart5, NA, NA, qdss_traceclk_a, NA,
+ atest_bbrx1, NA, NA),
+ PINGROUP(17, blsp_spi5, blsp_uart5, m_voc, qdss_cti_trig_in_a0, NA,
+ atest_bbrx0, NA, NA, NA),
+ PINGROUP(18, blsp_spi5, blsp_uart5, blsp_i2c5, qdss_tracectl_a, NA,
+ atest_gpsadc_dtest1_native, NA, NA, NA),
+ PINGROUP(19, blsp_spi5, blsp_uart5, blsp_i2c5, qdss_tracedata_a, NA,
+ NA, NA, NA, NA),
+ PINGROUP(20, blsp_spi6, blsp_uart6, NA, NA, NA, qdss_tracectl_b, NA,
+ dac_calib15, NA),
+ PINGROUP(21, blsp_spi6, blsp_uart6, m_voc, NA, NA, NA,
+ qdss_cti_trig_in_b0, NA, dac_calib16),
+ PINGROUP(22, blsp_spi6, blsp_uart6, blsp_i2c6, qdss_traceclk_b, NA,
+ atest_wlan0, NA, NA, NA),
+ PINGROUP(23, blsp_spi6, blsp_uart6, blsp_i2c6, qdss_tracedata_b, NA,
+ atest_wlan1, NA, NA, NA),
+ PINGROUP(24, mdp_vsync, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(25, mdp_vsync, pri_mi2s_mclk_a, sec_mi2s_mclk_a,
+ qdss_cti_trig_out_b1, NA, NA, NA, NA, NA),
+ PINGROUP(26, cam_mclk, NA, NA, NA, qdss_tracedata_a, NA, NA, NA, NA),
+ PINGROUP(27, cam_mclk, NA, NA, NA, qdss_tracedata_a, NA, NA, NA, NA),
+ PINGROUP(28, cam_mclk, NA, NA, NA, qdss_tracedata_a, NA, dac_calib3,
+ NA, NA),
+ PINGROUP(29, cci_i2c, pwr_modem_enabled_a, NA, NA, NA,
+ qdss_tracedata_a, NA, dac_calib4, NA),
+ PINGROUP(30, cci_i2c, NA, NA, NA, qdss_tracedata_a, NA, dac_calib19,
+ NA, NA),
+ PINGROUP(31, cci_i2c, NA, NA, NA, qdss_tracedata_a, NA, NA, NA, NA),
+ PINGROUP(32, cci_i2c, NA, NA, NA, qdss_tracedata_a, NA, NA, NA, NA),
+ PINGROUP(33, cci_timer0, NA, NA, NA, NA, qdss_tracedata_a, NA, NA, NA),
+ PINGROUP(34, cci_timer1, NA, NA, NA, NA, qdss_tracedata_a, NA, NA, NA),
+ PINGROUP(35, cci_timer2, blsp1_spi, pwr_nav_enabled_a, NA, NA, NA,
+ qdss_tracedata_a, NA, NA),
+ PINGROUP(36, cci_timer3, blsp1_spi, NA, pwr_crypto_enabled_a, NA, NA,
+ NA, qdss_tracedata_a, NA),
+ PINGROUP(37, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(38, cci_async, NA, qdss_tracedata_a, NA, NA, NA, NA, NA, NA),
+ PINGROUP(39, NA, NA, NA, qdss_tracedata_a, NA, dac_calib5, NA, NA, NA),
+ PINGROUP(40, NA, NA, qdss_tracedata_a, NA, dac_calib6, NA, NA, NA, NA),
+ PINGROUP(41, cci_timer4, blsp3_spi, gcc_gp1_clk_b, NA, NA,
+ qdss_cti_trig_out_a0, NA, dac_calib7, NA),
+ PINGROUP(42, gcc_gp1_clk_a, qdss_tracedata_b, NA, dac_calib8, NA, NA,
+ NA, NA, NA),
+ PINGROUP(43, gcc_gp2_clk_a, qdss_tracedata_b, NA, dac_calib9, NA, NA,
+ NA, NA, NA),
+ PINGROUP(44, gcc_gp3_clk_a, qdss_tracedata_b, NA, dac_calib10, NA, NA,
+ NA, NA, NA),
+ PINGROUP(45, NA, qdss_tracedata_b, NA, dac_calib11, NA, NA, NA, NA, NA),
+ PINGROUP(46, qdss_tracedata_b, NA, dac_calib12, NA, NA, NA, NA, NA, NA),
+ PINGROUP(47, blsp6_spi, qdss_tracedata_b, NA, dac_calib13, NA, NA, NA,
+ NA, NA),
+ PINGROUP(48, blsp6_spi, NA, qdss_cti_trig_in_b1, NA, dac_calib14, NA,
+ NA, NA, NA),
+ PINGROUP(49, uim_batt, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(50, blsp3_spi, sd_write, NA, NA, NA, qdss_tracedata_a, NA, NA,
+ NA),
+ PINGROUP(51, uim1_data, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(52, uim1_clk, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(53, uim1_reset, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(54, uim1_present, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(55, uim2_data, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(56, uim2_clk, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(57, uim2_reset, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(58, uim2_present, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(59, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(60, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(61, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(62, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(63, atest_char3, dbg_out, bimc_dte0, NA, NA, NA, NA, NA, NA),
+ PINGROUP(64, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(65, bimc_dte0, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(66, sec_mi2s_mclk_b, pri_mi2s, NA, qdss_tracedata_b, NA, NA,
+ NA, NA, NA),
+ PINGROUP(67, cdc_pdm0, atest_char1, ebi_cdc, NA, dac_calib17, NA, NA,
+ NA, NA),
+ PINGROUP(68, cdc_pdm0, atest_char0, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(69, cdc_pdm0, pri_mi2s_mclk_b, ebi_cdc, NA, NA, NA, NA, NA,
+ NA),
+ PINGROUP(70, lpass_slimbus, cdc_pdm0, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(71, lpass_slimbus0, cdc_pdm0, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(72, lpass_slimbus1, cdc_pdm0, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(73, cdc_pdm0, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(74, cdc_pdm0, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(75, wcss_bt, atest_char2, NA, ebi_ch0, NA, NA, NA, NA, NA),
+ PINGROUP(76, wcss_wlan2, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(77, wcss_wlan1, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(78, wcss_wlan0, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(79, wcss_wlan, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(80, wcss_wlan, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(81, wcss_fm, ext_lpass, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(82, wcss_fm, mss_lte, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(83, wcss_bt, mss_lte, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(84, wcss_bt, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(85, pbs0, cri_trng0, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(86, pbs1, cri_trng1, qdss_tracedata_b, NA, NA, NA, NA, NA, NA),
+ PINGROUP(87, pbs2, cri_trng, qdss_tracedata_b, gcc_tlmm, NA, NA, NA,
+ NA, NA),
+ PINGROUP(88, pri_mi2s, NA, NA, NA, qdss_tracedata_b, NA, NA, NA, NA),
+ PINGROUP(89, dmic0_clk, blsp7_spi, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(90, dmic0_data, blsp7_spi, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(91, pri_mi2s, NA, NA, NA, qdss_cti_trig_in_a1, NA, NA, NA, NA),
+ PINGROUP(92, pri_mi2s_ws, NA, NA, NA, qdss_tracedata_b, NA, NA, NA, NA),
+ PINGROUP(93, pri_mi2s, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(94, wsa_io, pri_mi2s, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(95, wsa_io, pri_mi2s, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(96, blsp_spi8, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(97, blsp_spi8, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(98, blsp_i2c8, blsp_spi8, gcc_plltest, NA, NA, NA, NA, NA, NA),
+ PINGROUP(99, blsp_i2c8, blsp_spi8, gcc_plltest, NA, NA, NA, NA, NA, NA),
+ PINGROUP(100, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(101, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(102, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(103, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(104, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(105, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(106, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(107, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(108, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(109, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(110, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(111, NA, NA, nav_pps_in_a, NA, NA, NA, NA, NA, NA),
+ PINGROUP(112, NA, pa_indicator, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(113, NA, nav_pps_in_b, nav_pps, modem_tsync, nav_tsync, NA,
+ NA, NA, NA),
+ PINGROUP(114, NA, ssbi_wtr1, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(115, NA, gsm1_tx, NA, dac_calib18, NA, NA, NA, NA, NA),
+ PINGROUP(116, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(117, gsm0_tx, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(118, NA, ebi_cdc, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(119, NA, ebi_cdc, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(120, NA, atest_char, ebi_cdc, NA, atest_tsens, NA, NA, NA, NA),
+ PINGROUP(121, NA, NA, NA, bimc_dte1, NA, NA, NA, NA, NA),
+ PINGROUP(122, NA, NA, NA, bimc_dte1, NA, NA, NA, NA, NA),
+ PINGROUP(123, NA, ssbi_wtr1, ebi_cdc, NA, NA, NA, NA, NA, NA),
+ PINGROUP(124, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(125, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(126, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(127, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(128, cam_mclk, NA, dac_calib20, NA, NA, NA, NA, NA, NA),
+ PINGROUP(129, ddr_bist, NA, dac_calib21, NA, NA, NA, NA, NA, NA),
+ PINGROUP(130, ddr_bist, NA, dac_calib22, NA, NA, NA, NA, NA, NA),
+ PINGROUP(131, ddr_bist, NA, dac_calib23, NA, NA, NA, NA, NA, NA),
+ PINGROUP(132, ddr_bist, NA, dac_calib24, NA, NA, NA, NA, NA, NA),
+ PINGROUP(133, NA, dac_calib25, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(134, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(135, sec_mi2s, blsp_spi7, blsp_i2c7, NA, NA, NA, NA, NA, NA),
+ PINGROUP(136, sec_mi2s, blsp_spi7, blsp_i2c7, NA, NA, NA, NA, NA, NA),
+ PINGROUP(137, sec_mi2s, blsp_spi7, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(138, sec_mi2s, blsp_spi7, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(139, tsens_max, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(140, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ PINGROUP(141, NA, NA, NA, NA, NA, NA, NA, NA, NA),
+ SDC_QDSD_PINGROUP(sdc1_clk, 0x10a000, 13, 6),
+ SDC_QDSD_PINGROUP(sdc1_cmd, 0x10a000, 11, 3),
+ SDC_QDSD_PINGROUP(sdc1_data, 0x10a000, 9, 0),
+ SDC_QDSD_PINGROUP(sdc1_rclk, 0x10a000, 15, 0),
+ SDC_QDSD_PINGROUP(sdc2_clk, 0x109000, 14, 6),
+ SDC_QDSD_PINGROUP(sdc2_cmd, 0x109000, 11, 3),
+ SDC_QDSD_PINGROUP(sdc2_data, 0x109000, 9, 0),
+ SDC_QDSD_PINGROUP(qdsd_clk, 0x19c000, 3, 0),
+ SDC_QDSD_PINGROUP(qdsd_cmd, 0x19c000, 8, 5),
+ SDC_QDSD_PINGROUP(qdsd_data0, 0x19c000, 13, 10),
+ SDC_QDSD_PINGROUP(qdsd_data1, 0x19c000, 18, 15),
+ SDC_QDSD_PINGROUP(qdsd_data2, 0x19c000, 23, 20),
+ SDC_QDSD_PINGROUP(qdsd_data3, 0x19c000, 28, 25),
+};
+
+static const struct msm_pinctrl_soc_data msm8953_pinctrl = {
+ .pins = msm8953_pins,
+ .npins = ARRAY_SIZE(msm8953_pins),
+ .functions = msm8953_functions,
+ .nfunctions = ARRAY_SIZE(msm8953_functions),
+ .groups = msm8953_groups,
+ .ngroups = ARRAY_SIZE(msm8953_groups),
+ .ngpios = 142,
+};
+
+static int msm8953_pinctrl_probe(struct platform_device *pdev)
+{
+ return msm_pinctrl_probe(pdev, &msm8953_pinctrl);
+}
+
+static const struct of_device_id msm8953_pinctrl_of_match[] = {
+ { .compatible = "qcom,msm8953-pinctrl", },
+ { },
+};
+
+static struct platform_driver msm8953_pinctrl_driver = {
+ .driver = {
+ .name = "msm8953-pinctrl",
+ .owner = THIS_MODULE,
+ .of_match_table = msm8953_pinctrl_of_match,
+ },
+ .probe = msm8953_pinctrl_probe,
+ .remove = msm_pinctrl_remove,
+};
+
+static int __init msm8953_pinctrl_init(void)
+{
+ return platform_driver_register(&msm8953_pinctrl_driver);
+}
+arch_initcall(msm8953_pinctrl_init);
+
+static void __exit msm8953_pinctrl_exit(void)
+{
+ platform_driver_unregister(&msm8953_pinctrl_driver);
+}
+module_exit(msm8953_pinctrl_exit);
+
+MODULE_DESCRIPTION("QTI msm8953 pinctrl driver");
+MODULE_LICENSE("GPL v2");
+MODULE_DEVICE_TABLE(of, msm8953_pinctrl_of_match);
diff --git a/drivers/platform/msm/ipa/ipa_clients/ecm_ipa.c b/drivers/platform/msm/ipa/ipa_clients/ecm_ipa.c
index 105294a..2975192 100644
--- a/drivers/platform/msm/ipa/ipa_clients/ecm_ipa.c
+++ b/drivers/platform/msm/ipa/ipa_clients/ecm_ipa.c
@@ -19,6 +19,8 @@
#include <linux/sched.h>
#include <linux/atomic.h>
#include <linux/ecm_ipa.h>
+#include "../ipa_common_i.h"
+#include "../ipa_v3/ipa_pm.h"
#define DRIVER_NAME "ecm_ipa"
#define ECM_IPA_IPV4_HDR_NAME "ecm_eth_ipv4"
@@ -120,6 +122,7 @@
* @usb_to_ipa_client: producer client
* @ipa_rm_resource_name_prod: IPA resource manager producer resource
* @ipa_rm_resource_name_cons: IPA resource manager consumer resource
+ * @pm_hdl: handle for IPA PM
*/
struct ecm_ipa_dev {
struct net_device *net;
@@ -137,6 +140,7 @@
enum ipa_client_type usb_to_ipa_client;
enum ipa_rm_resource_name ipa_rm_resource_name_prod;
enum ipa_rm_resource_name ipa_rm_resource_name_cons;
+ u32 pm_hdl;
};
static int ecm_ipa_open(struct net_device *net);
@@ -158,6 +162,8 @@
static struct net_device_stats *ecm_ipa_get_stats(struct net_device *net);
static int ecm_ipa_create_rm_resource(struct ecm_ipa_dev *ecm_ipa_ctx);
static void ecm_ipa_destroy_rm_resource(struct ecm_ipa_dev *ecm_ipa_ctx);
+static int ecm_ipa_register_pm_client(struct ecm_ipa_dev *ecm_ipa_ctx);
+static void ecm_ipa_deregister_pm_client(struct ecm_ipa_dev *ecm_ipa_ctx);
static int resource_request(struct ecm_ipa_dev *ecm_ipa_ctx);
static void resource_release(struct ecm_ipa_dev *ecm_ipa_ctx);
static netdev_tx_t ecm_ipa_start_xmit
@@ -403,27 +409,34 @@
ECM_IPA_DEBUG("usb_to_ipa_client = %d\n",
ecm_ipa_ctx->usb_to_ipa_client);
- ecm_ipa_ctx->ipa_rm_resource_name_cons =
- ipa_get_rm_resource_from_ep(ipa_to_usb_hdl);
- if (ecm_ipa_ctx->ipa_rm_resource_name_cons < 0) {
- ECM_IPA_ERROR("Error getting CONS RM resource from handle %d\n",
+ if (ipa_pm_is_used()) {
+ retval = ecm_ipa_register_pm_client(ecm_ipa_ctx);
+ } else {
+ ecm_ipa_ctx->ipa_rm_resource_name_cons =
+ ipa_get_rm_resource_from_ep(ipa_to_usb_hdl);
+ if (ecm_ipa_ctx->ipa_rm_resource_name_cons < 0) {
+ ECM_IPA_ERROR(
+ "Error getting CONS RM resource from handle %d\n",
+ ecm_ipa_ctx->ipa_rm_resource_name_cons);
+ return -EINVAL;
+ }
+ ECM_IPA_DEBUG("ipa_rm_resource_name_cons = %d\n",
ecm_ipa_ctx->ipa_rm_resource_name_cons);
- return -EINVAL;
- }
- ECM_IPA_DEBUG("ipa_rm_resource_name_cons = %d\n",
- ecm_ipa_ctx->ipa_rm_resource_name_cons);
- ecm_ipa_ctx->ipa_rm_resource_name_prod =
- ipa_get_rm_resource_from_ep(usb_to_ipa_hdl);
- if (ecm_ipa_ctx->ipa_rm_resource_name_prod < 0) {
- ECM_IPA_ERROR("Error getting PROD RM resource from handle %d\n",
+ ecm_ipa_ctx->ipa_rm_resource_name_prod =
+ ipa_get_rm_resource_from_ep(usb_to_ipa_hdl);
+ if (ecm_ipa_ctx->ipa_rm_resource_name_prod < 0) {
+ ECM_IPA_ERROR(
+ "Error getting PROD RM resource from handle %d\n",
+ ecm_ipa_ctx->ipa_rm_resource_name_prod);
+ return -EINVAL;
+ }
+ ECM_IPA_DEBUG("ipa_rm_resource_name_prod = %d\n",
ecm_ipa_ctx->ipa_rm_resource_name_prod);
- return -EINVAL;
- }
- ECM_IPA_DEBUG("ipa_rm_resource_name_prod = %d\n",
- ecm_ipa_ctx->ipa_rm_resource_name_prod);
- retval = ecm_ipa_create_rm_resource(ecm_ipa_ctx);
+ retval = ecm_ipa_create_rm_resource(ecm_ipa_ctx);
+ }
+
if (retval) {
ECM_IPA_ERROR("fail on RM create\n");
goto fail_create_rm;
@@ -488,7 +501,10 @@
fail:
ecm_ipa_deregister_properties();
fail_create_rm:
- ecm_ipa_destroy_rm_resource(ecm_ipa_ctx);
+ if (ipa_pm_is_used())
+ ecm_ipa_deregister_pm_client(ecm_ipa_ctx);
+ else
+ ecm_ipa_destroy_rm_resource(ecm_ipa_ctx);
return retval;
}
EXPORT_SYMBOL(ecm_ipa_connect);
@@ -746,7 +762,10 @@
netif_stop_queue(ecm_ipa_ctx->net);
ECM_IPA_DEBUG("queue stopped\n");
- ecm_ipa_destroy_rm_resource(ecm_ipa_ctx);
+ if (ipa_pm_is_used())
+ ecm_ipa_deregister_pm_client(ecm_ipa_ctx);
+ else
+ ecm_ipa_destroy_rm_resource(ecm_ipa_ctx);
outstanding_dropped_pkts =
atomic_read(&ecm_ipa_ctx->outstanding_pkts);
@@ -1117,15 +1136,65 @@
ECM_IPA_LOG_EXIT();
}
+static void ecm_ipa_pm_cb(void *p, enum ipa_pm_cb_event event)
+{
+ struct ecm_ipa_dev *ecm_ipa_ctx = p;
+
+ ECM_IPA_LOG_ENTRY();
+ if (event != IPA_PM_CLIENT_ACTIVATED) {
+ ECM_IPA_ERROR("unexpected event %d\n", event);
+ WARN_ON(1);
+ return;
+ }
+
+ if (netif_queue_stopped(ecm_ipa_ctx->net)) {
+ ECM_IPA_DEBUG("Resource Granted - starting queue\n");
+ netif_start_queue(ecm_ipa_ctx->net);
+ }
+ ECM_IPA_LOG_EXIT();
+}
+
+static int ecm_ipa_register_pm_client(struct ecm_ipa_dev *ecm_ipa_ctx)
+{
+ int result;
+ struct ipa_pm_register_params pm_reg;
+
+ memset(&pm_reg, 0, sizeof(pm_reg));
+ pm_reg.name = ecm_ipa_ctx->net->name;
+ pm_reg.user_data = ecm_ipa_ctx;
+ pm_reg.callback = ecm_ipa_pm_cb;
+ pm_reg.group = IPA_PM_GROUP_APPS;
+ result = ipa_pm_register(&pm_reg, &ecm_ipa_ctx->pm_hdl);
+ if (result) {
+ ECM_IPA_ERROR("failed to create IPA PM client %d\n", result);
+ return result;
+ }
+ return 0;
+}
+
+static void ecm_ipa_deregister_pm_client(struct ecm_ipa_dev *ecm_ipa_ctx)
+{
+ ipa_pm_deactivate_sync(ecm_ipa_ctx->pm_hdl);
+ ipa_pm_deregister(ecm_ipa_ctx->pm_hdl);
+ ecm_ipa_ctx->pm_hdl = ~0;
+}
+
static int resource_request(struct ecm_ipa_dev *ecm_ipa_ctx)
{
+ if (ipa_pm_is_used())
+ return ipa_pm_activate(ecm_ipa_ctx->pm_hdl);
+
return ipa_rm_inactivity_timer_request_resource(
IPA_RM_RESOURCE_STD_ECM_PROD);
}
static void resource_release(struct ecm_ipa_dev *ecm_ipa_ctx)
{
- ipa_rm_inactivity_timer_release_resource(IPA_RM_RESOURCE_STD_ECM_PROD);
+ if (ipa_pm_is_used())
+ ipa_pm_deferred_deactivate(ecm_ipa_ctx->pm_hdl);
+ else
+ ipa_rm_inactivity_timer_release_resource(
+ IPA_RM_RESOURCE_STD_ECM_PROD);
}
/**
diff --git a/drivers/platform/msm/ipa/ipa_clients/ipa_mhi_client.c b/drivers/platform/msm/ipa/ipa_clients/ipa_mhi_client.c
index 9b3b53d..4d3113f 100644
--- a/drivers/platform/msm/ipa/ipa_clients/ipa_mhi_client.c
+++ b/drivers/platform/msm/ipa/ipa_clients/ipa_mhi_client.c
@@ -19,6 +19,7 @@
#include <linux/ipa_qmi_service_v01.h>
#include <linux/ipa_mhi.h>
#include "../ipa_common_i.h"
+#include "../ipa_v3/ipa_pm.h"
#define IPA_MHI_DRV_NAME "ipa_mhi_client"
#define IPA_MHI_DBG(fmt, args...) \
@@ -136,6 +137,8 @@
u32 use_ipadma;
bool assert_bit40;
bool test_mode;
+ u32 pm_hdl;
+ u32 modem_pm_hdl;
};
static struct ipa_mhi_client_ctx *ipa_mhi_client_ctx;
@@ -834,25 +837,38 @@
IPA_MHI_DBG("event_context_array_addr 0x%llx\n",
ipa_mhi_client_ctx->event_context_array_addr);
- /* Add MHI <-> Q6 dependencies to IPA RM */
- res = ipa_rm_add_dependency(IPA_RM_RESOURCE_MHI_PROD,
- IPA_RM_RESOURCE_Q6_CONS);
- if (res && res != -EINPROGRESS) {
- IPA_MHI_ERR("failed to add dependency %d\n", res);
- goto fail_add_mhi_q6_dep;
- }
+ if (ipa_pm_is_used()) {
+ res = ipa_pm_activate_sync(ipa_mhi_client_ctx->pm_hdl);
+ if (res) {
+ IPA_MHI_ERR("failed activate client %d\n", res);
+ goto fail_pm_activate;
+ }
+ res = ipa_pm_activate_sync(ipa_mhi_client_ctx->modem_pm_hdl);
+ if (res) {
+ IPA_MHI_ERR("failed activate modem client %d\n", res);
+ goto fail_pm_activate_modem;
+ }
+ } else {
+ /* Add MHI <-> Q6 dependencies to IPA RM */
+ res = ipa_rm_add_dependency(IPA_RM_RESOURCE_MHI_PROD,
+ IPA_RM_RESOURCE_Q6_CONS);
+ if (res && res != -EINPROGRESS) {
+ IPA_MHI_ERR("failed to add dependency %d\n", res);
+ goto fail_add_mhi_q6_dep;
+ }
- res = ipa_rm_add_dependency(IPA_RM_RESOURCE_Q6_PROD,
- IPA_RM_RESOURCE_MHI_CONS);
- if (res && res != -EINPROGRESS) {
- IPA_MHI_ERR("failed to add dependency %d\n", res);
- goto fail_add_q6_mhi_dep;
- }
+ res = ipa_rm_add_dependency(IPA_RM_RESOURCE_Q6_PROD,
+ IPA_RM_RESOURCE_MHI_CONS);
+ if (res && res != -EINPROGRESS) {
+ IPA_MHI_ERR("failed to add dependency %d\n", res);
+ goto fail_add_q6_mhi_dep;
+ }
- res = ipa_mhi_request_prod();
- if (res) {
- IPA_MHI_ERR("failed request prod %d\n", res);
- goto fail_request_prod;
+ res = ipa_mhi_request_prod();
+ if (res) {
+ IPA_MHI_ERR("failed request prod %d\n", res);
+ goto fail_request_prod;
+ }
}
/* gsi params */
@@ -880,14 +896,23 @@
return 0;
fail_init_engine:
- ipa_mhi_release_prod();
+ if (!ipa_pm_is_used())
+ ipa_mhi_release_prod();
fail_request_prod:
- ipa_rm_delete_dependency(IPA_RM_RESOURCE_Q6_PROD,
- IPA_RM_RESOURCE_MHI_CONS);
+ if (!ipa_pm_is_used())
+ ipa_rm_delete_dependency(IPA_RM_RESOURCE_Q6_PROD,
+ IPA_RM_RESOURCE_MHI_CONS);
fail_add_q6_mhi_dep:
- ipa_rm_delete_dependency(IPA_RM_RESOURCE_MHI_PROD,
- IPA_RM_RESOURCE_Q6_CONS);
+ if (!ipa_pm_is_used())
+ ipa_rm_delete_dependency(IPA_RM_RESOURCE_MHI_PROD,
+ IPA_RM_RESOURCE_Q6_CONS);
fail_add_mhi_q6_dep:
+ if (ipa_pm_is_used())
+ ipa_pm_deactivate_sync(ipa_mhi_client_ctx->modem_pm_hdl);
+fail_pm_activate_modem:
+ if (ipa_pm_is_used())
+ ipa_pm_deactivate_sync(ipa_mhi_client_ctx->pm_hdl);
+fail_pm_activate:
ipa_mhi_set_state(IPA_MHI_STATE_INITIALIZED);
return res;
}
@@ -2095,20 +2120,32 @@
*/
IPA_ACTIVE_CLIENTS_INC_SIMPLE();
- IPA_MHI_DBG("release prod\n");
- res = ipa_mhi_release_prod();
- if (res) {
- IPA_MHI_ERR("ipa_mhi_release_prod failed %d\n", res);
- goto fail_release_prod;
- }
+ if (ipa_pm_is_used()) {
+ res = ipa_pm_deactivate_sync(ipa_mhi_client_ctx->pm_hdl);
+ if (res) {
+ IPA_MHI_ERR("fail to deactivate client %d\n", res);
+ goto fail_deactivate_pm;
+ }
+ res = ipa_pm_deactivate_sync(ipa_mhi_client_ctx->modem_pm_hdl);
+ if (res) {
+ IPA_MHI_ERR("fail to deactivate client %d\n", res);
+ goto fail_deactivate_modem_pm;
+ }
+ } else {
+ IPA_MHI_DBG("release prod\n");
+ res = ipa_mhi_release_prod();
+ if (res) {
+ IPA_MHI_ERR("ipa_mhi_release_prod failed %d\n", res);
+ goto fail_release_prod;
+ }
- IPA_MHI_DBG("wait for cons release\n");
- res = ipa_mhi_wait_for_cons_release();
- if (res) {
- IPA_MHI_ERR("ipa_mhi_wait_for_cons_release failed %d\n", res);
- goto fail_release_cons;
+ IPA_MHI_DBG("wait for cons release\n");
+ res = ipa_mhi_wait_for_cons_release();
+ if (res) {
+ IPA_MHI_ERR("ipa_mhi_wait_for_cons_release failed\n");
+ goto fail_release_cons;
+ }
}
-
usleep_range(IPA_MHI_SUSPEND_SLEEP_MIN, IPA_MHI_SUSPEND_SLEEP_MAX);
res = ipa_mhi_suspend_dl(force);
@@ -2132,8 +2169,15 @@
fail_suspend_dl_channel:
fail_release_cons:
+ if (!ipa_pm_is_used())
ipa_mhi_request_prod();
fail_release_prod:
+ if (ipa_pm_is_used())
+ ipa_pm_deactivate_sync(ipa_mhi_client_ctx->modem_pm_hdl);
+fail_deactivate_modem_pm:
+ if (ipa_pm_is_used())
+ ipa_pm_deactivate_sync(ipa_mhi_client_ctx->pm_hdl);
+fail_deactivate_pm:
IPA_ACTIVE_CLIENTS_DEC_SIMPLE();
fail_suspend_ul_channel:
ipa_mhi_resume_channels(true, ipa_mhi_client_ctx->ul_channels);
@@ -2193,10 +2237,23 @@
ipa_mhi_client_ctx->rm_cons_state = IPA_MHI_RM_STATE_GRANTED;
}
- res = ipa_mhi_request_prod();
- if (res) {
- IPA_MHI_ERR("ipa_mhi_request_prod failed %d\n", res);
- goto fail_request_prod;
+ if (ipa_pm_is_used()) {
+ res = ipa_pm_activate_sync(ipa_mhi_client_ctx->pm_hdl);
+ if (res) {
+ IPA_MHI_ERR("fail to activate client %d\n", res);
+ goto fail_pm_activate;
+ }
+ ipa_pm_activate_sync(ipa_mhi_client_ctx->modem_pm_hdl);
+ if (res) {
+ IPA_MHI_ERR("fail to activate client %d\n", res);
+ goto fail_pm_activate_modem;
+ }
+ } else {
+ res = ipa_mhi_request_prod();
+ if (res) {
+ IPA_MHI_ERR("ipa_mhi_request_prod failed %d\n", res);
+ goto fail_request_prod;
+ }
}
/* resume all UL channels */
@@ -2234,8 +2291,15 @@
fail_resume_dl_channels2:
ipa_mhi_suspend_channels(ipa_mhi_client_ctx->ul_channels);
fail_resume_ul_channels:
- ipa_mhi_release_prod();
+ if (!ipa_pm_is_used())
+ ipa_mhi_release_prod();
fail_request_prod:
+ if (ipa_pm_is_used())
+ ipa_pm_deactivate_sync(ipa_mhi_client_ctx->modem_pm_hdl);
+fail_pm_activate_modem:
+ if (ipa_pm_is_used())
+ ipa_pm_deactivate_sync(ipa_mhi_client_ctx->pm_hdl);
+fail_pm_activate:
ipa_mhi_suspend_channels(ipa_mhi_client_ctx->dl_channels);
fail_resume_dl_channels:
ipa_mhi_set_state(IPA_MHI_STATE_SUSPENDED);
@@ -2319,6 +2383,85 @@
debugfs_remove_recursive(dent);
}
+static void ipa_mhi_delete_rm_resources(void)
+{
+ int res;
+
+ if (ipa_mhi_client_ctx->state != IPA_MHI_STATE_INITIALIZED &&
+ ipa_mhi_client_ctx->state != IPA_MHI_STATE_READY) {
+
+ IPA_MHI_DBG("release prod\n");
+ res = ipa_mhi_release_prod();
+ if (res) {
+ IPA_MHI_ERR("ipa_mhi_release_prod failed %d\n",
+ res);
+ goto fail;
+ }
+ IPA_MHI_DBG("wait for cons release\n");
+ res = ipa_mhi_wait_for_cons_release();
+ if (res) {
+ IPA_MHI_ERR("ipa_mhi_wait_for_cons_release%d\n",
+ res);
+ goto fail;
+ }
+
+ usleep_range(IPA_MHI_SUSPEND_SLEEP_MIN,
+ IPA_MHI_SUSPEND_SLEEP_MAX);
+
+ IPA_MHI_DBG("deleate dependency Q6_PROD->MHI_CONS\n");
+ res = ipa_rm_delete_dependency(IPA_RM_RESOURCE_Q6_PROD,
+ IPA_RM_RESOURCE_MHI_CONS);
+ if (res) {
+ IPA_MHI_ERR(
+ "Error deleting dependency %d->%d, res=%d\n",
+ IPA_RM_RESOURCE_Q6_PROD,
+ IPA_RM_RESOURCE_MHI_CONS,
+ res);
+ goto fail;
+ }
+ IPA_MHI_DBG("deleate dependency MHI_PROD->Q6_CONS\n");
+ res = ipa_rm_delete_dependency(IPA_RM_RESOURCE_MHI_PROD,
+ IPA_RM_RESOURCE_Q6_CONS);
+ if (res) {
+ IPA_MHI_ERR(
+ "Error deleting dependency %d->%d, res=%d\n",
+ IPA_RM_RESOURCE_MHI_PROD,
+ IPA_RM_RESOURCE_Q6_CONS,
+ res);
+ goto fail;
+ }
+ }
+
+ res = ipa_rm_delete_resource(IPA_RM_RESOURCE_MHI_PROD);
+ if (res) {
+ IPA_MHI_ERR("Error deleting resource %d, res=%d\n",
+ IPA_RM_RESOURCE_MHI_PROD, res);
+ goto fail;
+ }
+
+ res = ipa_rm_delete_resource(IPA_RM_RESOURCE_MHI_CONS);
+ if (res) {
+ IPA_MHI_ERR("Error deleting resource %d, res=%d\n",
+ IPA_RM_RESOURCE_MHI_CONS, res);
+ goto fail;
+ }
+
+ return;
+fail:
+ ipa_assert();
+}
+
+static void ipa_mhi_deregister_pm(void)
+{
+ ipa_pm_deactivate_sync(ipa_mhi_client_ctx->pm_hdl);
+ ipa_pm_deregister(ipa_mhi_client_ctx->pm_hdl);
+ ipa_mhi_client_ctx->pm_hdl = ~0;
+
+ ipa_pm_deactivate_sync(ipa_mhi_client_ctx->modem_pm_hdl);
+ ipa_pm_deregister(ipa_mhi_client_ctx->modem_pm_hdl);
+ ipa_mhi_client_ctx->modem_pm_hdl = ~0;
+}
+
/**
* ipa_mhi_destroy() - Destroy MHI IPA
*
@@ -2351,62 +2494,10 @@
ipa_uc_mhi_cleanup();
}
-
- if (ipa_mhi_client_ctx->state != IPA_MHI_STATE_INITIALIZED &&
- ipa_mhi_client_ctx->state != IPA_MHI_STATE_READY) {
- IPA_MHI_DBG("release prod\n");
- res = ipa_mhi_release_prod();
- if (res) {
- IPA_MHI_ERR("ipa_mhi_release_prod failed %d\n", res);
- goto fail;
- }
- IPA_MHI_DBG("wait for cons release\n");
- res = ipa_mhi_wait_for_cons_release();
- if (res) {
- IPA_MHI_ERR("ipa_mhi_wait_for_cons_release failed %d\n",
- res);
- goto fail;
- }
- usleep_range(IPA_MHI_SUSPEND_SLEEP_MIN,
- IPA_MHI_SUSPEND_SLEEP_MAX);
-
- IPA_MHI_DBG("deleate dependency Q6_PROD->MHI_CONS\n");
- res = ipa_rm_delete_dependency(IPA_RM_RESOURCE_Q6_PROD,
- IPA_RM_RESOURCE_MHI_CONS);
- if (res) {
- IPA_MHI_ERR(
- "Error deleting dependency %d->%d, res=%d\n"
- , IPA_RM_RESOURCE_Q6_PROD,
- IPA_RM_RESOURCE_MHI_CONS,
- res);
- goto fail;
- }
- IPA_MHI_DBG("deleate dependency MHI_PROD->Q6_CONS\n");
- res = ipa_rm_delete_dependency(IPA_RM_RESOURCE_MHI_PROD,
- IPA_RM_RESOURCE_Q6_CONS);
- if (res) {
- IPA_MHI_ERR(
- "Error deleting dependency %d->%d, res=%d\n",
- IPA_RM_RESOURCE_MHI_PROD,
- IPA_RM_RESOURCE_Q6_CONS,
- res);
- goto fail;
- }
- }
-
- res = ipa_rm_delete_resource(IPA_RM_RESOURCE_MHI_PROD);
- if (res) {
- IPA_MHI_ERR("Error deleting resource %d, res=%d\n",
- IPA_RM_RESOURCE_MHI_PROD, res);
- goto fail;
- }
-
- res = ipa_rm_delete_resource(IPA_RM_RESOURCE_MHI_CONS);
- if (res) {
- IPA_MHI_ERR("Error deleting resource %d, res=%d\n",
- IPA_RM_RESOURCE_MHI_CONS, res);
- goto fail;
- }
+ if (ipa_pm_is_used())
+ ipa_mhi_deregister_pm();
+ else
+ ipa_mhi_delete_rm_resources();
ipa_mhi_debugfs_destroy();
destroy_workqueue(ipa_mhi_client_ctx->wq);
@@ -2420,6 +2511,132 @@
ipa_assert();
}
+static void ipa_mhi_pm_cb(void *p, enum ipa_pm_cb_event event)
+{
+ unsigned long flags;
+
+ IPA_MHI_FUNC_ENTRY();
+
+ if (event != IPA_PM_REQUEST_WAKEUP) {
+ IPA_MHI_ERR("Unexpected event %d\n", event);
+ WARN_ON(1);
+ return;
+ }
+
+ IPA_MHI_DBG("%s\n", MHI_STATE_STR(ipa_mhi_client_ctx->state));
+ spin_lock_irqsave(&ipa_mhi_client_ctx->state_lock, flags);
+ if (ipa_mhi_client_ctx->state == IPA_MHI_STATE_SUSPENDED) {
+ ipa_mhi_notify_wakeup();
+ } else if (ipa_mhi_client_ctx->state ==
+ IPA_MHI_STATE_SUSPEND_IN_PROGRESS) {
+ /* wakeup event will be trigger after suspend finishes */
+ ipa_mhi_client_ctx->trigger_wakeup = true;
+ }
+ spin_unlock_irqrestore(&ipa_mhi_client_ctx->state_lock, flags);
+ IPA_MHI_DBG("EXIT");
+}
+
+static int ipa_mhi_register_pm(void)
+{
+ int res;
+ struct ipa_pm_register_params params;
+
+ memset(¶ms, 0, sizeof(params));
+ params.name = "MHI";
+ params.callback = ipa_mhi_pm_cb;
+ params.group = IPA_PM_GROUP_DEFAULT;
+ res = ipa_pm_register(¶ms, &ipa_mhi_client_ctx->pm_hdl);
+ if (res) {
+ IPA_MHI_ERR("fail to register with PM %d\n", res);
+ return res;
+ }
+
+ res = ipa_pm_associate_ipa_cons_to_client(ipa_mhi_client_ctx->pm_hdl,
+ IPA_CLIENT_MHI_CONS);
+ if (res) {
+ IPA_MHI_ERR("fail to associate cons with PM %d\n", res);
+ goto fail_pm_cons;
+ }
+
+ res = ipa_pm_set_perf_profile(ipa_mhi_client_ctx->pm_hdl, 1000);
+ if (res) {
+ IPA_MHI_ERR("fail to set perf profile to PM %d\n", res);
+ goto fail_pm_cons;
+ }
+
+ /* create a modem client for clock scaling */
+ memset(¶ms, 0, sizeof(params));
+ params.name = "MODEM (MHI)";
+ params.group = IPA_PM_GROUP_MODEM;
+ params.skip_clk_vote = true;
+ res = ipa_pm_register(¶ms, &ipa_mhi_client_ctx->modem_pm_hdl);
+ if (res) {
+ IPA_MHI_ERR("fail to register with PM %d\n", res);
+ goto fail_pm_cons;
+ }
+
+ return 0;
+
+fail_pm_cons:
+ ipa_pm_deregister(ipa_mhi_client_ctx->pm_hdl);
+ ipa_mhi_client_ctx->pm_hdl = ~0;
+ return res;
+}
+
+static int ipa_mhi_create_rm_resources(void)
+{
+ int res;
+ struct ipa_rm_create_params mhi_prod_params;
+ struct ipa_rm_create_params mhi_cons_params;
+ struct ipa_rm_perf_profile profile;
+
+ /* Create PROD in IPA RM */
+ memset(&mhi_prod_params, 0, sizeof(mhi_prod_params));
+ mhi_prod_params.name = IPA_RM_RESOURCE_MHI_PROD;
+ mhi_prod_params.floor_voltage = IPA_VOLTAGE_SVS;
+ mhi_prod_params.reg_params.notify_cb = ipa_mhi_rm_prod_notify;
+ res = ipa_rm_create_resource(&mhi_prod_params);
+ if (res) {
+ IPA_MHI_ERR("fail to create IPA_RM_RESOURCE_MHI_PROD\n");
+ goto fail_create_rm_prod;
+ }
+
+ memset(&profile, 0, sizeof(profile));
+ profile.max_supported_bandwidth_mbps = 1000;
+ res = ipa_rm_set_perf_profile(IPA_RM_RESOURCE_MHI_PROD, &profile);
+ if (res) {
+ IPA_MHI_ERR("fail to set profile to MHI_PROD\n");
+ goto fail_perf_rm_prod;
+ }
+
+ /* Create CONS in IPA RM */
+ memset(&mhi_cons_params, 0, sizeof(mhi_cons_params));
+ mhi_cons_params.name = IPA_RM_RESOURCE_MHI_CONS;
+ mhi_cons_params.floor_voltage = IPA_VOLTAGE_SVS;
+ mhi_cons_params.request_resource = ipa_mhi_rm_cons_request;
+ mhi_cons_params.release_resource = ipa_mhi_rm_cons_release;
+ res = ipa_rm_create_resource(&mhi_cons_params);
+ if (res) {
+ IPA_MHI_ERR("fail to create IPA_RM_RESOURCE_MHI_CONS\n");
+ goto fail_create_rm_cons;
+ }
+
+ memset(&profile, 0, sizeof(profile));
+ profile.max_supported_bandwidth_mbps = 1000;
+ res = ipa_rm_set_perf_profile(IPA_RM_RESOURCE_MHI_CONS, &profile);
+ if (res) {
+ IPA_MHI_ERR("fail to set profile to MHI_CONS\n");
+ goto fail_perf_rm_cons;
+ }
+fail_perf_rm_cons:
+ ipa_rm_delete_resource(IPA_RM_RESOURCE_MHI_CONS);
+fail_create_rm_cons:
+fail_perf_rm_prod:
+ ipa_rm_delete_resource(IPA_RM_RESOURCE_MHI_PROD);
+fail_create_rm_prod:
+ return res;
+}
+
/**
* ipa_mhi_init() - Initialize IPA MHI driver
* @params: initialization params
@@ -2437,9 +2654,6 @@
int ipa_mhi_init(struct ipa_mhi_init_params *params)
{
int res;
- struct ipa_rm_create_params mhi_prod_params;
- struct ipa_rm_create_params mhi_cons_params;
- struct ipa_rm_perf_profile profile;
IPA_MHI_FUNC_ENTRY();
@@ -2500,43 +2714,14 @@
goto fail_create_wq;
}
- /* Create PROD in IPA RM */
- memset(&mhi_prod_params, 0, sizeof(mhi_prod_params));
- mhi_prod_params.name = IPA_RM_RESOURCE_MHI_PROD;
- mhi_prod_params.floor_voltage = IPA_VOLTAGE_SVS;
- mhi_prod_params.reg_params.notify_cb = ipa_mhi_rm_prod_notify;
- res = ipa_rm_create_resource(&mhi_prod_params);
+ if (ipa_pm_is_used())
+ res = ipa_mhi_register_pm();
+ else
+ res = ipa_mhi_create_rm_resources();
if (res) {
- IPA_MHI_ERR("fail to create IPA_RM_RESOURCE_MHI_PROD\n");
- goto fail_create_rm_prod;
- }
-
- memset(&profile, 0, sizeof(profile));
- profile.max_supported_bandwidth_mbps = 1000;
- res = ipa_rm_set_perf_profile(IPA_RM_RESOURCE_MHI_PROD, &profile);
- if (res) {
- IPA_MHI_ERR("fail to set profile to MHI_PROD\n");
- goto fail_perf_rm_prod;
- }
-
- /* Create CONS in IPA RM */
- memset(&mhi_cons_params, 0, sizeof(mhi_cons_params));
- mhi_cons_params.name = IPA_RM_RESOURCE_MHI_CONS;
- mhi_cons_params.floor_voltage = IPA_VOLTAGE_SVS;
- mhi_cons_params.request_resource = ipa_mhi_rm_cons_request;
- mhi_cons_params.release_resource = ipa_mhi_rm_cons_release;
- res = ipa_rm_create_resource(&mhi_cons_params);
- if (res) {
- IPA_MHI_ERR("fail to create IPA_RM_RESOURCE_MHI_CONS\n");
- goto fail_create_rm_cons;
- }
-
- memset(&profile, 0, sizeof(profile));
- profile.max_supported_bandwidth_mbps = 1000;
- res = ipa_rm_set_perf_profile(IPA_RM_RESOURCE_MHI_CONS, &profile);
- if (res) {
- IPA_MHI_ERR("fail to set profile to MHI_CONS\n");
- goto fail_perf_rm_cons;
+ IPA_MHI_ERR("failed to create RM resources\n");
+ res = -EFAULT;
+ goto fail_rm;
}
/* Initialize uC interface */
@@ -2551,12 +2736,7 @@
IPA_MHI_FUNC_EXIT();
return 0;
-fail_perf_rm_cons:
- ipa_rm_delete_resource(IPA_RM_RESOURCE_MHI_CONS);
-fail_create_rm_cons:
-fail_perf_rm_prod:
- ipa_rm_delete_resource(IPA_RM_RESOURCE_MHI_PROD);
-fail_create_rm_prod:
+fail_rm:
destroy_workqueue(ipa_mhi_client_ctx->wq);
fail_create_wq:
kfree(ipa_mhi_client_ctx);
diff --git a/drivers/platform/msm/ipa/ipa_clients/ipa_uc_offload.c b/drivers/platform/msm/ipa/ipa_clients/ipa_uc_offload.c
index a15a9d8..e19d297 100644
--- a/drivers/platform/msm/ipa/ipa_clients/ipa_uc_offload.c
+++ b/drivers/platform/msm/ipa/ipa_clients/ipa_uc_offload.c
@@ -13,6 +13,7 @@
#include <linux/ipa_uc_offload.h>
#include <linux/msm_ipa.h>
#include "../ipa_common_i.h"
+#include "../ipa_v3/ipa_pm.h"
#define IPA_NTN_DMA_POOL_ALIGNMENT 8
#define OFFLOAD_DRV_NAME "ipa_uc_offload"
@@ -69,6 +70,7 @@
char netdev_name[IPA_RESOURCE_NAME_MAX];
ipa_notify_cb notify;
struct completion ntn_completion;
+ u32 pm_hdl;
};
static struct ipa_uc_offload_ctx *ipa_uc_offload_ctx[IPA_UC_MAX_PROT_SIZE];
@@ -113,22 +115,53 @@
return 0;
}
-static int ipa_uc_offload_ntn_reg_intf(
- struct ipa_uc_offload_intf_params *inp,
- struct ipa_uc_offload_out_params *outp,
+static void ipa_uc_offload_ntn_pm_cb(void *p, enum ipa_pm_cb_event event)
+{
+ /* suspend/resume is not supported */
+ IPA_UC_OFFLOAD_DBG("event = %d\n", event);
+}
+
+static int ipa_uc_offload_ntn_register_pm_client(
struct ipa_uc_offload_ctx *ntn_ctx)
{
- struct ipa_ioc_add_hdr *hdr = NULL;
- struct ipa_tx_intf tx;
- struct ipa_rx_intf rx;
- struct ipa_ioc_tx_intf_prop tx_prop[2];
- struct ipa_ioc_rx_intf_prop rx_prop[2];
- struct ipa_rm_create_params param;
- u32 len;
- int ret = 0;
+ int res;
+ struct ipa_pm_register_params params;
- IPA_UC_OFFLOAD_DBG("register interface for netdev %s\n",
- inp->netdev_name);
+ memset(¶ms, 0, sizeof(params));
+ params.name = "ETH";
+ params.callback = ipa_uc_offload_ntn_pm_cb;
+ params.user_data = ntn_ctx;
+ params.group = IPA_PM_GROUP_DEFAULT;
+ res = ipa_pm_register(¶ms, &ntn_ctx->pm_hdl);
+ if (res) {
+ IPA_UC_OFFLOAD_ERR("fail to register with PM %d\n", res);
+ return res;
+ }
+
+ res = ipa_pm_associate_ipa_cons_to_client(ntn_ctx->pm_hdl,
+ IPA_CLIENT_ETHERNET_CONS);
+ if (res) {
+ IPA_UC_OFFLOAD_ERR("fail to associate cons with PM %d\n", res);
+ ipa_pm_deregister(ntn_ctx->pm_hdl);
+ ntn_ctx->pm_hdl = ~0;
+ return res;
+ }
+
+ return 0;
+}
+
+static void ipa_uc_offload_ntn_deregister_pm_client(
+ struct ipa_uc_offload_ctx *ntn_ctx)
+{
+ ipa_pm_deactivate_sync(ntn_ctx->pm_hdl);
+ ipa_pm_deregister(ntn_ctx->pm_hdl);
+}
+static int ipa_uc_offload_ntn_create_rm_resources(
+ struct ipa_uc_offload_ctx *ntn_ctx)
+{
+ int ret;
+ struct ipa_rm_create_params param;
+
memset(¶m, 0, sizeof(param));
param.name = IPA_RM_RESOURCE_ETHERNET_PROD;
param.reg_params.user_data = ntn_ctx;
@@ -147,9 +180,37 @@
ret = ipa_rm_create_resource(¶m);
if (ret) {
IPA_UC_OFFLOAD_ERR("fail to create ETHERNET_CONS resource\n");
- goto fail_create_rm_cons;
+ ipa_rm_delete_resource(IPA_RM_RESOURCE_ETHERNET_PROD);
+ return -EFAULT;
}
+ return 0;
+}
+
+static int ipa_uc_offload_ntn_reg_intf(
+ struct ipa_uc_offload_intf_params *inp,
+ struct ipa_uc_offload_out_params *outp,
+ struct ipa_uc_offload_ctx *ntn_ctx)
+{
+ struct ipa_ioc_add_hdr *hdr = NULL;
+ struct ipa_tx_intf tx;
+ struct ipa_rx_intf rx;
+ struct ipa_ioc_tx_intf_prop tx_prop[2];
+ struct ipa_ioc_rx_intf_prop rx_prop[2];
+ int ret = 0;
+ u32 len;
+
+
+ IPA_UC_OFFLOAD_DBG("register interface for netdev %s\n",
+ inp->netdev_name);
+ if (ipa_pm_is_used())
+ ret = ipa_uc_offload_ntn_register_pm_client(ntn_ctx);
+ else
+ ret = ipa_uc_offload_ntn_create_rm_resources(ntn_ctx);
+ if (ret) {
+ IPA_UC_OFFLOAD_ERR("fail to create rm resource\n");
+ return -EFAULT;
+ }
memcpy(ntn_ctx->netdev_name, inp->netdev_name, IPA_RESOURCE_NAME_MAX);
ntn_ctx->hdr_len = inp->hdr_info[0].hdr_len;
ntn_ctx->notify = inp->notify;
@@ -228,9 +289,12 @@
fail:
kfree(hdr);
fail_alloc:
- ipa_rm_delete_resource(IPA_RM_RESOURCE_ETHERNET_CONS);
-fail_create_rm_cons:
- ipa_rm_delete_resource(IPA_RM_RESOURCE_ETHERNET_PROD);
+ if (ipa_pm_is_used()) {
+ ipa_uc_offload_ntn_deregister_pm_client(ntn_ctx);
+ } else {
+ ipa_rm_delete_resource(IPA_RM_RESOURCE_ETHERNET_CONS);
+ ipa_rm_delete_resource(IPA_RM_RESOURCE_ETHERNET_PROD);
+ }
return ret;
}
@@ -348,25 +412,34 @@
return -EINVAL;
}
- result = ipa_rm_add_dependency(IPA_RM_RESOURCE_ETHERNET_PROD,
- IPA_RM_RESOURCE_APPS_CONS);
- if (result) {
- IPA_UC_OFFLOAD_ERR("fail to add rm dependency: %d\n", result);
- return result;
- }
+ if (ipa_pm_is_used()) {
+ result = ipa_pm_activate_sync(ntn_ctx->pm_hdl);
+ if (result) {
+ IPA_UC_OFFLOAD_ERR("fail to activate: %d\n", result);
+ return result;
+ }
+ } else {
+ result = ipa_rm_add_dependency(IPA_RM_RESOURCE_ETHERNET_PROD,
+ IPA_RM_RESOURCE_APPS_CONS);
+ if (result) {
+ IPA_UC_OFFLOAD_ERR("fail to add rm dependency: %d\n",
+ result);
+ return result;
+ }
- result = ipa_rm_request_resource(IPA_RM_RESOURCE_ETHERNET_PROD);
- if (result == -EINPROGRESS) {
- if (wait_for_completion_timeout(&ntn_ctx->ntn_completion,
- 10*HZ) == 0) {
- IPA_UC_OFFLOAD_ERR("ETH_PROD resource req time out\n");
+ result = ipa_rm_request_resource(IPA_RM_RESOURCE_ETHERNET_PROD);
+ if (result == -EINPROGRESS) {
+ if (wait_for_completion_timeout(&ntn_ctx->ntn_completion
+ , 10*HZ) == 0) {
+ IPA_UC_OFFLOAD_ERR("ETH_PROD req timeout\n");
+ result = -EFAULT;
+ goto fail;
+ }
+ } else if (result != 0) {
+ IPA_UC_OFFLOAD_ERR("fail to request resource\n");
result = -EFAULT;
goto fail;
}
- } else if (result != 0) {
- IPA_UC_OFFLOAD_ERR("fail to request resource\n");
- result = -EFAULT;
- goto fail;
}
ntn_ctx->state = IPA_UC_OFFLOAD_STATE_UP;
@@ -383,8 +456,9 @@
return 0;
fail:
- ipa_rm_delete_dependency(IPA_RM_RESOURCE_ETHERNET_PROD,
- IPA_RM_RESOURCE_APPS_CONS);
+ if (!ipa_pm_is_used())
+ ipa_rm_delete_dependency(IPA_RM_RESOURCE_ETHERNET_PROD,
+ IPA_RM_RESOURCE_APPS_CONS);
return result;
}
@@ -455,6 +529,11 @@
return -EINVAL;
}
+ if (ipa_pm_is_used())
+ return ipa_pm_set_perf_profile(
+ ipa_uc_offload_ctx[IPA_UC_NTN]->pm_hdl,
+ profile->max_supported_bw_mbps);
+
if (ipa_rm_set_perf_profile(resource_name, &rm_profile)) {
IPA_UC_OFFLOAD_ERR("fail to setup rm perf profile\n");
return -EFAULT;
@@ -471,18 +550,27 @@
ntn_ctx->state = IPA_UC_OFFLOAD_STATE_INITIALIZED;
- ret = ipa_rm_release_resource(IPA_RM_RESOURCE_ETHERNET_PROD);
- if (ret) {
- IPA_UC_OFFLOAD_ERR("fail to release ETHERNET_PROD res: %d\n",
- ret);
- return -EFAULT;
- }
+ if (ipa_pm_is_used()) {
+ ret = ipa_pm_deactivate_sync(ntn_ctx->pm_hdl);
+ if (ret) {
+ IPA_UC_OFFLOAD_ERR("fail to deactivate res: %d\n",
+ ret);
+ return -EFAULT;
+ }
+ } else {
+ ret = ipa_rm_release_resource(IPA_RM_RESOURCE_ETHERNET_PROD);
+ if (ret) {
+ IPA_UC_OFFLOAD_ERR("fail release ETHERNET_PROD: %d\n",
+ ret);
+ return -EFAULT;
+ }
- ret = ipa_rm_delete_dependency(IPA_RM_RESOURCE_ETHERNET_PROD,
- IPA_RM_RESOURCE_APPS_CONS);
- if (ret) {
- IPA_UC_OFFLOAD_ERR("fail to del dep ETH_PROD->APPS, %d\n", ret);
- return -EFAULT;
+ ret = ipa_rm_delete_dependency(IPA_RM_RESOURCE_ETHERNET_PROD,
+ IPA_RM_RESOURCE_APPS_CONS);
+ if (ret) {
+ IPA_UC_OFFLOAD_ERR("fail del dep ETH->APPS, %d\n", ret);
+ return -EFAULT;
+ }
}
ipa_ep_idx_ul = ipa_get_ep_mapping(IPA_CLIENT_ETHERNET_PROD);
@@ -539,14 +627,18 @@
int len, result = 0;
struct ipa_ioc_del_hdr *hdr;
- if (ipa_rm_delete_resource(IPA_RM_RESOURCE_ETHERNET_PROD)) {
- IPA_UC_OFFLOAD_ERR("fail to delete ETHERNET_PROD resource\n");
- return -EFAULT;
- }
+ if (ipa_pm_is_used()) {
+ ipa_uc_offload_ntn_deregister_pm_client(ntn_ctx);
+ } else {
+ if (ipa_rm_delete_resource(IPA_RM_RESOURCE_ETHERNET_PROD)) {
+ IPA_UC_OFFLOAD_ERR("fail to delete ETHERNET_PROD\n");
+ return -EFAULT;
+ }
- if (ipa_rm_delete_resource(IPA_RM_RESOURCE_ETHERNET_CONS)) {
- IPA_UC_OFFLOAD_ERR("fail to delete ETHERNET_CONS resource\n");
- return -EFAULT;
+ if (ipa_rm_delete_resource(IPA_RM_RESOURCE_ETHERNET_CONS)) {
+ IPA_UC_OFFLOAD_ERR("fail to delete ETHERNET_CONS\n");
+ return -EFAULT;
+ }
}
len = sizeof(struct ipa_ioc_del_hdr) + 2 * sizeof(struct ipa_hdr_del);
diff --git a/drivers/platform/msm/ipa/ipa_clients/ipa_usb.c b/drivers/platform/msm/ipa/ipa_clients/ipa_usb.c
index f5d8d61..745e429 100644
--- a/drivers/platform/msm/ipa/ipa_clients/ipa_usb.c
+++ b/drivers/platform/msm/ipa/ipa_clients/ipa_usb.c
@@ -119,6 +119,12 @@
bool cons_requested_released;
};
+struct ipa3_usb_pm_context {
+ struct ipa_pm_register_params reg_params;
+ struct work_struct *remote_wakeup_work;
+ u32 hdl;
+};
+
enum ipa3_usb_state {
IPA_USB_INVALID,
IPA_USB_INITIALIZED,
@@ -157,6 +163,7 @@
*/
struct ipa3_usb_transport_type_ctx {
struct ipa3_usb_rm_context rm_ctx;
+ struct ipa3_usb_pm_context pm_ctx;
int (*ipa_usb_notify_cb)(enum ipa_usb_notify_event, void *user_data);
void *user_data;
enum ipa3_usb_state state;
@@ -362,7 +369,8 @@
ipa3_usb_state_to_string(new_state));
}
- if (state_legal && (new_state == IPA_USB_CONNECTED)) {
+ if (!ipa_pm_is_used() &&
+ state_legal && (new_state == IPA_USB_CONNECTED)) {
rm_ctx = &ipa3_usb_ctx->ttype_ctx[ttype].rm_ctx;
if ((rm_ctx->cons_state == IPA_USB_CONS_GRANTED) ||
rm_ctx->cons_requested_released) {
@@ -656,6 +664,30 @@
return ipa3_usb_cons_release_resource_cb_do(IPA_USB_TRANSPORT_DPL);
}
+static void ipa3_usb_pm_cb(void *p, enum ipa_pm_cb_event event)
+{
+ struct ipa3_usb_transport_type_ctx *ttype_ctx =
+ (struct ipa3_usb_transport_type_ctx *)p;
+ unsigned long flags;
+
+ IPA_USB_DBG_LOW("entry\n");
+
+ if (event != IPA_PM_REQUEST_WAKEUP) {
+ IPA_USB_ERR("Unexpected event %d\n", event);
+ WARN_ON(1);
+ return;
+ }
+
+ spin_lock_irqsave(&ipa3_usb_ctx->state_lock, flags);
+ IPA_USB_DBG("state is %s\n",
+ ipa3_usb_state_to_string(ttype_ctx->state));
+ if (ttype_ctx->state == IPA_USB_SUSPENDED)
+ queue_work(ipa3_usb_ctx->wq,
+ ttype_ctx->pm_ctx.remote_wakeup_work);
+ spin_unlock_irqrestore(&ipa3_usb_ctx->state_lock, flags);
+ IPA_USB_DBG_LOW("exit\n");
+}
+
static char *ipa3_usb_teth_prot_to_string(enum ipa_usb_teth_prot teth_prot)
{
switch (teth_prot) {
@@ -703,6 +735,59 @@
return 0;
}
+static int ipa3_usb_register_pm(enum ipa3_usb_transport_type ttype)
+{
+ struct ipa3_usb_transport_type_ctx *ttype_ctx =
+ &ipa3_usb_ctx->ttype_ctx[ttype];
+ int result;
+
+ memset(&ttype_ctx->pm_ctx.reg_params, 0,
+ sizeof(ttype_ctx->pm_ctx.reg_params));
+ ttype_ctx->pm_ctx.reg_params.name = (ttype == IPA_USB_TRANSPORT_DPL) ?
+ "USB DPL" : "USB";
+ ttype_ctx->pm_ctx.reg_params.callback = ipa3_usb_pm_cb;
+ ttype_ctx->pm_ctx.reg_params.user_data = ttype_ctx;
+ ttype_ctx->pm_ctx.reg_params.group = IPA_PM_GROUP_DEFAULT;
+
+ result = ipa_pm_register(&ttype_ctx->pm_ctx.reg_params,
+ &ttype_ctx->pm_ctx.hdl);
+ if (result) {
+ IPA_USB_ERR("fail to register with PM %d\n", result);
+ goto fail_pm_reg;
+ }
+
+ result = ipa_pm_associate_ipa_cons_to_client(ttype_ctx->pm_ctx.hdl,
+ (ttype == IPA_USB_TRANSPORT_DPL) ?
+ IPA_CLIENT_USB_DPL_CONS : IPA_CLIENT_USB_CONS);
+ if (result) {
+ IPA_USB_ERR("fail to associate cons with PM %d\n", result);
+ goto fail_pm_cons;
+ }
+
+ return 0;
+
+fail_pm_cons:
+ ipa_pm_deregister(ttype_ctx->pm_ctx.hdl);
+fail_pm_reg:
+ memset(&ttype_ctx->pm_ctx.reg_params, 0,
+ sizeof(ttype_ctx->pm_ctx.reg_params));
+ return result;
+}
+
+static int ipa3_usb_deregister_pm(enum ipa3_usb_transport_type ttype)
+{
+ struct ipa3_usb_pm_context *pm_ctx =
+ &ipa3_usb_ctx->ttype_ctx[ttype].pm_ctx;
+ int result;
+
+ result = ipa_pm_deregister(pm_ctx->hdl);
+ if (result)
+ return result;
+
+ memset(&pm_ctx->reg_params, 0, sizeof(pm_ctx->reg_params));
+ return 0;
+}
+
static int ipa3_usb_create_rm_resources(enum ipa3_usb_transport_type ttype)
{
struct ipa3_usb_rm_context *rm_ctx;
@@ -802,7 +887,10 @@
}
/* Create IPA RM USB resources */
- result = ipa3_usb_create_rm_resources(ttype);
+ if (ipa_pm_is_used())
+ result = ipa3_usb_register_pm(ttype);
+ else
+ result = ipa3_usb_create_rm_resources(ttype);
if (result) {
IPA_USB_ERR("Failed creating IPA RM USB resources\n");
goto bad_params;
@@ -934,12 +1022,18 @@
teth_prot_init_fail:
if ((IPA3_USB_IS_TTYPE_DPL(ttype))
|| (ipa3_usb_ctx->num_init_prot == 0)) {
- ipa3_usb_ctx->ttype_ctx[ttype].rm_ctx.prod_valid = false;
- ipa3_usb_ctx->ttype_ctx[ttype].rm_ctx.cons_valid = false;
- ipa_rm_delete_resource(
+ if (ipa_pm_is_used()) {
+ ipa3_usb_deregister_pm(ttype);
+ } else {
+ ipa3_usb_ctx->ttype_ctx[ttype].rm_ctx.prod_valid =
+ false;
+ ipa3_usb_ctx->ttype_ctx[ttype].rm_ctx.cons_valid =
+ false;
+ ipa_rm_delete_resource(
ipa3_usb_ctx->ttype_ctx[ttype].rm_ctx.prod_params.name);
- ipa_rm_delete_resource(
+ ipa_rm_delete_resource(
ipa3_usb_ctx->ttype_ctx[ttype].rm_ctx.cons_params.name);
+ }
}
bad_params:
mutex_unlock(&ipa3_usb_ctx->general_mutex);
@@ -1393,6 +1487,9 @@
{
int res = 0;
+ if (ipa_pm_is_used())
+ return 0;
+
/*
* Add DPL dependency to RM dependency graph, first add_dependency call
* is sync in order to make sure the IPA clocks are up before we
@@ -1572,6 +1669,9 @@
{
int res;
+ if (ipa_pm_is_used())
+ return 0;
+
/* Remove DPL RM dependency */
res = ipa_rm_delete_dependency(IPA_RM_RESOURCE_USB_DPL_DUMMY_PROD,
IPA_RM_RESOURCE_Q6_CONS);
@@ -1699,32 +1799,51 @@
return result;
}
- /* Set RM PROD & CONS perf profile */
- profile.max_supported_bandwidth_mbps =
- params->max_supported_bandwidth_mbps;
- result = ipa_rm_set_perf_profile(
- ipa3_usb_ctx->ttype_ctx[ttype].rm_ctx.prod_params.name,
- &profile);
- if (result) {
- IPA_USB_ERR("failed to set %s perf profile\n",
- ipa_rm_resource_str(ipa3_usb_ctx->ttype_ctx[ttype].
- rm_ctx.prod_params.name));
- return result;
- }
- result = ipa_rm_set_perf_profile(
- ipa3_usb_ctx->ttype_ctx[ttype].rm_ctx.cons_params.name,
- &profile);
- if (result) {
- IPA_USB_ERR("failed to set %s perf profile\n",
- ipa_rm_resource_str(ipa3_usb_ctx->ttype_ctx[ttype].
- rm_ctx.cons_params.name));
- return result;
- }
+ if (ipa_pm_is_used()) {
+ result = ipa_pm_set_perf_profile(
+ ipa3_usb_ctx->ttype_ctx[ttype].pm_ctx.hdl,
+ params->max_supported_bandwidth_mbps);
+ if (result) {
+ IPA_USB_ERR("failed to set perf profile\n");
+ return result;
+ }
- /* Request PROD */
- result = ipa3_usb_request_prod(ttype);
- if (result)
- return result;
+ result = ipa_pm_activate_sync(
+ ipa3_usb_ctx->ttype_ctx[ttype].pm_ctx.hdl);
+ if (result) {
+ IPA_USB_ERR("failed to activate pm\n");
+ return result;
+ }
+ } else {
+ /* Set RM PROD & CONS perf profile */
+ profile.max_supported_bandwidth_mbps =
+ params->max_supported_bandwidth_mbps;
+ result = ipa_rm_set_perf_profile(
+ ipa3_usb_ctx->ttype_ctx[ttype].rm_ctx.prod_params.name,
+ &profile);
+ if (result) {
+ IPA_USB_ERR("failed to set %s perf profile\n",
+ ipa_rm_resource_str(ipa3_usb_ctx->
+ ttype_ctx[ttype].
+ rm_ctx.prod_params.name));
+ return result;
+ }
+ result = ipa_rm_set_perf_profile(
+ ipa3_usb_ctx->ttype_ctx[ttype].rm_ctx.cons_params.name,
+ &profile);
+ if (result) {
+ IPA_USB_ERR("failed to set %s perf profile\n",
+ ipa_rm_resource_str(ipa3_usb_ctx->
+ ttype_ctx[ttype].
+ rm_ctx.cons_params.name));
+ return result;
+ }
+
+ /* Request PROD */
+ result = ipa3_usb_request_prod(ttype);
+ if (result)
+ return result;
+ }
if (params->teth_prot != IPA_USB_DIAG) {
/* Start UL channel */
@@ -1775,7 +1894,11 @@
ipa3_reset_gsi_event_ring(params->usb_to_ipa_clnt_hdl);
}
connect_ul_fail:
- ipa3_usb_release_prod(ttype);
+ if (ipa_pm_is_used())
+ ipa_pm_deactivate_sync(
+ ipa3_usb_ctx->ttype_ctx[ttype].pm_ctx.hdl);
+ else
+ ipa3_usb_release_prod(ttype);
return result;
}
@@ -2224,7 +2347,11 @@
goto bad_params;
if (orig_state != IPA_USB_SUSPENDED) {
- result = ipa3_usb_release_prod(ttype);
+ if (ipa_pm_is_used())
+ result = ipa_pm_deactivate_sync(
+ ipa3_usb_ctx->ttype_ctx[ttype].pm_ctx.hdl);
+ else
+ result = ipa3_usb_release_prod(ttype);
if (result) {
IPA_USB_ERR("failed to release PROD.\n");
goto bad_params;
@@ -2334,13 +2461,19 @@
(ipa3_usb_ctx->num_init_prot == 0)) {
if (!ipa3_usb_set_state(IPA_USB_INVALID, false, ttype))
IPA_USB_ERR("failed to change state to invalid\n");
- ipa_rm_delete_resource(
+ if (ipa_pm_is_used()) {
+ ipa3_usb_deregister_pm(ttype);
+ } else {
+ ipa_rm_delete_resource(
ipa3_usb_ctx->ttype_ctx[ttype].rm_ctx.prod_params.name);
- ipa3_usb_ctx->ttype_ctx[ttype].rm_ctx.prod_valid = false;
- ipa_rm_delete_resource(
+ ipa3_usb_ctx->ttype_ctx[ttype].rm_ctx.prod_valid =
+ false;
+ ipa_rm_delete_resource(
ipa3_usb_ctx->ttype_ctx[ttype].rm_ctx.cons_params.name);
- ipa3_usb_ctx->ttype_ctx[ttype].rm_ctx.cons_valid = false;
- ipa3_usb_ctx->ttype_ctx[ttype].ipa_usb_notify_cb = NULL;
+ ipa3_usb_ctx->ttype_ctx[ttype].rm_ctx.cons_valid =
+ false;
+ ipa3_usb_ctx->ttype_ctx[ttype].ipa_usb_notify_cb = NULL;
+ }
}
IPA_USB_DBG_LOW("exit\n");
@@ -2400,7 +2533,11 @@
if (result)
goto start_ul;
- result = ipa3_usb_release_prod(ttype);
+ if (ipa_pm_is_used())
+ result = ipa_pm_deactivate_sync(
+ ipa3_usb_ctx->ttype_ctx[ttype].pm_ctx.hdl);
+ else
+ result = ipa3_usb_release_prod(ttype);
if (result) {
IPA_USB_ERR("failed to release PROD.\n");
goto connect_teth;
@@ -2477,7 +2614,11 @@
}
ipa3_usb_ctx->qmi_req_id++;
- result = ipa3_usb_release_prod(ttype);
+ if (ipa_pm_is_used())
+ result = ipa_pm_deactivate_sync(
+ ipa3_usb_ctx->ttype_ctx[ttype].pm_ctx.hdl);
+ else
+ result = ipa3_usb_release_prod(ttype);
if (result) {
IPA_USB_ERR("failed to release PROD\n");
goto release_prod_fail;
@@ -2543,7 +2684,11 @@
"DPL channel":"Data Tethering channels");
/* Request USB_PROD */
- result = ipa3_usb_request_prod(ttype);
+ if (ipa_pm_is_used())
+ result = ipa_pm_activate_sync(
+ ipa3_usb_ctx->ttype_ctx[ttype].pm_ctx.hdl);
+ else
+ result = ipa3_usb_request_prod(ttype);
if (result)
goto fail_exit;
@@ -2590,7 +2735,11 @@
disconn_teth:
(void)ipa3_usb_disconnect_teth_prot(teth_prot);
release_prod:
- (void)ipa3_usb_release_prod(ttype);
+ if (ipa_pm_is_used())
+ (void)ipa_pm_deactivate_sync(
+ ipa3_usb_ctx->ttype_ctx[ttype].pm_ctx.hdl);
+ else
+ (void)ipa3_usb_release_prod(ttype);
fail_exit:
return result;
}
@@ -2642,7 +2791,11 @@
}
/* Request USB_PROD */
- result = ipa3_usb_request_prod(ttype);
+ if (ipa_pm_is_used())
+ result = ipa_pm_activate_sync(
+ ipa3_usb_ctx->ttype_ctx[ttype].pm_ctx.hdl);
+ else
+ result = ipa3_usb_request_prod(ttype);
if (result)
goto prod_req_fail;
@@ -2685,7 +2838,11 @@
IPA_USB_ERR("Error stopping UL channel: %d\n", result);
}
start_ul_fail:
- ipa3_usb_release_prod(ttype);
+ if (ipa_pm_is_used())
+ ipa_pm_deactivate_sync(
+ ipa3_usb_ctx->ttype_ctx[ttype].pm_ctx.hdl);
+ else
+ ipa3_usb_release_prod(ttype);
prod_req_fail:
/* Change state back to prev_state */
if (!ipa3_usb_set_state(prev_state, true, ttype))
@@ -2722,6 +2879,20 @@
ipa3_usb_ctx->dl_data_pending = false;
mutex_init(&ipa3_usb_ctx->general_mutex);
+ if (ipa_pm_is_used()) {
+ struct ipa3_usb_pm_context *pm_ctx;
+
+ pm_ctx =
+ &ipa3_usb_ctx->ttype_ctx[IPA_USB_TRANSPORT_TETH].pm_ctx;
+ pm_ctx->hdl = ~0;
+ pm_ctx->remote_wakeup_work =
+ &ipa3_usb_notify_remote_wakeup_work;
+ pm_ctx = &ipa3_usb_ctx->ttype_ctx[IPA_USB_TRANSPORT_DPL].pm_ctx;
+ pm_ctx->hdl = ~0;
+ pm_ctx->remote_wakeup_work =
+ &ipa3_usb_dpl_notify_remote_wakeup_work;
+ }
+
for (i = 0; i < IPA_USB_TRANSPORT_MAX; i++) {
ipa3_usb_ctx->ttype_ctx[i].rm_ctx.prod_valid = false;
ipa3_usb_ctx->ttype_ctx[i].rm_ctx.cons_valid = false;
diff --git a/drivers/platform/msm/ipa/ipa_clients/odu_bridge.c b/drivers/platform/msm/ipa/ipa_clients/odu_bridge.c
index a623d0b..f0d1102 100644
--- a/drivers/platform/msm/ipa/ipa_clients/odu_bridge.c
+++ b/drivers/platform/msm/ipa/ipa_clients/odu_bridge.c
@@ -27,6 +27,7 @@
#include <linux/cdev.h>
#include <linux/ipa_odu_bridge.h>
#include "../ipa_common_i.h"
+#include "../ipa_v3/ipa_pm.h"
#define ODU_BRIDGE_DRV_NAME "odu_ipa_bridge"
@@ -152,6 +153,7 @@
void *logbuf_low;
struct completion rm_comp;
void (*wakeup_request)(void *);
+ u32 pm_hdl;
};
static struct odu_bridge_ctx *odu_bridge_ctx;
@@ -273,20 +275,22 @@
memset(&odu_prod_params, 0, sizeof(odu_prod_params));
memset(&odu_emb_cons_params, 0, sizeof(odu_emb_cons_params));
- /* Build IPA Resource manager dependency graph */
- ODU_BRIDGE_DBG_LOW("build dependency graph\n");
- res = ipa_rm_add_dependency(IPA_RM_RESOURCE_ODU_ADAPT_PROD,
+ if (!ipa_pm_is_used()) {
+ /* Build IPA Resource manager dependency graph */
+ ODU_BRIDGE_DBG_LOW("build dependency graph\n");
+ res = ipa_rm_add_dependency(IPA_RM_RESOURCE_ODU_ADAPT_PROD,
IPA_RM_RESOURCE_Q6_CONS);
- if (res && res != -EINPROGRESS) {
- ODU_BRIDGE_ERR("ipa_rm_add_dependency() failed\n");
- goto fail_add_dependency_1;
- }
+ if (res && res != -EINPROGRESS) {
+ ODU_BRIDGE_ERR("ipa_rm_add_dependency() failed\n");
+ goto fail_add_dependency_1;
+ }
- res = ipa_rm_add_dependency(IPA_RM_RESOURCE_Q6_PROD,
+ res = ipa_rm_add_dependency(IPA_RM_RESOURCE_Q6_PROD,
IPA_RM_RESOURCE_ODU_ADAPT_CONS);
- if (res && res != -EINPROGRESS) {
- ODU_BRIDGE_ERR("ipa_rm_add_dependency() failed\n");
- goto fail_add_dependency_2;
+ if (res && res != -EINPROGRESS) {
+ ODU_BRIDGE_ERR("ipa_rm_add_dependency() failed\n");
+ goto fail_add_dependency_2;
+ }
}
/* configure RX (ODU->IPA) EP */
@@ -346,10 +350,12 @@
ipa_teardown_sys_pipe(odu_bridge_ctx->odu_prod_hdl);
odu_bridge_ctx->odu_prod_hdl = 0;
fail_odu_prod:
- ipa_rm_delete_dependency(IPA_RM_RESOURCE_Q6_PROD,
+ if (!ipa_pm_is_used())
+ ipa_rm_delete_dependency(IPA_RM_RESOURCE_Q6_PROD,
IPA_RM_RESOURCE_ODU_ADAPT_CONS);
fail_add_dependency_2:
- ipa_rm_delete_dependency(IPA_RM_RESOURCE_ODU_ADAPT_PROD,
+ if (!ipa_pm_is_used())
+ ipa_rm_delete_dependency(IPA_RM_RESOURCE_ODU_ADAPT_PROD,
IPA_RM_RESOURCE_Q6_CONS);
fail_add_dependency_1:
return res;
@@ -397,17 +403,19 @@
ODU_BRIDGE_ERR("teardown ODU EMB CONS failed\n");
odu_bridge_ctx->odu_emb_cons_hdl = 0;
- /* Delete IPA Resource manager dependency graph */
- ODU_BRIDGE_DBG("deleting dependency graph\n");
- res = ipa_rm_delete_dependency(IPA_RM_RESOURCE_ODU_ADAPT_PROD,
- IPA_RM_RESOURCE_Q6_CONS);
- if (res && res != -EINPROGRESS)
- ODU_BRIDGE_ERR("ipa_rm_delete_dependency() failed\n");
+ if (!ipa_pm_is_used()) {
+ /* Delete IPA Resource manager dependency graph */
+ ODU_BRIDGE_DBG("deleting dependency graph\n");
+ res = ipa_rm_delete_dependency(IPA_RM_RESOURCE_ODU_ADAPT_PROD,
+ IPA_RM_RESOURCE_Q6_CONS);
+ if (res && res != -EINPROGRESS)
+ ODU_BRIDGE_ERR("ipa_rm_delete_dependency() failed\n");
- res = ipa_rm_delete_dependency(IPA_RM_RESOURCE_Q6_PROD,
- IPA_RM_RESOURCE_ODU_ADAPT_CONS);
- if (res && res != -EINPROGRESS)
- ODU_BRIDGE_ERR("ipa_rm_delete_dependency() failed\n");
+ res = ipa_rm_delete_dependency(IPA_RM_RESOURCE_Q6_PROD,
+ IPA_RM_RESOURCE_ODU_ADAPT_CONS);
+ if (res && res != -EINPROGRESS)
+ ODU_BRIDGE_ERR("ipa_rm_delete_dependency() failed\n");
+ }
return 0;
}
@@ -1319,24 +1327,58 @@
return 0;
}
-/* IPA Bridge API is the new API which will replaces old odu_bridge API */
-int ipa_bridge_init(struct ipa_bridge_init_params *params, u32 *hdl)
+static void ipa_br_pm_cb(void *p, enum ipa_pm_cb_event event)
+{
+ ODU_BRIDGE_FUNC_ENTRY();
+ if (event != IPA_PM_REQUEST_WAKEUP) {
+ ODU_BRIDGE_ERR("Unexpected event %d\n", event);
+ WARN_ON(1);
+ return;
+ }
+
+ if (odu_bridge_ctx->is_suspended)
+ odu_bridge_ctx->wakeup_request(odu_bridge_ctx->priv);
+ ODU_BRIDGE_FUNC_EXIT();
+}
+
+static int ipa_br_register_pm(void)
+{
+ struct ipa_pm_register_params reg_params;
+ int ret;
+
+ memset(®_params, 0, sizeof(reg_params));
+ reg_params.name = "ODU Bridge";
+ reg_params.callback = ipa_br_pm_cb;
+ reg_params.group = IPA_PM_GROUP_DEFAULT;
+
+ ret = ipa_pm_register(®_params,
+ &odu_bridge_ctx->pm_hdl);
+ if (ret) {
+ ODU_BRIDGE_ERR("fail to register with PM %d\n", ret);
+ goto fail_pm_reg;
+ }
+
+ ret = ipa_pm_associate_ipa_cons_to_client(odu_bridge_ctx->pm_hdl,
+ IPA_CLIENT_ODU_EMB_CONS);
+ if (ret) {
+ ODU_BRIDGE_ERR("fail to associate cons with PM %d\n", ret);
+ goto fail_pm_cons;
+ }
+
+ return 0;
+
+fail_pm_cons:
+ ipa_pm_deregister(odu_bridge_ctx->pm_hdl);
+ odu_bridge_ctx->pm_hdl = ~0;
+fail_pm_reg:
+ return ret;
+}
+
+static int ipa_br_create_rm_resources(void)
{
int ret;
struct ipa_rm_create_params create_params;
- if (!params || !params->wakeup_request || !hdl) {
- ODU_BRIDGE_ERR("NULL arg\n");
- return -EINVAL;
- }
-
-
- ret = odu_bridge_init(¶ms->info);
- if (ret)
- return ret;
-
- odu_bridge_ctx->wakeup_request = params->wakeup_request;
-
/* create IPA RM resources for power management */
init_completion(&odu_bridge_ctx->rm_comp);
memset(&create_params, 0, sizeof(create_params));
@@ -1368,9 +1410,6 @@
goto fail_rm_cons;
}
- /* handle is ignored for now */
- *hdl = 0;
-
return 0;
fail_rm_cons:
@@ -1379,6 +1418,41 @@
fail_add_dep:
ipa_rm_delete_resource(IPA_RM_RESOURCE_ODU_ADAPT_PROD);
fail_rm_prod:
+ return ret;
+}
+
+/* IPA Bridge API is the new API which will replaces old odu_bridge API */
+int ipa_bridge_init(struct ipa_bridge_init_params *params, u32 *hdl)
+{
+ int ret;
+
+ if (!params || !params->wakeup_request || !hdl) {
+ ODU_BRIDGE_ERR("NULL arg\n");
+ return -EINVAL;
+ }
+
+
+ ret = odu_bridge_init(¶ms->info);
+ if (ret)
+ return ret;
+
+ odu_bridge_ctx->wakeup_request = params->wakeup_request;
+
+ if (ipa_pm_is_used())
+ ret = ipa_br_register_pm();
+ else
+ ret = ipa_br_create_rm_resources();
+ if (ret) {
+ ODU_BRIDGE_ERR("fail to register woth RM/PM %d\n", ret);
+ goto fail_pm;
+ }
+
+ /* handle is ignored for now */
+ *hdl = 0;
+
+ return 0;
+
+fail_pm:
odu_bridge_cleanup();
return ret;
}
@@ -1398,7 +1472,10 @@
return -EFAULT;
}
- ret = ipa_br_request_prod();
+ if (ipa_pm_is_used())
+ ret = ipa_pm_activate_sync(odu_bridge_ctx->pm_hdl);
+ else
+ ret = ipa_br_request_prod();
if (ret)
return ret;
@@ -1411,6 +1488,10 @@
struct ipa_rm_perf_profile profile = {0};
int ret;
+ if (ipa_pm_is_used())
+ return ipa_pm_set_perf_profile(odu_bridge_ctx->pm_hdl,
+ bandwidth);
+
profile.max_supported_bandwidth_mbps = bandwidth;
ret = ipa_rm_set_perf_profile(IPA_RM_RESOURCE_ODU_ADAPT_PROD, &profile);
if (ret) {
@@ -1436,7 +1517,10 @@
if (ret)
return ret;
- ret = ipa_br_release_prod();
+ if (ipa_pm_is_used())
+ ret = ipa_pm_deactivate_sync(odu_bridge_ctx->pm_hdl);
+ else
+ ret = ipa_br_release_prod();
if (ret)
return ret;
@@ -1470,7 +1554,10 @@
return ret;
}
- ret = ipa_br_release_prod();
+ if (ipa_pm_is_used())
+ ret = ipa_pm_deactivate_sync(odu_bridge_ctx->pm_hdl);
+ else
+ ret = ipa_br_release_prod();
if (ret) {
ODU_BRIDGE_ERR("failed to release prod %d\n", ret);
ipa_start_gsi_channel(odu_bridge_ctx->odu_emb_cons_hdl);
@@ -1501,7 +1588,10 @@
return -EFAULT;
}
- ret = ipa_br_request_prod();
+ if (ipa_pm_is_used())
+ ret = ipa_pm_activate_sync(odu_bridge_ctx->pm_hdl);
+ else
+ ret = ipa_br_request_prod();
if (ret)
return ret;
@@ -1523,12 +1613,27 @@
}
EXPORT_SYMBOL(ipa_bridge_tx_dp);
-int ipa_bridge_cleanup(u32 hdl)
+static void ipa_br_delete_rm_resources(void)
{
ipa_rm_delete_dependency(IPA_RM_RESOURCE_ODU_ADAPT_PROD,
IPA_RM_RESOURCE_APPS_CONS);
ipa_rm_delete_resource(IPA_RM_RESOURCE_ODU_ADAPT_PROD);
ipa_rm_delete_resource(IPA_RM_RESOURCE_ODU_ADAPT_CONS);
+}
+
+static void ipa_br_deregister_pm(void)
+{
+ ipa_pm_deactivate_sync(odu_bridge_ctx->pm_hdl);
+ ipa_pm_deregister(odu_bridge_ctx->pm_hdl);
+ odu_bridge_ctx->pm_hdl = ~0;
+}
+
+int ipa_bridge_cleanup(u32 hdl)
+{
+ if (ipa_pm_is_used())
+ ipa_br_deregister_pm();
+ else
+ ipa_br_delete_rm_resources();
return odu_bridge_cleanup();
}
EXPORT_SYMBOL(ipa_bridge_cleanup);
diff --git a/drivers/platform/msm/ipa/ipa_clients/rndis_ipa.c b/drivers/platform/msm/ipa/ipa_clients/rndis_ipa.c
index f62cb27..1c47e69 100644
--- a/drivers/platform/msm/ipa/ipa_clients/rndis_ipa.c
+++ b/drivers/platform/msm/ipa/ipa_clients/rndis_ipa.c
@@ -9,7 +9,6 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
-
#include <linux/atomic.h>
#include <linux/errno.h>
#include <linux/etherdevice.h>
@@ -27,6 +26,8 @@
#include <linux/random.h>
#include <linux/rndis_ipa.h>
#include <linux/workqueue.h>
+#include "../ipa_common_i.h"
+#include "../ipa_v3/ipa_pm.h"
#define CREATE_TRACE_POINTS
#include "rndis_ipa_trace.h"
@@ -160,6 +161,7 @@
* state is changed to RNDIS_IPA_CONNECTED_AND_UP
* @xmit_error_delayed_work: work item for cases where IPA driver Tx fails
* @state_lock: used to protect the state variable.
+ * @pm_hdl: handle for IPA PM framework
*/
struct rndis_ipa_dev {
struct net_device *net;
@@ -188,6 +190,7 @@
void (*device_ready_notify)(void);
struct delayed_work xmit_error_delayed_work;
spinlock_t state_lock; /* Spinlock for the state variable.*/
+ u32 pm_hdl;
};
/**
@@ -233,6 +236,8 @@
unsigned long data);
static int rndis_ipa_create_rm_resource(struct rndis_ipa_dev *rndis_ipa_ctx);
static int rndis_ipa_destroy_rm_resource(struct rndis_ipa_dev *rndis_ipa_ctx);
+static int rndis_ipa_register_pm_client(struct rndis_ipa_dev *rndis_ipa_ctx);
+static int rndis_ipa_deregister_pm_client(struct rndis_ipa_dev *rndis_ipa_ctx);
static bool rx_filter(struct sk_buff *skb);
static bool tx_filter(struct sk_buff *skb);
static bool rm_enabled(struct rndis_ipa_dev *rndis_ipa_ctx);
@@ -701,7 +706,10 @@
return -EINVAL;
}
- result = rndis_ipa_create_rm_resource(rndis_ipa_ctx);
+ if (ipa_pm_is_used())
+ result = rndis_ipa_register_pm_client(rndis_ipa_ctx);
+ else
+ result = rndis_ipa_create_rm_resource(rndis_ipa_ctx);
if (result) {
RNDIS_IPA_ERROR("fail on RM create\n");
goto fail_create_rm;
@@ -763,7 +771,10 @@
return 0;
fail:
- rndis_ipa_destroy_rm_resource(rndis_ipa_ctx);
+ if (ipa_pm_is_used())
+ rndis_ipa_deregister_pm_client(rndis_ipa_ctx);
+ else
+ rndis_ipa_destroy_rm_resource(rndis_ipa_ctx);
fail_create_rm:
return result;
}
@@ -1235,7 +1246,10 @@
rndis_ipa_ctx->net->stats.tx_dropped += outstanding_dropped_pkts;
atomic_set(&rndis_ipa_ctx->outstanding_pkts, 0);
- retval = rndis_ipa_destroy_rm_resource(rndis_ipa_ctx);
+ if (ipa_pm_is_used())
+ retval = rndis_ipa_deregister_pm_client(rndis_ipa_ctx);
+ else
+ retval = rndis_ipa_destroy_rm_resource(rndis_ipa_ctx);
if (retval) {
RNDIS_IPA_ERROR("Fail to clean RM\n");
return retval;
@@ -1772,6 +1786,29 @@
return result;
}
+static void rndis_ipa_pm_cb(void *p, enum ipa_pm_cb_event event)
+{
+ struct rndis_ipa_dev *rndis_ipa_ctx = p;
+
+ RNDIS_IPA_LOG_ENTRY();
+
+ if (event != IPA_PM_CLIENT_ACTIVATED) {
+ RNDIS_IPA_ERROR("unexpected event %d\n", event);
+ WARN_ON(1);
+ return;
+ }
+ RNDIS_IPA_DEBUG("Resource Granted\n");
+
+ if (netif_queue_stopped(rndis_ipa_ctx->net)) {
+ RNDIS_IPA_DEBUG("starting queue\n");
+ netif_start_queue(rndis_ipa_ctx->net);
+ } else {
+ RNDIS_IPA_DEBUG("queue already awake\n");
+ }
+
+ RNDIS_IPA_LOG_EXIT();
+}
+
/**
* rndis_ipa_destroy_rm_resource() - delete the dependency and destroy
* the resource done on rndis_ipa_create_rm_resource()
@@ -1831,6 +1868,33 @@
return result;
}
+static int rndis_ipa_register_pm_client(struct rndis_ipa_dev *rndis_ipa_ctx)
+{
+ int result;
+ struct ipa_pm_register_params pm_reg;
+
+ memset(&pm_reg, 0, sizeof(pm_reg));
+
+ pm_reg.name = rndis_ipa_ctx->net->name;
+ pm_reg.user_data = rndis_ipa_ctx;
+ pm_reg.callback = rndis_ipa_pm_cb;
+ pm_reg.group = IPA_PM_GROUP_APPS;
+ result = ipa_pm_register(&pm_reg, &rndis_ipa_ctx->pm_hdl);
+ if (result) {
+ RNDIS_IPA_ERROR("failed to create IPA PM client %d\n", result);
+ return result;
+ }
+ return 0;
+}
+
+static int rndis_ipa_deregister_pm_client(struct rndis_ipa_dev *rndis_ipa_ctx)
+{
+ ipa_pm_deactivate_sync(rndis_ipa_ctx->pm_hdl);
+ ipa_pm_deregister(rndis_ipa_ctx->pm_hdl);
+ rndis_ipa_ctx->pm_hdl = ~0;
+ return 0;
+}
+
/**
* resource_request() - request for the Netdev resource
* @rndis_ipa_ctx: main driver context
@@ -1849,11 +1913,14 @@
int result = 0;
if (!rm_enabled(rndis_ipa_ctx))
- goto out;
- result = ipa_rm_inactivity_timer_request_resource(
+ return result;
+
+ if (ipa_pm_is_used())
+ return ipa_pm_activate(rndis_ipa_ctx->pm_hdl);
+
+ return ipa_rm_inactivity_timer_request_resource(
DRV_RESOURCE_ID);
-out:
- return result;
+
}
/**
@@ -1868,9 +1935,12 @@
static void resource_release(struct rndis_ipa_dev *rndis_ipa_ctx)
{
if (!rm_enabled(rndis_ipa_ctx))
- goto out;
- ipa_rm_inactivity_timer_release_resource(DRV_RESOURCE_ID);
-out:
+ return;
+ if (ipa_pm_is_used())
+ ipa_pm_deferred_deactivate(rndis_ipa_ctx->pm_hdl);
+ else
+ ipa_rm_inactivity_timer_release_resource(DRV_RESOURCE_ID);
+
return;
}
diff --git a/drivers/platform/msm/ipa/ipa_common_i.h b/drivers/platform/msm/ipa/ipa_common_i.h
index 32c8b25..a487bf4 100644
--- a/drivers/platform/msm/ipa/ipa_common_i.h
+++ b/drivers/platform/msm/ipa/ipa_common_i.h
@@ -386,4 +386,6 @@
const char *ipa_get_version_string(enum ipa_hw_type ver);
int ipa_start_gsi_channel(u32 clnt_hdl);
+bool ipa_pm_is_used(void);
+
#endif /* _IPA_COMMON_I_H_ */
diff --git a/drivers/platform/msm/ipa/ipa_v3/Makefile b/drivers/platform/msm/ipa/ipa_v3/Makefile
index e3f8d45..5db2545 100644
--- a/drivers/platform/msm/ipa/ipa_v3/Makefile
+++ b/drivers/platform/msm/ipa/ipa_v3/Makefile
@@ -4,6 +4,6 @@
ipat-y := ipa.o ipa_debugfs.o ipa_hdr.o ipa_flt.o ipa_rt.o ipa_dp.o ipa_client.o \
ipa_utils.o ipa_nat.o ipa_intf.o teth_bridge.o ipa_interrupts.o \
ipa_uc.o ipa_uc_wdi.o ipa_dma.o ipa_uc_mhi.o ipa_mhi.o ipa_uc_ntn.o \
- ipa_hw_stats.o
+ ipa_hw_stats.o ipa_pm.o
obj-$(CONFIG_RMNET_IPA3) += rmnet_ipa.o ipa_qmi_service_v01.o ipa_qmi_service.o rmnet_ipa_fd_ioctl.o
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa.c b/drivers/platform/msm/ipa/ipa_v3/ipa.c
index 2210ee7..a52b4e0 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa.c
@@ -1466,6 +1466,10 @@
}
break;
case IPA_IOC_RM_ADD_DEPENDENCY:
+ /* deprecate if IPA PM is used */
+ if (ipa3_ctx->use_ipa_pm)
+ return 0;
+
if (copy_from_user((u8 *)&rm_depend, (u8 *)arg,
sizeof(struct ipa_ioc_rm_dependency))) {
retval = -EFAULT;
@@ -1475,6 +1479,10 @@
rm_depend.resource_name, rm_depend.depends_on_name);
break;
case IPA_IOC_RM_DEL_DEPENDENCY:
+ /* deprecate if IPA PM is used */
+ if (ipa3_ctx->use_ipa_pm)
+ return 0;
+
if (copy_from_user((u8 *)&rm_depend, (u8 *)arg,
sizeof(struct ipa_ioc_rm_dependency))) {
retval = -EFAULT;
@@ -2350,7 +2358,6 @@
struct ipahal_imm_cmd_register_write reg_write;
struct ipahal_imm_cmd_pyld *cmd_pyld;
int retval;
- struct ipahal_reg_valmask valmask;
desc = kcalloc(ipa3_ctx->ipa_num_pipes, sizeof(struct ipa3_desc),
GFP_KERNEL);
@@ -2365,39 +2372,10 @@
if (ep_idx == -1)
continue;
- if (ipa3_ctx->ep[ep_idx].valid &&
- ipa3_ctx->ep[ep_idx].skip_ep_cfg) {
- BUG_ON(num_descs >= ipa3_ctx->ipa_num_pipes);
-
- reg_write.skip_pipeline_clear = false;
- reg_write.pipeline_clear_options =
- IPAHAL_HPS_CLEAR;
- reg_write.offset =
- ipahal_get_reg_n_ofst(IPA_ENDP_STATUS_n,
- ep_idx);
- ipahal_get_status_ep_valmask(
- ipa3_get_ep_mapping(IPA_CLIENT_APPS_LAN_CONS),
- &valmask);
- reg_write.value = valmask.val;
- reg_write.value_mask = valmask.mask;
- cmd_pyld = ipahal_construct_imm_cmd(
- IPA_IMM_CMD_REGISTER_WRITE, ®_write, false);
- if (!cmd_pyld) {
- IPAERR("fail construct register_write cmd\n");
- BUG();
- }
-
- desc[num_descs].opcode = cmd_pyld->opcode;
- desc[num_descs].type = IPA_IMM_CMD_DESC;
- desc[num_descs].callback = ipa3_destroy_imm;
- desc[num_descs].user1 = cmd_pyld;
- desc[num_descs].pyld = cmd_pyld->data;
- desc[num_descs].len = cmd_pyld->len;
- num_descs++;
- }
-
- /* disable statuses for modem producers */
- if (IPA_CLIENT_IS_Q6_PROD(client_idx)) {
+ /* disable statuses for all modem controlled prod pipes */
+ if (IPA_CLIENT_IS_Q6_PROD(client_idx) ||
+ (ipa3_ctx->ep[ep_idx].valid &&
+ ipa3_ctx->ep[ep_idx].skip_ep_cfg)) {
ipa_assert_on(num_descs >= ipa3_ctx->ipa_num_pipes);
reg_write.skip_pipeline_clear = false;
@@ -3712,6 +3690,53 @@
spin_unlock_irqrestore(&ipa3_ctx->wakelock_ref_cnt.spinlock, flags);
}
+int ipa3_set_clock_plan_from_pm(int idx)
+{
+ u32 clk_rate;
+
+ IPADBG_LOW("idx = %d\n", idx);
+
+ if (idx <= 0 || idx >= ipa3_ctx->ctrl->msm_bus_data_ptr->num_usecases) {
+ IPAERR("bad voltage\n");
+ return -EINVAL;
+ }
+
+ if (idx == 1)
+ clk_rate = ipa3_ctx->ctrl->ipa_clk_rate_svs;
+ else if (idx == 2)
+ clk_rate = ipa3_ctx->ctrl->ipa_clk_rate_nominal;
+ else if (idx == 3)
+ clk_rate = ipa3_ctx->ctrl->ipa_clk_rate_turbo;
+ else {
+ IPAERR("bad voltage\n");
+ WARN_ON(1);
+ return -EFAULT;
+ }
+
+ if (clk_rate == ipa3_ctx->curr_ipa_clk_rate) {
+ IPADBG_LOW("Same voltage\n");
+ return 0;
+ }
+
+ mutex_lock(&ipa3_ctx->ipa3_active_clients.mutex);
+ ipa3_ctx->curr_ipa_clk_rate = clk_rate;
+ ipa3_ctx->ipa3_active_clients.bus_vote_idx = idx;
+ IPADBG_LOW("setting clock rate to %u\n", ipa3_ctx->curr_ipa_clk_rate);
+ if (atomic_read(&ipa3_ctx->ipa3_active_clients.cnt) > 0) {
+ if (ipa3_clk)
+ clk_set_rate(ipa3_clk, ipa3_ctx->curr_ipa_clk_rate);
+ if (msm_bus_scale_client_update_request(ipa3_ctx->ipa_bus_hdl,
+ ipa3_get_bus_vote()))
+ WARN_ON(1);
+ } else {
+ IPADBG_LOW("clocks are gated, not setting rate\n");
+ }
+ mutex_unlock(&ipa3_ctx->ipa3_active_clients.mutex);
+ IPADBG_LOW("Done\n");
+
+ return 0;
+}
+
int ipa3_set_required_perf_profile(enum ipa_voltage_level floor_voltage,
u32 bandwidth_mbps)
{
@@ -3814,14 +3839,19 @@
u32 i = 0;
int res;
struct ipa_ep_cfg_holb holb_cfg;
+ u32 pipe_bitmask = 0;
IPADBG("interrupt=%d, interrupt_data=%u\n",
interrupt, suspend_data);
memset(&holb_cfg, 0, sizeof(holb_cfg));
holb_cfg.tmr_val = 0;
- for (i = 0; i < ipa3_ctx->ipa_num_pipes; i++) {
+ for (i = 0; i < ipa3_ctx->ipa_num_pipes; i++, bmsk = bmsk << 1) {
if ((suspend_data & bmsk) && (ipa3_ctx->ep[i].valid)) {
+ if (ipa3_ctx->use_ipa_pm) {
+ pipe_bitmask |= bmsk;
+ continue;
+ }
if (IPA_CLIENT_IS_APPS_CONS(ipa3_ctx->ep[i].client)) {
/*
* pipe will be unsuspended as part of
@@ -3860,7 +3890,13 @@
}
}
}
- bmsk = bmsk << 1;
+ }
+ if (ipa3_ctx->use_ipa_pm) {
+ res = ipa_pm_handle_suspend(pipe_bitmask);
+ if (res) {
+ IPAERR("ipa_pm_handle_suspend failed %d\n", res);
+ return;
+ }
}
}
@@ -4621,6 +4657,7 @@
ipa3_ctx->ee = resource_p->ee;
ipa3_ctx->apply_rg10_wa = resource_p->apply_rg10_wa;
ipa3_ctx->gsi_ch20_wa = resource_p->gsi_ch20_wa;
+ ipa3_ctx->use_ipa_pm = resource_p->use_ipa_pm;
ipa3_ctx->ipa3_active_clients_logging.log_rdy = false;
if (resource_p->ipa_tz_unlock_reg) {
ipa3_ctx->ipa_tz_unlock_reg_num =
@@ -4934,20 +4971,30 @@
wakeup_source_init(&ipa3_ctx->w_lock, "IPA_WS");
spin_lock_init(&ipa3_ctx->wakelock_ref_cnt.spinlock);
- /* Initialize IPA RM (resource manager) */
- result = ipa_rm_initialize();
- if (result) {
- IPAERR("RM initialization failed (%d)\n", -result);
- result = -ENODEV;
- goto fail_ipa_rm_init;
- }
- IPADBG("IPA resource manager initialized");
+ /* Initialize Power Management framework */
+ if (ipa3_ctx->use_ipa_pm) {
+ result = ipa_pm_init(&ipa3_res.pm_init);
+ if (result) {
+ IPAERR("IPA PM initialization failed (%d)\n", -result);
+ result = -ENODEV;
+ goto fail_ipa_rm_init;
+ }
+ IPADBG("IPA resource manager initialized");
+ } else {
+ result = ipa_rm_initialize();
+ if (result) {
+ IPAERR("RM initialization failed (%d)\n", -result);
+ result = -ENODEV;
+ goto fail_ipa_rm_init;
+ }
+ IPADBG("IPA resource manager initialized");
- result = ipa3_create_apps_resource();
- if (result) {
- IPAERR("Failed to create APPS_CONS resource\n");
- result = -ENODEV;
- goto fail_create_apps_resource;
+ result = ipa3_create_apps_resource();
+ if (result) {
+ IPAERR("Failed to create APPS_CONS resource\n");
+ result = -ENODEV;
+ goto fail_create_apps_resource;
+ }
}
result = ipa3_alloc_pkt_init();
@@ -4998,9 +5045,11 @@
fail_cdev_add:
fail_ipa_init_interrupts:
- ipa_rm_delete_resource(IPA_RM_RESOURCE_APPS_CONS);
+ if (!ipa3_ctx->use_ipa_pm)
+ ipa_rm_delete_resource(IPA_RM_RESOURCE_APPS_CONS);
fail_create_apps_resource:
- ipa_rm_exit();
+ if (!ipa3_ctx->use_ipa_pm)
+ ipa_rm_exit();
fail_ipa_rm_init:
fail_nat_dev_add:
device_destroy(ipa3_ctx->class, ipa3_ctx->dev_num);
@@ -5069,6 +5118,101 @@
return result;
}
+bool ipa_pm_is_used(void)
+{
+ return (ipa3_ctx) ? ipa3_ctx->use_ipa_pm : false;
+}
+
+static int get_ipa_dts_pm_info(struct platform_device *pdev,
+ struct ipa3_plat_drv_res *ipa_drv_res)
+{
+ int result;
+ int i, j;
+
+ ipa_drv_res->use_ipa_pm = of_property_read_bool(pdev->dev.of_node,
+ "qcom,use-ipa-pm");
+ IPADBG("use_ipa_pm=%d\n", ipa_drv_res->use_ipa_pm);
+ if (!ipa_drv_res->use_ipa_pm)
+ return 0;
+
+ result = of_property_read_u32(pdev->dev.of_node,
+ "qcom,msm-bus,num-cases",
+ &ipa_drv_res->pm_init.threshold_size);
+ /* No vote is ignored */
+ ipa_drv_res->pm_init.threshold_size -= 2;
+ if (result || ipa_drv_res->pm_init.threshold_size >
+ IPA_PM_THRESHOLD_MAX) {
+ IPAERR("invalid property qcom,msm-bus,num-cases %d\n",
+ ipa_drv_res->pm_init.threshold_size);
+ return -EFAULT;
+ }
+
+ result = of_property_read_u32_array(pdev->dev.of_node,
+ "qcom,throughput-threshold",
+ ipa_drv_res->pm_init.default_threshold,
+ ipa_drv_res->pm_init.threshold_size);
+ if (result) {
+ IPAERR("failed to read qcom,throughput-thresholds\n");
+ return -EFAULT;
+ }
+
+ result = of_property_count_strings(pdev->dev.of_node,
+ "qcom,scaling-exceptions");
+ if (result < 0) {
+ IPADBG("no exception list for ipa pm\n");
+ result = 0;
+ }
+
+ if (result % (ipa_drv_res->pm_init.threshold_size + 1)) {
+ IPAERR("failed to read qcom,scaling-exceptions\n");
+ return -EFAULT;
+ }
+
+ ipa_drv_res->pm_init.exception_size = result /
+ (ipa_drv_res->pm_init.threshold_size + 1);
+ if (ipa_drv_res->pm_init.exception_size >=
+ IPA_PM_EXCEPTION_MAX) {
+ IPAERR("exception list larger then max %d\n",
+ ipa_drv_res->pm_init.exception_size);
+ return -EFAULT;
+ }
+
+ for (i = 0; i < ipa_drv_res->pm_init.exception_size; i++) {
+ struct ipa_pm_exception *ex = ipa_drv_res->pm_init.exceptions;
+
+ result = of_property_read_string_index(pdev->dev.of_node,
+ "qcom,scaling-exceptions",
+ i * ipa_drv_res->pm_init.threshold_size,
+ &ex[i].usecase);
+ if (result) {
+ IPAERR("failed to read qcom,scaling-exceptions");
+ return -EFAULT;
+ }
+
+ for (j = 0; j < ipa_drv_res->pm_init.threshold_size; j++) {
+ const char *str;
+
+ result = of_property_read_string_index(
+ pdev->dev.of_node,
+ "qcom,scaling-exceptions",
+ i * ipa_drv_res->pm_init.threshold_size + j + 1,
+ &str);
+ if (result) {
+ IPAERR("failed to read qcom,scaling-exceptions"
+ );
+ return -EFAULT;
+ }
+
+ if (kstrtou32(str, 0, &ex[i].threshold[j])) {
+ IPAERR("error str=%s\n", str);
+ return -EFAULT;
+ }
+ }
+ }
+
+ return 0;
+}
+
static int get_ipa_dts_configuration(struct platform_device *pdev,
struct ipa3_plat_drv_res *ipa_drv_res)
{
@@ -5307,6 +5451,14 @@
}
kfree(ipa_tz_unlock_reg);
}
+
+ /* get IPA PM related information */
+ result = get_ipa_dts_pm_info(pdev, ipa_drv_res);
+ if (result) {
+ IPAERR("failed to get pm info from dts %d\n", result);
+ return result;
+ }
+
return 0;
}
@@ -5844,11 +5996,16 @@
}
}
- /*
- * Release transport IPA resource without waiting for inactivity timer
- */
- atomic_set(&ipa3_ctx->transport_pm.eot_activity, 0);
- ipa3_transport_release_resource(NULL);
+ if (ipa3_ctx->use_ipa_pm) {
+ ipa_pm_deactivate_all_deferred();
+ } else {
+ /*
+ * Release transport IPA resource without waiting
+ * for inactivity timer
+ */
+ atomic_set(&ipa3_ctx->transport_pm.eot_activity, 0);
+ ipa3_transport_release_resource(NULL);
+ }
IPADBG("Exit\n");
return 0;
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c b/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c
index 153548b..dabd6a3 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c
@@ -1705,6 +1705,10 @@
{
int result, nbytes, cnt = 0;
+ /* deprecate if IPA PM is used */
+ if (ipa3_ctx->use_ipa_pm)
+ return 0;
+
result = ipa_rm_stat(dbg_buff, IPA_MAX_MSG_LEN);
if (result < 0) {
nbytes = scnprintf(dbg_buff, IPA_MAX_MSG_LEN,
@@ -1716,6 +1720,45 @@
return simple_read_from_buffer(ubuf, count, ppos, dbg_buff, cnt);
}
+static ssize_t ipa3_pm_read_stats(struct file *file, char __user *ubuf,
+ size_t count, loff_t *ppos)
+{
+ int result, nbytes, cnt = 0;
+
+ if (!ipa3_ctx->use_ipa_pm)
+ return 0;
+
+ result = ipa_pm_stat(dbg_buff, IPA_MAX_MSG_LEN);
+ if (result < 0) {
+ nbytes = scnprintf(dbg_buff, IPA_MAX_MSG_LEN,
+ "Error in printing PM stat %d\n", result);
+ cnt += nbytes;
+ } else
+ cnt += result;
+
+ return simple_read_from_buffer(ubuf, count, ppos, dbg_buff, cnt);
+}
+
+static ssize_t ipa3_pm_ex_read_stats(struct file *file, char __user *ubuf,
+ size_t count, loff_t *ppos)
+{
+ int result, nbytes, cnt = 0;
+
+ if (!ipa3_ctx->use_ipa_pm)
+ return 0;
+
+ result = ipa_pm_exceptions_stat(dbg_buff, IPA_MAX_MSG_LEN);
+ if (result < 0) {
+ nbytes = scnprintf(dbg_buff, IPA_MAX_MSG_LEN,
+ "Error in printing PM stat %d\n", result);
+ cnt += nbytes;
+ } else
+ cnt += result;
+
+ return simple_read_from_buffer(ubuf, count, ppos, dbg_buff, cnt);
+}
+
+
static void ipa_dump_status(struct ipahal_pkt_status *status)
{
IPA_DUMP_STATUS_FIELD(status_opcode);
@@ -1940,6 +1983,15 @@
.read = ipa3_rm_read_stats,
};
+static const struct file_operations ipa3_pm_stats = {
+ .read = ipa3_pm_read_stats,
+};
+
+
+static const struct file_operations ipa3_pm_ex_stats = {
+ .read = ipa3_pm_ex_read_stats,
+};
+
const struct file_operations ipa3_active_clients = {
.read = ipa3_print_active_clients_log,
.write = ipa3_clear_active_clients_log,
@@ -2131,11 +2183,27 @@
goto fail;
}
- dfile_rm_stats = debugfs_create_file("rm_stats",
- read_only_mode, dent, 0, &ipa3_rm_stats);
- if (!dfile_rm_stats || IS_ERR(dfile_rm_stats)) {
- IPAERR("fail to create file for debug_fs rm_stats\n");
- goto fail;
+ if (ipa3_ctx->use_ipa_pm) {
+ file = dfile_rm_stats = debugfs_create_file("pm_stats",
+ read_only_mode, dent, NULL, &ipa3_pm_stats);
+ if (!file || IS_ERR(file)) {
+ IPAERR("fail to create file for debug_fs pm_stats\n");
+ goto fail;
+ }
+
+ file = dfile_rm_stats = debugfs_create_file("pm_ex_stats",
+ read_only_mode, dent, NULL, &ipa3_pm_ex_stats);
+ if (!file || IS_ERR(file)) {
+ IPAERR("fail to create file for debugfs pm_ex_stats\n");
+ goto fail;
+ }
+ } else {
+ dfile_rm_stats = debugfs_create_file("rm_stats",
+ read_only_mode, dent, NULL, &ipa3_rm_stats);
+ if (!dfile_rm_stats || IS_ERR(dfile_rm_stats)) {
+ IPAERR("fail to create file for debug_fs rm_stats\n");
+ goto fail;
+ }
}
dfile_status_stats = debugfs_create_file("status_stats",
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c b/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c
index 26d5f5e..7f30a10 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c
@@ -73,6 +73,8 @@
#define IPA_TX_SEND_COMPL_NOP_DELAY_NS (2 * 1000 * 1000)
+#define IPA_APPS_BW_FOR_PM 700
+
static struct sk_buff *ipa3_get_skb_ipa_rx(unsigned int len, gfp_t flags);
static void ipa3_replenish_wlan_rx_cache(struct ipa3_sys_context *sys);
static void ipa3_replenish_rx_cache(struct ipa3_sys_context *sys);
@@ -748,7 +750,10 @@
int inactive_cycles = 0;
int cnt;
- IPA_ACTIVE_CLIENTS_INC_SIMPLE();
+ if (ipa3_ctx->use_ipa_pm)
+ ipa_pm_activate_sync(sys->pm_hdl);
+ else
+ IPA_ACTIVE_CLIENTS_INC_SIMPLE();
do {
cnt = ipa3_handle_rx_core(sys, true, true);
if (cnt == 0)
@@ -772,7 +777,10 @@
trace_poll_to_intr3(sys->ep->client);
ipa3_rx_switch_to_intr_mode(sys);
- IPA_ACTIVE_CLIENTS_DEC_SIMPLE();
+ if (ipa3_ctx->use_ipa_pm)
+ ipa_pm_deferred_deactivate(sys->pm_hdl);
+ else
+ IPA_ACTIVE_CLIENTS_DEC_SIMPLE();
}
static void ipa3_switch_to_intr_rx_work_func(struct work_struct *work)
@@ -799,6 +807,32 @@
return HRTIMER_NORESTART;
}
+static void ipa_pm_sys_pipe_cb(void *p, enum ipa_pm_cb_event event)
+{
+ struct ipa3_sys_context *sys = (struct ipa3_sys_context *)p;
+
+ switch (event) {
+ case IPA_PM_CLIENT_ACTIVATED:
+ /*
+ * this event is ignored as the sync version of activation
+ * will be used.
+ */
+ break;
+ case IPA_PM_REQUEST_WAKEUP:
+ /*
+ * pipe will be unsuspended as part of
+ * enabling IPA clocks
+ */
+ ipa_pm_activate_sync(sys->pm_hdl);
+ ipa_pm_deferred_deactivate(sys->pm_hdl);
+ break;
+ default:
+ IPAERR("Unexpected event %d\n", event);
+ WARN_ON(1);
+ return;
+ }
+}
+
/**
* ipa3_setup_sys_pipe() - Setup an IPA GPI pipe and perform
* IPA EP configuration
@@ -846,6 +880,9 @@
memset(ep, 0, offsetof(struct ipa3_ep_context, sys));
if (!ep->sys) {
+ struct ipa_pm_register_params pm_reg;
+
+ memset(&pm_reg, 0, sizeof(pm_reg));
ep->sys = kzalloc(sizeof(struct ipa3_sys_context), GFP_KERNEL);
if (!ep->sys) {
IPAERR("failed to sys ctx for client %d\n",
@@ -884,6 +921,35 @@
hrtimer_init(&ep->sys->db_timer, CLOCK_MONOTONIC,
HRTIMER_MODE_REL);
ep->sys->db_timer.function = ipa3_ring_doorbell_timer_fn;
+
+ /* create IPA PM resources for handling polling mode */
+ if (ipa3_ctx->use_ipa_pm &&
+ IPA_CLIENT_IS_CONS(sys_in->client)) {
+ pm_reg.name = ipa_clients_strings[sys_in->client];
+ pm_reg.callback = ipa_pm_sys_pipe_cb;
+ pm_reg.user_data = ep->sys;
+ pm_reg.group = IPA_PM_GROUP_APPS;
+ result = ipa_pm_register(&pm_reg, &ep->sys->pm_hdl);
+ if (result) {
+ IPAERR("failed to create IPA PM client %d\n",
+ result);
+ goto fail_pm;
+ }
+
+ result = ipa_pm_associate_ipa_cons_to_client(
+ ep->sys->pm_hdl, sys_in->client);
+ if (result) {
+ IPAERR("failed to associate IPA PM client\n");
+ goto fail_gen2;
+ }
+
+ result = ipa_pm_set_perf_profile(ep->sys->pm_hdl,
+ IPA_APPS_BW_FOR_PM);
+ if (result) {
+ IPAERR("failed to set profile IPA PM client\n");
+ goto fail_gen2;
+ }
+ }
} else {
memset(ep->sys, 0, offsetof(struct ipa3_sys_context, ep));
}
@@ -984,6 +1050,9 @@
return 0;
fail_gen2:
+ if (ipa3_ctx->use_ipa_pm)
+ ipa_pm_deregister(ep->sys->pm_hdl);
+fail_pm:
destroy_workqueue(ep->sys->repl_wq);
fail_wq2:
destroy_workqueue(ep->sys->wq);
@@ -1402,7 +1471,8 @@
sys = container_of(work, struct ipa3_sys_context, work);
if (sys->ep->napi_enabled) {
- IPA_ACTIVE_CLIENTS_INC_SPECIAL("NAPI");
+ if (!ipa3_ctx->use_ipa_pm)
+ IPA_ACTIVE_CLIENTS_INC_SPECIAL("NAPI");
sys->ep->client_notify(sys->ep->priv,
IPA_CLIENT_START_POLL, 0);
} else
@@ -3283,11 +3353,48 @@
}
}
+void __ipa_gsi_irq_rx_scedule_poll(struct ipa3_sys_context *sys)
+{
+ bool clk_off;
+
+ atomic_set(&sys->curr_polling_state, 1);
+ ipa3_inc_acquire_wakelock();
+
+ /*
+ * pm deactivate is done in wq context
+ * or after NAPI poll
+ */
+ if (ipa3_ctx->use_ipa_pm) {
+ clk_off = ipa_pm_activate(sys->pm_hdl);
+ if (!clk_off && sys->ep->napi_enabled) {
+ sys->ep->client_notify(sys->ep->priv,
+ IPA_CLIENT_START_POLL, 0);
+ return;
+ }
+ queue_work(sys->wq, &sys->work);
+ return;
+ }
+
+ if (sys->ep->napi_enabled) {
+ struct ipa_active_client_logging_info log;
+
+ IPA_ACTIVE_CLIENTS_PREP_SPECIAL(log, "NAPI");
+ clk_off = ipa3_inc_client_enable_clks_no_block(
+ &log);
+ if (!clk_off) {
+ sys->ep->client_notify(sys->ep->priv,
+ IPA_CLIENT_START_POLL, 0);
+ return;
+ }
+ }
+
+ queue_work(sys->wq, &sys->work);
+}
+
static void ipa_gsi_irq_rx_notify_cb(struct gsi_chan_xfer_notify *notify)
{
struct ipa3_sys_context *sys;
struct ipa3_rx_pkt_wrapper *rx_pkt_expected, *rx_pkt_rcvd;
- int clk_off;
if (!notify) {
IPAERR("gsi notify is NULL.\n");
@@ -3317,22 +3424,7 @@
/* put the gsi channel into polling mode */
gsi_config_channel_mode(sys->ep->gsi_chan_hdl,
GSI_CHAN_MODE_POLL);
- ipa3_inc_acquire_wakelock();
- atomic_set(&sys->curr_polling_state, 1);
- if (sys->ep->napi_enabled) {
- struct ipa_active_client_logging_info log;
-
- IPA_ACTIVE_CLIENTS_PREP_SPECIAL(log, "NAPI");
- clk_off = ipa3_inc_client_enable_clks_no_block(
- &log);
- if (!clk_off)
- sys->ep->client_notify(sys->ep->priv,
- IPA_CLIENT_START_POLL, 0);
- else
- queue_work(sys->wq, &sys->work);
- } else {
- queue_work(sys->wq, &sys->work);
- }
+ __ipa_gsi_irq_rx_scedule_poll(sys);
}
break;
default:
@@ -3734,7 +3826,10 @@
if (cnt < weight) {
ep->client_notify(ep->priv, IPA_CLIENT_COMP_NAPI, 0);
ipa3_rx_switch_to_intr_mode(ep->sys);
- ipa3_dec_client_disable_clks_no_block(&log);
+ if (ipa3_ctx->use_ipa_pm)
+ ipa_pm_deferred_deactivate(ep->sys->pm_hdl);
+ else
+ ipa3_dec_client_disable_clks_no_block(&log);
}
return cnt;
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h
index 4d1baea..3e1d188 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h
@@ -36,6 +36,7 @@
#include "ipahal/ipahal_hw_stats.h"
#include "../ipa_common_i.h"
#include "ipa_uc_offload_i.h"
+#include "ipa_pm.h"
#define DRV_NAME "ipa"
#define NAT_DEV_NAME "ipaNatTable"
@@ -647,6 +648,7 @@
struct workqueue_struct *wq;
struct workqueue_struct *repl_wq;
struct ipa3_status_stats *status_stat;
+ u32 pm_hdl;
/* ordering is important - other immutable fields go below */
};
@@ -869,6 +871,7 @@
struct ipa3_active_clients {
struct mutex mutex;
atomic_t cnt;
+ int bus_vote_idx;
};
struct ipa3_wakelock_ref_cnt {
@@ -1314,6 +1317,7 @@
struct ipa_cne_evt ipa_cne_evt_req_cache[IPA_MAX_NUM_REQ_CACHE];
int num_ipa_cne_evt_req;
struct mutex ipa_cne_evt_lock;
+ bool use_ipa_pm;
};
struct ipa3_plat_drv_res {
@@ -1341,6 +1345,8 @@
bool tethered_flow_control;
u32 ipa_tz_unlock_reg_num;
struct ipa_tz_unlock_reg_info *ipa_tz_unlock_reg;
+ bool use_ipa_pm;
+ struct ipa_pm_init_params pm_init;
};
/**
@@ -2226,4 +2232,6 @@
int ipa3_alloc_common_event_ring(void);
int ipa3_allocate_dma_task_for_gsi(void);
void ipa3_free_dma_task_for_gsi(void);
+int ipa3_set_clock_plan_from_pm(int idx);
+void __ipa_gsi_irq_rx_scedule_poll(struct ipa3_sys_context *sys);
#endif /* _IPA3_I_H_ */
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_pm.c b/drivers/platform/msm/ipa/ipa_v3/ipa_pm.c
new file mode 100644
index 0000000..66c712c
--- /dev/null
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_pm.c
@@ -0,0 +1,1301 @@
+/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/debugfs.h>
+#include "ipa_pm.h"
+#include "ipa_i.h"
+
+static const char *client_state_to_str[IPA_PM_STATE_MAX] = {
+ __stringify(IPA_PM_DEACTIVATED),
+ __stringify(IPA_PM_DEACTIVATE_IN_PROGRESS),
+ __stringify(IPA_PM_ACTIVATE_IN_PROGRESS),
+ __stringify(IPA_PM_ACTIVATED),
+ __stringify(IPA_PM_ACTIVATED_PENDING_DEACTIVATION),
+ __stringify(IPA_PM_ACTIVATED_TIMER_SET),
+ __stringify(IPA_PM_ACTIVATED_PENDING_RESCHEDULE),
+};
+
+static const char *ipa_pm_group_to_str[IPA_PM_GROUP_MAX] = {
+ __stringify(IPA_PM_GROUP_DEFAULT),
+ __stringify(IPA_PM_GROUP_APPS),
+ __stringify(IPA_PM_GROUP_MODEM),
+};
+
+
+#define IPA_PM_DRV_NAME "ipa_pm"
+
+#define IPA_PM_DBG(fmt, args...) \
+ do { \
+ pr_debug(IPA_PM_DRV_NAME " %s:%d " fmt, \
+ __func__, __LINE__, ## args); \
+ IPA_IPC_LOGGING(ipa_get_ipc_logbuf(), \
+ IPA_PM_DRV_NAME " %s:%d " fmt, ## args); \
+ IPA_IPC_LOGGING(ipa_get_ipc_logbuf_low(), \
+ IPA_PM_DRV_NAME " %s:%d " fmt, ## args); \
+ } while (0)
+#define IPA_PM_DBG_LOW(fmt, args...) \
+ do { \
+ pr_debug(IPA_PM_DRV_NAME " %s:%d " fmt, \
+ __func__, __LINE__, ## args); \
+ IPA_IPC_LOGGING(ipa_get_ipc_logbuf_low(), \
+ IPA_PM_DRV_NAME " %s:%d " fmt, ## args); \
+ } while (0)
+#define IPA_PM_ERR(fmt, args...) \
+ do { \
+ pr_err(IPA_PM_DRV_NAME " %s:%d " fmt, \
+ __func__, __LINE__, ## args); \
+ IPA_IPC_LOGGING(ipa_get_ipc_logbuf(), \
+ IPA_PM_DRV_NAME " %s:%d " fmt, ## args); \
+ IPA_IPC_LOGGING(ipa_get_ipc_logbuf_low(), \
+ IPA_PM_DRV_NAME " %s:%d " fmt, ## args); \
+ } while (0)
+#define IPA_PM_DBG_STATE(hdl, name, state) \
+ IPA_PM_DBG_LOW("Client[%d] %s: %s\n", hdl, name, \
+ client_state_to_str[state])
+
+
+#if IPA_PM_MAX_CLIENTS > 32
+#error max client greater than 32 all bitmask types should be changed
+#endif
+
+/*
+ * struct ipa_pm_exception_list - holds information about an exception
+ * @pending: number of clients in exception that have not yet been adctivated
+ * @bitmask: bitmask of the clients in the exception based on handle
+ * @threshold: the threshold values for the exception
+ */
+struct ipa_pm_exception_list {
+ char clients[IPA_PM_MAX_EX_CL];
+ int pending;
+ u32 bitmask;
+ int threshold[IPA_PM_THRESHOLD_MAX];
+};
+
+/*
+ * struct clk_scaling_db - holds information about threshholds and exceptions
+ * @lock: lock the bitmasks and thresholds
+ * @exception_list: pointer to the list of exceptions
+ * @work: work for clock scaling algorithm
+ * @active_client_bitmask: the bits represent handles in the clients array that
+ * contain non-null client
+ * @threshold_size: size of the throughput threshold
+ * @exception_size: size of the exception list
+ * @cur_vote: idx of the threshold
+ * @default_threshold: the thresholds used if no exception passes
+ * @current_threshold: the current threshold of the clock plan
+ */
+struct clk_scaling_db {
+ spinlock_t lock;
+ struct ipa_pm_exception_list exception_list[IPA_PM_EXCEPTION_MAX];
+ struct work_struct work;
+ u32 active_client_bitmask;
+ int threshold_size;
+ int exception_size;
+ int cur_vote;
+ int default_threshold[IPA_PM_THRESHOLD_MAX];
+ int *current_threshold;
+};
+
+/*
+ * ipa_pm state names
+ *
+ * Timer free states:
+ * @IPA_PM_DEACTIVATED: client starting state when registered
+ * @IPA_PM_DEACTIVATE_IN_PROGRESS: deactivate was called in progress of a client
+ * activating
+ * @IPA_PM_ACTIVATE_IN_PROGRESS: client is being activated by work_queue
+ * @IPA_PM_ACTIVATED: client is activated without any timers
+ *
+ * Timer set states:
+ * @IPA_PM_ACTIVATED_PENDING_DEACTIVATION: moves to deactivate once timer pass
+ * @IPA_PM_ACTIVATED_TIMER_SET: client was activated while timer was set, so
+ * when the timer pass, client will still be activated
+ *@IPA_PM_ACTIVATED_PENDING_RESCHEDULE: state signifying extended timer when
+ * a client is deferred_deactivated when a time ris still active
+ */
+enum ipa_pm_state {
+ IPA_PM_DEACTIVATED,
+ IPA_PM_DEACTIVATE_IN_PROGRESS,
+ IPA_PM_ACTIVATE_IN_PROGRESS,
+ IPA_PM_ACTIVATED,
+ IPA_PM_ACTIVATED_PENDING_DEACTIVATION,
+ IPA_PM_ACTIVATED_TIMER_SET,
+ IPA_PM_ACTIVATED_PENDING_RESCHEDULE,
+};
+
+#define IPA_PM_STATE_ACTIVE(state) \
+ (state == IPA_PM_ACTIVATED ||\
+ state == IPA_PM_ACTIVATED_PENDING_DEACTIVATION ||\
+ state == IPA_PM_ACTIVATED_TIMER_SET ||\
+ state == IPA_PM_ACTIVATED_PENDING_RESCHEDULE)
+
+#define IPA_PM_STATE_IN_PROGRESS(state) \
+ (state == IPA_PM_ACTIVATE_IN_PROGRESS \
+ || state == IPA_PM_DEACTIVATE_IN_PROGRESS)
+
+/*
+ * struct ipa_pm_client - holds information about a specific IPA client
+ * @name: string name of the client
+ * @callback: pointer to the client's callback function
+ * @callback_params: pointer to the client's callback parameters
+ * @state: Activation state of the client
+ * @skip_clk_vote: 0 if client votes for clock when activated, 1 if no vote
+ * @group: the ipa_pm_group the client belongs to
+ * @hdl: handle of the client
+ * @throughput: the throughput of the client for clock scaling
+ * @state_lock: spinlock to lock the pm_states
+ * @activate_work: work for activate (blocking case)
+ * @deactivate work: delayed work for deferred_deactivate function
+ * @complete: generic wait-for-completion handler
+ */
+struct ipa_pm_client {
+ char name[IPA_PM_MAX_EX_CL];
+ void (*callback)(void*, enum ipa_pm_cb_event);
+ void *callback_params;
+ enum ipa_pm_state state;
+ bool skip_clk_vote;
+ int group;
+ int hdl;
+ int throughput;
+ spinlock_t state_lock;
+ struct work_struct activate_work;
+ struct delayed_work deactivate_work;
+ struct completion complete;
+};
+
+/*
+ * struct ipa_pm_ctx - global ctx that will hold the client arrays and tput info
+ * @clients: array to the clients with the handle as its index
+ * @clients_by_pipe: array to the clients with endpoint as the index
+ * @wq: work queue for deferred deactivate, activate, and clk_scaling work
+ 8 @clk_scaling: pointer to clock scaling database
+ * @client_mutex: global mutex to lock the client arrays
+ * @aggragated_tput: aggragated tput value of all valid activated clients
+ * @group_tput: combined throughput for the groups
+ */
+struct ipa_pm_ctx {
+ struct ipa_pm_client *clients[IPA_PM_MAX_CLIENTS];
+ struct ipa_pm_client *clients_by_pipe[IPA3_MAX_NUM_PIPES];
+ struct workqueue_struct *wq;
+ struct clk_scaling_db clk_scaling;
+ struct mutex client_mutex;
+ int aggregated_tput;
+ int group_tput[IPA_PM_GROUP_MAX];
+};
+
+static struct ipa_pm_ctx *ipa_pm_ctx;
+
+/**
+ * pop_max_from_array() -pop the max and move the last element to where the
+ * max was popped
+ * @arr: array to be searched for max
+ * @n: size of the array
+ *
+ * Returns: max value of the array
+ */
+static int pop_max_from_array(int *arr, int *n)
+{
+ int i;
+ int max, max_idx;
+
+ max_idx = *n - 1;
+ max = 0;
+
+ if (*n == 0)
+ return 0;
+
+ for (i = 0; i < *n; i++) {
+ if (arr[i] > max) {
+ max = arr[i];
+ max_idx = i;
+ }
+ }
+ (*n)--;
+ arr[max_idx] = arr[*n];
+
+ return max;
+}
+
+/**
+ * calculate_throughput() - calculate the aggregated throughput
+ * based on active clients
+ *
+ * Returns: aggregated tput value
+ */
+static int calculate_throughput(void)
+{
+ int client_tput[IPA_PM_MAX_CLIENTS] = { 0 };
+ bool group_voted[IPA_PM_GROUP_MAX] = { false };
+ int i, n;
+ int max, second_max, aggregated_tput;
+ struct ipa_pm_client *client;
+
+ /* Create a basic array to hold throughputs*/
+ for (i = 0, n = 0; i < IPA_PM_MAX_CLIENTS; i++) {
+ client = ipa_pm_ctx->clients[i];
+ if (client != NULL && IPA_PM_STATE_ACTIVE(client->state)) {
+ /* default case */
+ if (client->group == IPA_PM_GROUP_DEFAULT) {
+ client_tput[n++] = client->throughput;
+ } else if (group_voted[client->group] == false) {
+ client_tput[n++] = ipa_pm_ctx->group_tput
+ [client->group];
+ group_voted[client->group] = true;
+ }
+ }
+ }
+ /*the array will only use n+1 spots. n will be the last index used*/
+
+ aggregated_tput = 0;
+
+ /**
+ * throughput algorithm:
+ * 1) pop the max and second_max
+ * 2) add the 2nd max to aggregated tput
+ * 3) insert the value of max - 2nd max
+ * 4) repeat until array is of size 1
+ */
+ while (n > 1) {
+ max = pop_max_from_array(client_tput, &n);
+ second_max = pop_max_from_array(client_tput, &n);
+ client_tput[n++] = max - second_max;
+ aggregated_tput += second_max;
+ }
+
+ IPA_PM_DBG_LOW("Aggregated throughput: %d\n", aggregated_tput);
+
+ return aggregated_tput;
+}
+
+/**
+ * deactivate_client() - turn off the bit in the active client bitmask based on
+ * the handle passed in
+ * @hdl: The index of the client to be deactivated
+ */
+static void deactivate_client(u32 hdl)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&ipa_pm_ctx->clk_scaling.lock, flags);
+ ipa_pm_ctx->clk_scaling.active_client_bitmask &= ~(1 << hdl);
+ spin_unlock_irqrestore(&ipa_pm_ctx->clk_scaling.lock, flags);
+ IPA_PM_DBG_LOW("active bitmask: %x\n",
+ ipa_pm_ctx->clk_scaling.active_client_bitmask);
+}
+
+/**
+ * activate_client() - turn on the bit in the active client bitmask based on
+ * the handle passed in
+ * @hdl: The index of the client to be activated
+ */
+static void activate_client(u32 hdl)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&ipa_pm_ctx->clk_scaling.lock, flags);
+ ipa_pm_ctx->clk_scaling.active_client_bitmask |= (1 << hdl);
+ spin_unlock_irqrestore(&ipa_pm_ctx->clk_scaling.lock, flags);
+ IPA_PM_DBG_LOW("active bitmask: %x\n",
+ ipa_pm_ctx->clk_scaling.active_client_bitmask);
+}
+
+/**
+ * deactivate_client() - get threshold
+ *
+ * Returns: threshold of the exception that passes or default if none pass
+ */
+static void set_current_threshold(void)
+{
+ int i;
+ struct clk_scaling_db *clk;
+ struct ipa_pm_exception_list *exception;
+ unsigned long flags;
+
+ clk = &ipa_pm_ctx->clk_scaling;
+
+ spin_lock_irqsave(&ipa_pm_ctx->clk_scaling.lock, flags);
+ for (i = 0; i < clk->exception_size; i++) {
+ exception = &clk->exception_list[i];
+ if (exception->pending == 0 && (exception->bitmask
+ & ~clk->active_client_bitmask) == 0) {
+ spin_unlock_irqrestore(&ipa_pm_ctx->clk_scaling.lock,
+ flags);
+ clk->current_threshold = exception->threshold;
+ IPA_PM_DBG("Exception %d set\n", i);
+ return;
+ }
+ }
+ clk->current_threshold = clk->default_threshold;
+ spin_unlock_irqrestore(&ipa_pm_ctx->clk_scaling.lock, flags);
+}
+
+/**
+ * do_clk_scaling() - set the clock based on the activated clients
+ *
+ * Returns: 0 if success, negative otherwise
+ */
+static int do_clk_scaling(void)
+{
+ int i, tput;
+ int new_th_idx = 1;
+ struct clk_scaling_db *clk_scaling;
+
+ clk_scaling = &ipa_pm_ctx->clk_scaling;
+
+ mutex_lock(&ipa_pm_ctx->client_mutex);
+ IPA_PM_DBG("clock scaling started\n");
+ tput = calculate_throughput();
+ ipa_pm_ctx->aggregated_tput = tput;
+ set_current_threshold();
+
+ mutex_unlock(&ipa_pm_ctx->client_mutex);
+
+ for (i = 0; i < clk_scaling->threshold_size; i++) {
+ if (tput > clk_scaling->current_threshold[i])
+ new_th_idx++;
+ }
+
+ IPA_PM_DBG("old idx was at %d\n", ipa_pm_ctx->clk_scaling.cur_vote);
+
+
+ if (ipa_pm_ctx->clk_scaling.cur_vote != new_th_idx) {
+ ipa_pm_ctx->clk_scaling.cur_vote = new_th_idx;
+ ipa3_set_clock_plan_from_pm(ipa_pm_ctx->clk_scaling.cur_vote);
+ }
+
+ IPA_PM_DBG("new idx is at %d\n", ipa_pm_ctx->clk_scaling.cur_vote);
+
+ return 0;
+}
+
+/**
+ * clock_scaling_func() - set the clock on a work queue
+ */
+static void clock_scaling_func(struct work_struct *work)
+{
+ do_clk_scaling();
+}
+
+/**
+ * activate_work_func - activate a client and vote for clock on a work queue
+ */
+static void activate_work_func(struct work_struct *work)
+{
+ struct ipa_pm_client *client;
+ bool dec_clk = false;
+ unsigned long flags;
+
+ client = container_of(work, struct ipa_pm_client, activate_work);
+ if (!client->skip_clk_vote)
+ IPA_ACTIVE_CLIENTS_INC_SPECIAL(client->name);
+
+ spin_lock_irqsave(&client->state_lock, flags);
+ IPA_PM_DBG_STATE(client->hdl, client->name, client->state);
+ if (client->state == IPA_PM_ACTIVATE_IN_PROGRESS) {
+ client->state = IPA_PM_ACTIVATED;
+ } else if (client->state == IPA_PM_DEACTIVATE_IN_PROGRESS) {
+ client->state = IPA_PM_DEACTIVATED;
+ dec_clk = true;
+ } else {
+ IPA_PM_ERR("unexpected state %d\n", client->state);
+ WARN_ON(1);
+ }
+ spin_unlock_irqrestore(&client->state_lock, flags);
+
+ complete_all(&client->complete);
+
+ if (dec_clk) {
+ ipa_set_tag_process_before_gating(true);
+ if (!client->skip_clk_vote)
+ IPA_ACTIVE_CLIENTS_DEC_SPECIAL(client->name);
+
+ IPA_PM_DBG_STATE(client->hdl, client->name, client->state);
+ return;
+ }
+
+ activate_client(client->hdl);
+
+ mutex_lock(&ipa_pm_ctx->client_mutex);
+ client->callback(client->callback_params, IPA_PM_CLIENT_ACTIVATED);
+ mutex_unlock(&ipa_pm_ctx->client_mutex);
+
+ IPA_PM_DBG_STATE(client->hdl, client->name, client->state);
+ do_clk_scaling();
+}
+
+/**
+ * delayed_deferred_deactivate_work_func - deferred deactivate on a work queue
+ */
+static void delayed_deferred_deactivate_work_func(struct work_struct *work)
+{
+ struct delayed_work *dwork;
+ struct ipa_pm_client *client;
+ unsigned long flags;
+
+ dwork = container_of(work, struct delayed_work, work);
+ client = container_of(dwork, struct ipa_pm_client, deactivate_work);
+
+ spin_lock_irqsave(&client->state_lock, flags);
+ IPA_PM_DBG_STATE(client->hdl, client->name, client->state);
+ switch (client->state) {
+ case IPA_PM_ACTIVATED_TIMER_SET:
+ client->state = IPA_PM_ACTIVATED;
+ goto bail;
+ case IPA_PM_ACTIVATED_PENDING_RESCHEDULE:
+ queue_delayed_work(ipa_pm_ctx->wq, &client->deactivate_work,
+ msecs_to_jiffies(IPA_PM_DEFERRED_TIMEOUT));
+ client->state = IPA_PM_ACTIVATED_PENDING_DEACTIVATION;
+ goto bail;
+ case IPA_PM_ACTIVATED_PENDING_DEACTIVATION:
+ client->state = IPA_PM_DEACTIVATED;
+ IPA_PM_DBG_STATE(client->hdl, client->name, client->state);
+ spin_unlock_irqrestore(&client->state_lock, flags);
+ ipa_set_tag_process_before_gating(true);
+ if (!client->skip_clk_vote)
+ IPA_ACTIVE_CLIENTS_DEC_SPECIAL(client->name);
+
+ deactivate_client(client->hdl);
+ do_clk_scaling();
+ return;
+ default:
+ IPA_PM_ERR("unexpected state %d\n", client->state);
+ WARN_ON(1);
+ goto bail;
+ }
+
+bail:
+ IPA_PM_DBG_STATE(client->hdl, client->name, client->state);
+ spin_unlock_irqrestore(&client->state_lock, flags);
+}
+
+static int find_next_open_array_element(const char *name)
+{
+ int i, n;
+
+ n = -ENOBUFS;
+
+ for (i = IPA_PM_MAX_CLIENTS - 1; i >= 0; i--) {
+ if (ipa_pm_ctx->clients[i] == NULL) {
+ n = i;
+ continue;
+ }
+
+ if (strlen(name) == strlen(ipa_pm_ctx->clients[i]->name))
+ if (!strcmp(name, ipa_pm_ctx->clients[i]->name))
+ return -EEXIST;
+ }
+ return n;
+}
+
+/**
+ * add_client_to_exception_list() - add client to the exception list and
+ * update pending if necessary
+ * @hdl: index of the IPA client
+ *
+ * Returns: 0 if success, negative otherwise
+ */
+static int add_client_to_exception_list(u32 hdl)
+{
+ int i;
+ struct ipa_pm_exception_list *exception;
+
+ mutex_lock(&ipa_pm_ctx->client_mutex);
+ for (i = 0; i < ipa_pm_ctx->clk_scaling.exception_size; i++) {
+ exception = &ipa_pm_ctx->clk_scaling.exception_list[i];
+ if (strnstr(exception->clients, ipa_pm_ctx->clients[hdl]->name,
+ strlen(exception->clients))) {
+ exception->pending--;
+
+ if (exception->pending < 0) {
+ WARN_ON(1);
+ exception->pending = 0;
+ mutex_unlock(&ipa_pm_ctx->client_mutex);
+ return -EPERM;
+ }
+ exception->bitmask |= (1 << hdl);
+ }
+ }
+ IPA_PM_DBG("%s added to exception list\n",
+ ipa_pm_ctx->clients[hdl]->name);
+ mutex_unlock(&ipa_pm_ctx->client_mutex);
+
+ return 0;
+}
+
+/**
+ * remove_client_to_exception_list() - remove client from the exception list and
+ * update pending if necessary
+ * @hdl: index of the IPA client
+ *
+ * Returns: 0 if success, negative otherwise
+ */
+static int remove_client_from_exception_list(u32 hdl)
+{
+ int i;
+ struct ipa_pm_exception_list *exception;
+
+ for (i = 0; i < ipa_pm_ctx->clk_scaling.exception_size; i++) {
+ exception = &ipa_pm_ctx->clk_scaling.exception_list[i];
+ if (exception->bitmask & (1 << hdl)) {
+ exception->pending++;
+ exception->bitmask &= ~(1 << hdl);
+ }
+ }
+ IPA_PM_DBG("Client %d removed from exception list\n", hdl);
+
+ return 0;
+}
+
+/**
+ * ipa_pm_init() - initialize IPA PM Components
+ * @ipa_pm_init_params: parameters needed to fill exceptions and thresholds
+ *
+ * Returns: 0 on success, negative on failure
+ */
+int ipa_pm_init(struct ipa_pm_init_params *params)
+{
+ int i, j;
+ struct clk_scaling_db *clk_scaling;
+
+ if (params == NULL) {
+ IPA_PM_ERR("Invalid Params\n");
+ return -EINVAL;
+ }
+
+ if (params->threshold_size <= 0
+ || params->threshold_size > IPA_PM_THRESHOLD_MAX) {
+ IPA_PM_ERR("Invalid threshold size\n");
+ return -EINVAL;
+ }
+
+ if (params->exception_size < 0
+ || params->exception_size > IPA_PM_EXCEPTION_MAX) {
+ IPA_PM_ERR("Invalid exception size\n");
+ return -EINVAL;
+ }
+
+ IPA_PM_DBG("IPA PM initialization started\n");
+
+ if (ipa_pm_ctx != NULL) {
+ IPA_PM_ERR("Already initialized\n");
+ return -EPERM;
+ }
+
+
+ ipa_pm_ctx = kzalloc(sizeof(*ipa_pm_ctx), GFP_KERNEL);
+ if (!ipa_pm_ctx) {
+ IPA_PM_ERR(":kzalloc err.\n");
+ return -ENOMEM;
+ }
+
+ ipa_pm_ctx->wq = create_singlethread_workqueue("ipa_pm_activate");
+ if (!ipa_pm_ctx->wq) {
+ IPA_PM_ERR("create workqueue failed\n");
+ kfree(ipa_pm_ctx);
+ return -ENOMEM;
+ }
+
+ mutex_init(&ipa_pm_ctx->client_mutex);
+
+ /* Populate and init locks in clk_scaling_db */
+ clk_scaling = &ipa_pm_ctx->clk_scaling;
+ spin_lock_init(&clk_scaling->lock);
+ clk_scaling->threshold_size = params->threshold_size;
+ clk_scaling->exception_size = params->exception_size;
+ INIT_WORK(&clk_scaling->work, clock_scaling_func);
+
+ for (i = 0; i < params->threshold_size; i++)
+ clk_scaling->default_threshold[i] =
+ params->default_threshold[i];
+
+ /* Populate exception list*/
+ for (i = 0; i < params->exception_size; i++) {
+ strlcpy(clk_scaling->exception_list[i].clients,
+ params->exceptions[i].usecase, IPA_PM_MAX_EX_CL);
+ IPA_PM_DBG("Usecase: %s\n", params->exceptions[i].usecase);
+
+ /* Parse the commas to count the size of the clients */
+ for (j = 0; j < IPA_PM_MAX_EX_CL &&
+ clk_scaling->exception_list[i].clients[j]; j++) {
+ if (clk_scaling->exception_list[i].clients[j] == ',')
+ clk_scaling->exception_list[i].pending++;
+ }
+
+ clk_scaling->exception_list[i].pending++;
+ IPA_PM_DBG("Pending: %d\n", clk_scaling->
+ exception_list[i].pending);
+
+ /* populate the threshold */
+ for (j = 0; j < params->threshold_size; j++) {
+ clk_scaling->exception_list[i].threshold[j]
+ = params->exceptions[i].threshold[j];
+ }
+
+ }
+ IPA_PM_DBG("initialization success");
+
+ return 0;
+}
+
+int ipa_pm_destroy(void)
+{
+ IPA_PM_DBG("IPA PM destroy started\n");
+
+ if (ipa_pm_ctx == NULL) {
+ IPA_PM_ERR("Already destroyed\n");
+ return -EPERM;
+ }
+
+ destroy_workqueue(ipa_pm_ctx->wq);
+
+ kfree(ipa_pm_ctx);
+ ipa_pm_ctx = NULL;
+
+ return 0;
+}
+
+/**
+ * ipa_rm_delete_register() - register an IPA PM client with the PM
+ * @register_params: params for a client like throughput, callback, etc.
+ * @hdl: int pointer that will be used as an index to access the client
+ *
+ * Returns: 0 on success, negative on failure
+ *
+ * Side effects: *hdl is replaced with the client index or -EEXIST if
+ * client is already registered
+ */
+int ipa_pm_register(struct ipa_pm_register_params *params, u32 *hdl)
+{
+ struct ipa_pm_client *client;
+
+ if (params == NULL || hdl == NULL || params->name == NULL
+ || params->callback == NULL) {
+ IPA_PM_ERR("Invalid Params\n");
+ return -EINVAL;
+ }
+
+ IPA_PM_DBG("IPA PM registering client\n");
+
+ mutex_lock(&ipa_pm_ctx->client_mutex);
+
+ *hdl = find_next_open_array_element(params->name);
+
+ if (*hdl > IPA_CLIENT_MAX) {
+ mutex_unlock(&ipa_pm_ctx->client_mutex);
+ IPA_PM_ERR("client is already registered or array is full\n");
+ return *hdl;
+ }
+
+ ipa_pm_ctx->clients[*hdl] = kzalloc(sizeof
+ (struct ipa_pm_client), GFP_KERNEL);
+ if (!ipa_pm_ctx->clients[*hdl]) {
+ mutex_unlock(&ipa_pm_ctx->client_mutex);
+ IPA_PM_ERR(":kzalloc err.\n");
+ return -ENOMEM;
+ }
+ mutex_unlock(&ipa_pm_ctx->client_mutex);
+
+ client = ipa_pm_ctx->clients[*hdl];
+
+ spin_lock_init(&client->state_lock);
+
+ INIT_DELAYED_WORK(&client->deactivate_work,
+ delayed_deferred_deactivate_work_func);
+
+ INIT_WORK(&client->activate_work, activate_work_func);
+
+ /* populate fields */
+ strlcpy(client->name, params->name, IPA_PM_MAX_EX_CL);
+ client->callback = params->callback;
+ client->callback_params = params->user_data;
+ client->group = params->group;
+ client->hdl = *hdl;
+ client->skip_clk_vote = params->skip_clk_vote;
+
+ /* add client to exception list */
+ if (add_client_to_exception_list(*hdl)) {
+ ipa_pm_deregister(*hdl);
+ IPA_PM_ERR("Fail to add client to exception_list\n");
+ return -EPERM;
+ }
+
+ IPA_PM_DBG("IPA PM client registered with handle %d\n", *hdl);
+ return 0;
+}
+
+/**
+ * ipa_pm_deregister() - deregister IPA client from the PM
+ * @hdl: index of the client in the array
+ *
+ * Returns: 0 on success, negative on failure
+ */
+int ipa_pm_deregister(u32 hdl)
+{
+ struct ipa_pm_client *client;
+ int i;
+ unsigned long flags;
+
+ if (hdl >= IPA_PM_MAX_CLIENTS) {
+ IPA_PM_ERR("Invalid Param\n");
+ return -EINVAL;
+ }
+
+ if (ipa_pm_ctx->clients[hdl] == NULL) {
+ IPA_PM_ERR("Client is Null\n");
+ return -EINVAL;
+ }
+
+ IPA_PM_DBG("IPA PM deregistering client\n");
+
+ client = ipa_pm_ctx->clients[hdl];
+ spin_lock_irqsave(&client->state_lock, flags);
+ if (IPA_PM_STATE_IN_PROGRESS(client->state)) {
+ spin_unlock_irqrestore(&client->state_lock, flags);
+ wait_for_completion(&client->complete);
+ spin_lock_irqsave(&client->state_lock, flags);
+ }
+
+ if (IPA_PM_STATE_ACTIVE(client->state)) {
+ IPA_PM_DBG("Activated clients cannot be deregistered");
+ spin_unlock_irqrestore(&client->state_lock, flags);
+ return -EPERM;
+ }
+ spin_unlock_irqrestore(&client->state_lock, flags);
+
+ mutex_lock(&ipa_pm_ctx->client_mutex);
+
+ /* nullify pointers in pipe array */
+ for (i = 0; i < IPA3_MAX_NUM_PIPES; i++) {
+ if (ipa_pm_ctx->clients_by_pipe[i] == ipa_pm_ctx->clients[hdl])
+ ipa_pm_ctx->clients_by_pipe[i] = NULL;
+ }
+ kfree(client);
+ ipa_pm_ctx->clients[hdl] = NULL;
+
+ remove_client_from_exception_list(hdl);
+ IPA_PM_DBG("IPA PM client %d deregistered\n", hdl);
+ mutex_unlock(&ipa_pm_ctx->client_mutex);
+
+ return 0;
+}
+
+/**
+ * ipa_pm_associate_ipa_cons_to_client() - add mapping to pipe with ipa cllent
+ * @hdl: index of the client to be mapped
+ * @consumer: the pipe/consumer name to be pipped to the client
+ *
+ * Returns: 0 on success, negative on failure
+ *
+ * Side effects: multiple pipes are allowed to be mapped to a single client
+ */
+int ipa_pm_associate_ipa_cons_to_client(u32 hdl, enum ipa_client_type consumer)
+{
+ int idx;
+
+ if (hdl >= IPA_PM_MAX_CLIENTS || consumer < 0 ||
+ consumer >= IPA_CLIENT_MAX) {
+ IPA_PM_ERR("invalid params\n");
+ return -EINVAL;
+ }
+
+ mutex_lock(&ipa_pm_ctx->client_mutex);
+ idx = ipa_get_ep_mapping(consumer);
+
+ IPA_PM_DBG("Mapping pipe %d to client %d\n", idx, hdl);
+
+ if (idx < 0) {
+ mutex_unlock(&ipa_pm_ctx->client_mutex);
+ IPA_PM_DBG("Pipe is not used\n");
+ return 0;
+ }
+
+ if (ipa_pm_ctx->clients[hdl] == NULL) {
+ mutex_unlock(&ipa_pm_ctx->client_mutex);
+ IPA_PM_ERR("Client is NULL\n");
+ return -EPERM;
+ }
+
+ if (ipa_pm_ctx->clients_by_pipe[idx] != NULL) {
+ mutex_unlock(&ipa_pm_ctx->client_mutex);
+ IPA_PM_ERR("Pipe is already mapped\n");
+ return -EPERM;
+ }
+ ipa_pm_ctx->clients_by_pipe[idx] = ipa_pm_ctx->clients[hdl];
+ mutex_unlock(&ipa_pm_ctx->client_mutex);
+
+ IPA_PM_DBG("Pipe %d is mapped to client %d\n", idx, hdl);
+
+ return 0;
+}
+
+static int ipa_pm_activate_helper(struct ipa_pm_client *client, bool sync)
+{
+ struct ipa_active_client_logging_info log_info;
+ int result = 0;
+ unsigned long flags;
+
+ spin_lock_irqsave(&client->state_lock, flags);
+ IPA_PM_DBG_STATE(client->hdl, client->name, client->state);
+
+ if (IPA_PM_STATE_IN_PROGRESS(client->state)) {
+ if (sync) {
+ spin_unlock_irqrestore(&client->state_lock, flags);
+ wait_for_completion(&client->complete);
+ spin_lock_irqsave(&client->state_lock, flags);
+ } else {
+ client->state = IPA_PM_ACTIVATE_IN_PROGRESS;
+ spin_unlock_irqrestore(&client->state_lock, flags);
+ return -EINPROGRESS;
+ }
+ }
+
+ switch (client->state) {
+ case IPA_PM_ACTIVATED_PENDING_RESCHEDULE:
+ case IPA_PM_ACTIVATED_PENDING_DEACTIVATION:
+ client->state = IPA_PM_ACTIVATED_TIMER_SET;
+ case IPA_PM_ACTIVATED:
+ case IPA_PM_ACTIVATED_TIMER_SET:
+ spin_unlock_irqrestore(&client->state_lock, flags);
+ return 0;
+ case IPA_PM_DEACTIVATED:
+ break;
+ default:
+ IPA_PM_ERR("Invalid State\n");
+ spin_unlock_irqrestore(&client->state_lock, flags);
+ return -EPERM;
+ }
+ IPA_PM_DBG_STATE(client->hdl, client->name, client->state);
+
+ IPA_ACTIVE_CLIENTS_PREP_SPECIAL(log_info, client->name);
+ if (!client->skip_clk_vote) {
+ if (sync) {
+ client->state = IPA_PM_ACTIVATE_IN_PROGRESS;
+ spin_unlock_irqrestore(&client->state_lock, flags);
+ IPA_ACTIVE_CLIENTS_INC_SPECIAL(client->name);
+ spin_lock_irqsave(&client->state_lock, flags);
+ } else
+ result = ipa3_inc_client_enable_clks_no_block
+ (&log_info);
+ }
+
+ /* we got the clocks */
+ if (result == 0) {
+ client->state = IPA_PM_ACTIVATED;
+ spin_unlock_irqrestore(&client->state_lock, flags);
+ activate_client(client->hdl);
+ if (sync)
+ do_clk_scaling();
+ else
+ queue_work(ipa_pm_ctx->wq,
+ &ipa_pm_ctx->clk_scaling.work);
+ IPA_PM_DBG_STATE(client->hdl, client->name, client->state);
+ return 0;
+ }
+
+ client->state = IPA_PM_ACTIVATE_IN_PROGRESS;
+ init_completion(&client->complete);
+ queue_work(ipa_pm_ctx->wq, &client->activate_work);
+ spin_unlock_irqrestore(&client->state_lock, flags);
+ IPA_PM_DBG_STATE(client->hdl, client->name, client->state);
+ return -EINPROGRESS;
+}
+
+/**
+ * ipa_pm_activate(): activate ipa client to vote for clock(). Can be called
+ * from atomic context and returns -EINPROGRESS if cannot be done synchronously
+ * @hdl: index of the client in the array
+ *
+ * Returns: 0 on success, -EINPROGRESS if operation cannot be done synchronously
+ * and other negatives on failure
+ */
+int ipa_pm_activate(u32 hdl)
+{
+ if (hdl >= IPA_PM_MAX_CLIENTS || ipa_pm_ctx->clients[hdl] == NULL) {
+ IPA_PM_ERR("Invalid Param\n");
+ return -EINVAL;
+ }
+
+ return ipa_pm_activate_helper(ipa_pm_ctx->clients[hdl], false);
+}
+
+/**
+ * ipa_pm_activate(): activate ipa client to vote for clock synchronously.
+ * Cannot be called from an atomic contex.
+ * @hdl: index of the client in the array
+ *
+ * Returns: 0 on success, negative on failure
+ */
+int ipa_pm_activate_sync(u32 hdl)
+{
+ if (hdl >= IPA_PM_MAX_CLIENTS || ipa_pm_ctx->clients[hdl] == NULL) {
+ IPA_PM_ERR("Invalid Param\n");
+ return -EINVAL;
+ }
+
+ return ipa_pm_activate_helper(ipa_pm_ctx->clients[hdl], true);
+}
+
+/**
+ * ipa_pm_deferred_deactivate(): schedule a timer to deactivate client and
+ * devote clock. Can be called from atomic context (asynchronously)
+ * @hdl: index of the client in the array
+ *
+ * Returns: 0 on success, negative on failure
+ */
+int ipa_pm_deferred_deactivate(u32 hdl)
+{
+ struct ipa_pm_client *client;
+ unsigned long flags;
+
+ if (hdl >= IPA_PM_MAX_CLIENTS || ipa_pm_ctx->clients[hdl] == NULL) {
+ IPA_PM_ERR("Invalid Param\n");
+ return -EINVAL;
+ }
+
+ client = ipa_pm_ctx->clients[hdl];
+ IPA_PM_DBG_STATE(hdl, client->name, client->state);
+
+ spin_lock_irqsave(&client->state_lock, flags);
+ switch (client->state) {
+ case IPA_PM_ACTIVATE_IN_PROGRESS:
+ client->state = IPA_PM_DEACTIVATE_IN_PROGRESS;
+ case IPA_PM_DEACTIVATED:
+ IPA_PM_DBG_STATE(hdl, client->name, client->state);
+ spin_unlock_irqrestore(&client->state_lock, flags);
+ return 0;
+ case IPA_PM_ACTIVATED:
+ client->state = IPA_PM_ACTIVATED_PENDING_DEACTIVATION;
+ queue_delayed_work(ipa_pm_ctx->wq, &client->deactivate_work,
+ msecs_to_jiffies(IPA_PM_DEFERRED_TIMEOUT));
+ break;
+ case IPA_PM_ACTIVATED_TIMER_SET:
+ case IPA_PM_ACTIVATED_PENDING_DEACTIVATION:
+ client->state = IPA_PM_ACTIVATED_PENDING_RESCHEDULE;
+ case IPA_PM_DEACTIVATE_IN_PROGRESS:
+ case IPA_PM_ACTIVATED_PENDING_RESCHEDULE:
+ break;
+ }
+ IPA_PM_DBG_STATE(hdl, client->name, client->state);
+ spin_unlock_irqrestore(&client->state_lock, flags);
+
+ return 0;
+}
+
+/**
+ * ipa_pm_deactivate_all_deferred(): Cancel the deferred deactivation timer and
+ * immediately devotes for IPA clocks
+ *
+ * Returns: 0 on success, negative on failure
+ */
+int ipa_pm_deactivate_all_deferred(void)
+{
+ int i;
+ bool run_algorithm = false;
+ struct ipa_pm_client *client;
+ unsigned long flags;
+
+ for (i = 0; i < IPA_PM_MAX_CLIENTS; i++) {
+ client = ipa_pm_ctx->clients[i];
+
+ if (client == NULL)
+ continue;
+
+ cancel_delayed_work_sync(&client->deactivate_work);
+
+ if (IPA_PM_STATE_IN_PROGRESS(client->state)) {
+ wait_for_completion(&client->complete);
+ continue;
+ }
+
+ spin_lock_irqsave(&client->state_lock, flags);
+ IPA_PM_DBG_STATE(client->hdl, client->name, client->state);
+
+ if (client->state == IPA_PM_ACTIVATED_TIMER_SET) {
+ client->state = IPA_PM_ACTIVATED;
+ IPA_PM_DBG_STATE(client->hdl, client->name,
+ client->state);
+ spin_unlock_irqrestore(&client->state_lock, flags);
+ } else if (client->state ==
+ IPA_PM_ACTIVATED_PENDING_DEACTIVATION ||
+ IPA_PM_ACTIVATED_PENDING_RESCHEDULE) {
+ run_algorithm = true;
+ client->state = IPA_PM_DEACTIVATED;
+ IPA_PM_DBG_STATE(client->hdl, client->name,
+ client->state);
+ spin_unlock_irqrestore(&client->state_lock, flags);
+ ipa_set_tag_process_before_gating(true);
+ if (!client->skip_clk_vote)
+ IPA_ACTIVE_CLIENTS_DEC_SPECIAL(client->name);
+ deactivate_client(client->hdl);
+ } else /* if activated or deactivated, we do nothing */
+ spin_unlock_irqrestore(&client->state_lock, flags);
+ }
+
+ if (run_algorithm)
+ do_clk_scaling();
+
+ return 0;
+}
+
+/**
+ * ipa_pm_deactivate_sync(): deactivate ipa client and devote clock. Cannot be
+ * called from atomic context.
+ * @hdl: index of the client in the array
+ *
+ * Returns: 0 on success, negative on failure
+ */
+int ipa_pm_deactivate_sync(u32 hdl)
+{
+ struct ipa_pm_client *client = ipa_pm_ctx->clients[hdl];
+ unsigned long flags;
+
+ if (hdl >= IPA_PM_MAX_CLIENTS || ipa_pm_ctx->clients[hdl] == NULL) {
+ IPA_PM_ERR("Invalid Param\n");
+ return -EINVAL;
+ }
+
+ cancel_delayed_work_sync(&client->deactivate_work);
+
+ if (IPA_PM_STATE_IN_PROGRESS(client->state))
+ wait_for_completion(&client->complete);
+
+ spin_lock_irqsave(&client->state_lock, flags);
+ IPA_PM_DBG_STATE(hdl, client->name, client->state);
+
+ if (client->state == IPA_PM_DEACTIVATED) {
+ spin_unlock_irqrestore(&client->state_lock, flags);
+ return 0;
+ }
+
+ spin_unlock_irqrestore(&client->state_lock, flags);
+
+ /* else case (Deactivates all Activated cases)*/
+ ipa_set_tag_process_before_gating(true);
+ if (!client->skip_clk_vote)
+ IPA_ACTIVE_CLIENTS_DEC_SPECIAL(client->name);
+
+ spin_lock_irqsave(&client->state_lock, flags);
+ client->state = IPA_PM_DEACTIVATED;
+ IPA_PM_DBG_STATE(hdl, client->name, client->state);
+ spin_unlock_irqrestore(&client->state_lock, flags);
+ deactivate_client(hdl);
+ do_clk_scaling();
+
+ return 0;
+}
+
+/**
+ * ipa_pm_handle_suspend(): calls the callbacks of suspended clients to wake up
+ * @pipe_bitmask: the bits represent the indexes of the clients to be woken up
+ *
+ * Returns: 0 on success, negative on failure
+ */
+int ipa_pm_handle_suspend(u32 pipe_bitmask)
+{
+ int i;
+ struct ipa_pm_client *client;
+ bool client_notified[IPA_PM_MAX_CLIENTS] = { false };
+
+ IPA_PM_DBG_LOW("bitmask: %d", pipe_bitmask);
+
+ if (pipe_bitmask == 0)
+ return 0;
+
+ mutex_lock(&ipa_pm_ctx->client_mutex);
+ for (i = 0; i < IPA3_MAX_NUM_PIPES; i++) {
+ if (pipe_bitmask & (1 << i)) {
+ client = ipa_pm_ctx->clients_by_pipe[i];
+ if (client && client_notified[client->hdl] == false) {
+ client->callback(client->callback_params,
+ IPA_PM_REQUEST_WAKEUP);
+ client_notified[client->hdl] = true;
+ }
+ }
+ }
+ mutex_unlock(&ipa_pm_ctx->client_mutex);
+ return 0;
+}
+
+/**
+ * ipa_pm_set_perf_profile(): Adds/changes the throughput requirement to IPA PM
+ * to be used for clock scaling
+ * @hdl: index of the client in the array
+ * @throughput: the new throughput value to be set for that client
+ *
+ * Returns: 0 on success, negative on failure
+ */
+int ipa_pm_set_perf_profile(u32 hdl, int throughput)
+{
+ struct ipa_pm_client *client = ipa_pm_ctx->clients[hdl];
+ unsigned long flags;
+
+ if (hdl >= IPA_PM_MAX_CLIENTS || ipa_pm_ctx->clients[hdl] == NULL
+ || throughput < 0) {
+ IPA_PM_ERR("Invalid Params\n");
+ return -EINVAL;
+ }
+
+ mutex_lock(&ipa_pm_ctx->client_mutex);
+ if (client->group == IPA_PM_GROUP_DEFAULT)
+ IPA_PM_DBG_LOW("Old throughput: %d\n", client->throughput);
+ else
+ IPA_PM_DBG_LOW("old Group %d throughput: %d\n",
+ client->group, ipa_pm_ctx->group_tput[client->group]);
+
+ if (client->group == IPA_PM_GROUP_DEFAULT)
+ client->throughput = throughput;
+ else
+ ipa_pm_ctx->group_tput[client->group] = throughput;
+
+ if (client->group == IPA_PM_GROUP_DEFAULT)
+ IPA_PM_DBG_LOW("New throughput: %d\n", client->throughput);
+ else
+ IPA_PM_DBG_LOW("New Group %d throughput: %d\n",
+ client->group, ipa_pm_ctx->group_tput[client->group]);
+ mutex_unlock(&ipa_pm_ctx->client_mutex);
+
+ spin_lock_irqsave(&client->state_lock, flags);
+ if (IPA_PM_STATE_ACTIVE(client->state || (client->group !=
+ IPA_PM_GROUP_DEFAULT))) {
+ spin_unlock_irqrestore(&client->state_lock, flags);
+ do_clk_scaling();
+ return 0;
+ }
+ spin_unlock_irqrestore(&client->state_lock, flags);
+
+ return 0;
+}
+
+/**
+ * ipa_pm_stat() - print PM stat
+ * @buf: [in] The user buff used to print
+ * @size: [in] The size of buf
+ * Returns: number of bytes used on success, negative on failure
+ *
+ * This function is called by ipa_debugfs in order to receive
+ * a picture of the clients in the PM and the throughput, threshold and cur vote
+ */
+int ipa_pm_stat(char *buf, int size)
+{
+ struct ipa_pm_client *client;
+ struct clk_scaling_db *clk = &ipa_pm_ctx->clk_scaling;
+ int i, j, tput, cnt = 0, result = 0;
+ unsigned long flags;
+
+ if (!buf || size < 0)
+ return -EINVAL;
+
+ mutex_lock(&ipa_pm_ctx->client_mutex);
+
+ result = scnprintf(buf + cnt, size - cnt, "\n\nCurrent threshold: [");
+ cnt += result;
+
+ for (i = 0; i < clk->threshold_size; i++) {
+ result = scnprintf(buf + cnt, size - cnt,
+ "%d, ", clk->current_threshold[i]);
+ cnt += result;
+ }
+
+ result = scnprintf(buf + cnt, size - cnt, "\b\b]\n");
+ cnt += result;
+
+ result = scnprintf(buf + cnt, size - cnt,
+ "Aggregated tput: %d, Cur vote: %d",
+ ipa_pm_ctx->aggregated_tput, clk->cur_vote);
+ cnt += result;
+
+ result = scnprintf(buf + cnt, size - cnt, "\n\nRegistered Clients:\n");
+ cnt += result;
+
+
+ for (i = 0; i < IPA_PM_MAX_CLIENTS; i++) {
+ client = ipa_pm_ctx->clients[i];
+
+ if (client == NULL)
+ continue;
+
+ spin_lock_irqsave(&client->state_lock, flags);
+ if (client->group == IPA_PM_GROUP_DEFAULT)
+ tput = client->throughput;
+ else
+ tput = ipa_pm_ctx->group_tput[client->group];
+
+ result = scnprintf(buf + cnt, size - cnt,
+ "Client[%d]: %s State:%s\nGroup: %s Throughput: %d Pipes: ",
+ i, client->name, client_state_to_str[client->state],
+ ipa_pm_group_to_str[client->group], tput);
+ cnt += result;
+
+ for (j = 0; j < IPA3_MAX_NUM_PIPES; j++) {
+ if (ipa_pm_ctx->clients_by_pipe[j] == client) {
+ result = scnprintf(buf + cnt, size - cnt,
+ "%d, ", j);
+ cnt += result;
+ }
+ }
+
+ result = scnprintf(buf + cnt, size - cnt, "\b\b\n\n");
+ cnt += result;
+ spin_unlock_irqrestore(&client->state_lock, flags);
+ }
+ mutex_unlock(&ipa_pm_ctx->client_mutex);
+
+ return cnt;
+}
+
+/**
+ * ipa_pm_exceptions_stat() - print PM exceptions stat
+ * @buf: [in] The user buff used to print
+ * @size: [in] The size of buf
+ * Returns: number of bytes used on success, negative on failure
+ *
+ * This function is called by ipa_debugfs in order to receive
+ * a full picture of the exceptions in the PM
+ */
+int ipa_pm_exceptions_stat(char *buf, int size)
+{
+ int i, j, cnt = 0, result = 0;
+ struct ipa_pm_exception_list *exception;
+
+ if (!buf || size < 0)
+ return -EINVAL;
+
+ result = scnprintf(buf + cnt, size - cnt, "\n");
+ cnt += result;
+
+ mutex_lock(&ipa_pm_ctx->client_mutex);
+ for (i = 0; i < ipa_pm_ctx->clk_scaling.exception_size; i++) {
+ exception = &ipa_pm_ctx->clk_scaling.exception_list[i];
+ if (exception == NULL) {
+ result = scnprintf(buf + cnt, size - cnt,
+ "Exception %d is NULL\n\n", i);
+ cnt += result;
+ continue;
+ }
+
+ result = scnprintf(buf + cnt, size - cnt,
+ "Exception %d: %s\nPending: %d Bitmask: %d Threshold: ["
+ , i, exception->clients, exception->pending,
+ exception->bitmask);
+ cnt += result;
+ for (j = 0; j < ipa_pm_ctx->clk_scaling.threshold_size; j++) {
+ result = scnprintf(buf + cnt, size - cnt,
+ "%d, ", exception->threshold[j]);
+ cnt += result;
+ }
+ result = scnprintf(buf + cnt, size - cnt, "\b\b]\n\n");
+ cnt += result;
+ }
+ mutex_unlock(&ipa_pm_ctx->client_mutex);
+
+ return cnt;
+}
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_pm.h b/drivers/platform/msm/ipa/ipa_v3/ipa_pm.h
new file mode 100644
index 0000000..ca022b5
--- /dev/null
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_pm.h
@@ -0,0 +1,110 @@
+/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _IPA_PM_H_
+#define _IPA_PM_H_
+
+#include <linux/msm_ipa.h>
+
+/* internal to ipa */
+#define IPA_PM_MAX_CLIENTS 10
+#define IPA_PM_MAX_EX_CL 64
+#define IPA_PM_THRESHOLD_MAX 2
+#define IPA_PM_EXCEPTION_MAX 2
+#define IPA_PM_DEFERRED_TIMEOUT 100
+#define IPA_PM_STATE_MAX 7
+
+/*
+ * ipa_pm group names
+ *
+ * Default stands for individual clients while other groups share one throughput
+ * Some groups also have special flags like modem which do not vote for clock
+ * but is accounted for in clock scaling while activated
+ */
+enum ipa_pm_group {
+ IPA_PM_GROUP_DEFAULT,
+ IPA_PM_GROUP_APPS,
+ IPA_PM_GROUP_MODEM,
+ IPA_PM_GROUP_MAX,
+};
+
+/*
+ * ipa_pm_cb_event
+ *
+ * specifies what kind of callback is being called.
+ * IPA_PM_CLIENT_ACTIVATED: the client has completed asynchronous activation
+ * IPA_PM_REQUEST_WAKEUP: wake up the client after it has been suspended
+ */
+enum ipa_pm_cb_event {
+ IPA_PM_CLIENT_ACTIVATED,
+ IPA_PM_REQUEST_WAKEUP,
+ IPA_PM_CB_EVENT_MAX,
+};
+
+/*
+ * struct ipa_pm_exception - clients included in exception and its threshold
+ * @usecase: comma separated client names
+ * @threshold: the threshold values for the exception
+ */
+struct ipa_pm_exception {
+ const char *usecase;
+ int threshold[IPA_PM_THRESHOLD_MAX];
+};
+
+/*
+ * struct ipa_pm_init_params - parameters needed for initializng the pm
+ * @default_threshold: the thresholds used if no exception passes
+ * @threshold_size: size of the threshold
+ * @exceptions: list of exceptions for the pm
+ * @exception_size: size of the exception_list
+ */
+struct ipa_pm_init_params {
+ int default_threshold[IPA_PM_THRESHOLD_MAX];
+ int threshold_size;
+ struct ipa_pm_exception exceptions[IPA_PM_EXCEPTION_MAX];
+ int exception_size;
+};
+
+/*
+ * struct ipa_pm_register_params - parameters needed to register a client
+ * @name: name of the client
+ * @callback: pointer to the client's callback function
+ * @user_data: pointer to the client's callback parameters
+ * @group: group number of the client
+ * @skip_clk_vote: 0 if client votes for clock when activated, 1 if no vote
+ */
+struct ipa_pm_register_params {
+ const char *name;
+ void (*callback)(void*, enum ipa_pm_cb_event);
+ void *user_data;
+ enum ipa_pm_group group;
+ bool skip_clk_vote;
+};
+
+int ipa_pm_register(struct ipa_pm_register_params *params, u32 *hdl);
+int ipa_pm_associate_ipa_cons_to_client(u32 hdl, enum ipa_client_type consumer);
+int ipa_pm_activate(u32 hdl);
+int ipa_pm_activate_sync(u32 hdl);
+int ipa_pm_deferred_deactivate(u32 hdl);
+int ipa_pm_deactivate_sync(u32 hdl);
+int ipa_pm_set_perf_profile(u32 hdl, int throughput);
+int ipa_pm_deregister(u32 hdl);
+
+/* IPA Internal Functions */
+int ipa_pm_init(struct ipa_pm_init_params *params);
+int ipa_pm_destroy(void);
+int ipa_pm_handle_suspend(u32 pipe_bitmask);
+int ipa_pm_deactivate_all_deferred(void);
+int ipa_pm_stat(char *buf, int size);
+int ipa_pm_exceptions_stat(char *buf, int size);
+
+#endif /* _IPA_PM_H_ */
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c b/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c
index 61bccc6..4e8c233 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c
@@ -1214,7 +1214,6 @@
/* voting for bus BW to ipa_rm*/
int ipa3_vote_for_bus_bw(uint32_t *bw_mbps)
{
- struct ipa_rm_perf_profile profile;
int ret;
if (bw_mbps == NULL) {
@@ -1222,16 +1221,13 @@
return -EINVAL;
}
- memset(&profile, 0, sizeof(profile));
- profile.max_supported_bandwidth_mbps = *bw_mbps;
- ret = ipa_rm_set_perf_profile(IPA_RM_RESOURCE_Q6_PROD,
- &profile);
+ ret = ipa3_wwan_set_modem_perf_profile(*bw_mbps);
if (ret)
IPAWANERR("Failed to set perf profile to BW %u\n",
- profile.max_supported_bandwidth_mbps);
+ *bw_mbps);
else
IPAWANDBG("Succeeded to set perf profile to BW %u\n",
- profile.max_supported_bandwidth_mbps);
+ *bw_mbps);
return ret;
}
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.h b/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.h
index d5d8503..d3a4ba0 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.h
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.h
@@ -207,6 +207,10 @@
void ipa3_q6_handshake_complete(bool ssr_bootup);
+int ipa3_wwan_set_modem_perf_profile(int throughput);
+
+int ipa3_wwan_set_modem_state(struct wan_ioctl_notify_wan_state *state);
+
void ipa3_qmi_init(void);
void ipa3_qmi_cleanup(void);
@@ -323,6 +327,11 @@
static inline void ipa3_q6_handshake_complete(bool ssr_bootup) { }
+static inline int ipa3_wwan_set_modem_perf_profile(int throughput)
+{
+ return -EPERM;
+}
+
static inline void ipa3_qmi_init(void)
{
}
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c
index 5206337..f717264 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c
@@ -4855,11 +4855,8 @@
IPADBG("ch %ld not empty\n", ep->gsi_chan_hdl);
/* queue a work to start polling if don't have one */
atomic_set(&ipa3_ctx->transport_pm.eot_activity, 1);
- if (!atomic_read(&ep->sys->curr_polling_state)) {
- ipa3_inc_acquire_wakelock();
- atomic_set(&ep->sys->curr_polling_state, 1);
- queue_work(ep->sys->wq, &ep->sys->work);
- }
+ if (!atomic_read(&ep->sys->curr_polling_state))
+ __ipa_gsi_irq_rx_scedule_poll(ep->sys);
}
}
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.c b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.c
index dc71414..74f5bbd 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.c
@@ -1961,20 +1961,3 @@
valmask->mask = valmask->val;
}
-
-void ipahal_get_status_ep_valmask(int pipe_num,
- struct ipahal_reg_valmask *valmask)
-{
- if (!valmask) {
- IPAHAL_ERR("Input error\n");
- return;
- }
-
- valmask->val =
- (pipe_num & IPA_ENDP_STATUS_n_STATUS_ENDP_BMSK) <<
- IPA_ENDP_STATUS_n_STATUS_ENDP_SHFT;
-
- valmask->mask =
- IPA_ENDP_STATUS_n_STATUS_ENDP_BMSK <<
- IPA_ENDP_STATUS_n_STATUS_ENDP_SHFT;
-}
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.h b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.h
index a2864cd..df3c976 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.h
+++ b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.h
@@ -541,8 +541,6 @@
void ipahal_get_fltrt_hash_flush_valmask(
struct ipahal_reg_fltrt_hash_flush *flush,
struct ipahal_reg_valmask *valmask);
-void ipahal_get_status_ep_valmask(int pipe_num,
- struct ipahal_reg_valmask *valmask);
#endif /* _IPAHAL_REG_H_ */
diff --git a/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c b/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c
index 5095e1f..f08e1e3 100644
--- a/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c
+++ b/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c
@@ -142,6 +142,9 @@
u32 ipa3_to_apps_hdl;
struct mutex pipe_handle_guard;
struct mutex add_mux_channel_lock;
+ u32 pm_hdl;
+ u32 q6_pm_hdl;
+ u32 q6_teth_pm_hdl;
};
static struct rmnet_ipa3_context *rmnet_ipa3_ctx;
@@ -1134,8 +1137,14 @@
send:
/* IPA_RM checking start */
- ret = ipa_rm_inactivity_timer_request_resource(
- IPA_RM_RESOURCE_WWAN_0_PROD);
+ if (ipa3_ctx->use_ipa_pm) {
+ /* activate the modem pm for clock scaling */
+ ipa_pm_activate(rmnet_ipa3_ctx->q6_pm_hdl);
+ ret = ipa_pm_activate(rmnet_ipa3_ctx->pm_hdl);
+ } else {
+ ret = ipa_rm_inactivity_timer_request_resource(
+ IPA_RM_RESOURCE_WWAN_0_PROD);
+ }
if (ret == -EINPROGRESS) {
netif_stop_queue(dev);
return NETDEV_TX_BUSY;
@@ -1164,9 +1173,15 @@
dev->stats.tx_bytes += skb->len;
ret = NETDEV_TX_OK;
out:
- if (atomic_read(&wwan_ptr->outstanding_pkts) == 0)
- ipa_rm_inactivity_timer_release_resource(
- IPA_RM_RESOURCE_WWAN_0_PROD);
+ if (atomic_read(&wwan_ptr->outstanding_pkts) == 0) {
+ if (ipa3_ctx->use_ipa_pm) {
+ ipa_pm_deferred_deactivate(rmnet_ipa3_ctx->pm_hdl);
+ ipa_pm_deferred_deactivate(rmnet_ipa3_ctx->q6_pm_hdl);
+ } else {
+ ipa_rm_inactivity_timer_release_resource(
+ IPA_RM_RESOURCE_WWAN_0_PROD);
+ }
+ }
return ret;
}
@@ -1218,9 +1233,15 @@
netif_wake_queue(wwan_ptr->net);
}
- if (atomic_read(&wwan_ptr->outstanding_pkts) == 0)
- ipa_rm_inactivity_timer_release_resource(
+ if (atomic_read(&wwan_ptr->outstanding_pkts) == 0) {
+ if (ipa3_ctx->use_ipa_pm) {
+ ipa_pm_deferred_deactivate(rmnet_ipa3_ctx->pm_hdl);
+ ipa_pm_deferred_deactivate(rmnet_ipa3_ctx->q6_pm_hdl);
+ } else {
+ ipa_rm_inactivity_timer_release_resource(
IPA_RM_RESOURCE_WWAN_0_PROD);
+ }
+ }
__netif_tx_unlock_bh(netdev_get_tx_queue(dev, 0));
dev_kfree_skb_any(skb);
}
@@ -1858,6 +1879,91 @@
return;
}
}
+
+int ipa3_wwan_set_modem_state(struct wan_ioctl_notify_wan_state *state)
+{
+ if (!state)
+ return -EINVAL;
+
+ if (!ipa_pm_is_used())
+ return 0;
+
+ if (state->up)
+ return ipa_pm_activate_sync(rmnet_ipa3_ctx->q6_teth_pm_hdl);
+ else
+ return ipa_pm_deactivate_sync(rmnet_ipa3_ctx->q6_teth_pm_hdl);
+}
+
+/**
+ * ipa3_q6_register_pm - Register modem clients for PM
+ *
+ * This function will register 2 client with IPA PM to represent modem
+ * in clock scaling calculation:
+ * - "EMB MODEM" - this client will be activated with embedded traffic
+ - "TETH MODEM" - this client we be activated by IPACM on offload to
+ modem.
+*/
+static int ipa3_q6_register_pm(void)
+{
+ int result;
+ struct ipa_pm_register_params pm_reg;
+
+ memset(&pm_reg, 0, sizeof(pm_reg));
+ pm_reg.name = "EMB MODEM";
+ pm_reg.group = IPA_PM_GROUP_MODEM;
+ pm_reg.skip_clk_vote = true;
+ result = ipa_pm_register(&pm_reg, &rmnet_ipa3_ctx->q6_pm_hdl);
+ if (result) {
+ IPAERR("failed to create IPA PM client %d\n", result);
+ return result;
+ }
+
+ pm_reg.name = "TETH MODEM";
+ pm_reg.group = IPA_PM_GROUP_MODEM;
+ pm_reg.skip_clk_vote = true;
+ result = ipa_pm_register(&pm_reg, &rmnet_ipa3_ctx->q6_teth_pm_hdl);
+ if (result) {
+ IPAERR("failed to create IPA PM client %d\n", result);
+ return result;
+ }
+
+ return 0;
+}
+
+static void ipa3_q6_deregister_pm(void)
+{
+ ipa_pm_deactivate_sync(rmnet_ipa3_ctx->q6_pm_hdl);
+ ipa_pm_deregister(rmnet_ipa3_ctx->q6_pm_hdl);
+}
+
+int ipa3_wwan_set_modem_perf_profile(int throughput)
+{
+ struct ipa_rm_perf_profile profile;
+ int ret;
+
+ ret = ipa_pm_set_perf_profile(rmnet_ipa3_ctx->q6_pm_hdl, throughput);
+ if (ret)
+ return ret;
+ return ipa_pm_set_perf_profile(rmnet_ipa3_ctx->q6_teth_pm_hdl,
+ throughput);
+
+ if (ipa3_ctx->use_ipa_pm) {
+ ret = ipa_pm_set_perf_profile(rmnet_ipa3_ctx->q6_pm_hdl,
+ throughput);
+ if (ret)
+ return ret;
+ ret = ipa_pm_set_perf_profile(rmnet_ipa3_ctx->q6_teth_pm_hdl,
+ throughput);
+ } else {
+ memset(&profile, 0, sizeof(profile));
+ profile.max_supported_bandwidth_mbps = throughput;
+ ret = ipa_rm_set_perf_profile(IPA_RM_RESOURCE_Q6_PROD,
+ &profile);
+ }
+
+ return ret;
+}
+
static int ipa3_q6_initialize_rm(void)
{
struct ipa_rm_create_params create_params;
@@ -2075,6 +2181,120 @@
schedule_work(&ipa3_scheduled_probe);
}
+static void ipa_pm_wwan_pm_cb(void *p, enum ipa_pm_cb_event event)
+{
+ struct net_device *dev = (struct net_device *)p;
+ struct ipa3_wwan_private *wwan_ptr = netdev_priv(dev);
+
+ IPAWANDBG_LOW("event %d\n", event);
+ switch (event) {
+ case IPA_PM_CLIENT_ACTIVATED:
+ if (wwan_ptr->device_status == WWAN_DEVICE_INACTIVE) {
+ complete_all(&wwan_ptr->resource_granted_completion);
+ break;
+ }
+ ipa3_rm_resource_granted(dev);
+ break;
+ default:
+ pr_err("%s: unknown event %d\n", __func__, event);
+ break;
+ }
+}
+
+static int ipa3_wwan_register_netdev_pm_client(struct net_device *dev)
+{
+ int result;
+ struct ipa_pm_register_params pm_reg;
+
+ memset(&pm_reg, 0, sizeof(pm_reg));
+ pm_reg.name = IPA_NETDEV()->name;
+ pm_reg.user_data = dev;
+ pm_reg.callback = ipa_pm_wwan_pm_cb;
+ pm_reg.group = IPA_PM_GROUP_APPS;
+ result = ipa_pm_register(&pm_reg, &rmnet_ipa3_ctx->pm_hdl);
+ if (result) {
+ IPAERR("failed to create IPA PM client %d\n", result);
+ return result;
+ }
+ return 0;
+}
+
+static void ipa3_wwan_deregister_netdev_pm_client(void)
+{
+ ipa_pm_deactivate_sync(rmnet_ipa3_ctx->pm_hdl);
+ ipa_pm_deregister(rmnet_ipa3_ctx->pm_hdl);
+}
+
+static int ipa3_wwan_create_wwan_rm_resource(struct net_device *dev)
+{
+ struct ipa_rm_create_params ipa_rm_params;
+ struct ipa_rm_perf_profile profile;
+ int ret;
+
+ memset(&ipa_rm_params, 0, sizeof(struct ipa_rm_create_params));
+ ipa_rm_params.name = IPA_RM_RESOURCE_WWAN_0_PROD;
+ ipa_rm_params.reg_params.user_data = dev;
+ ipa_rm_params.reg_params.notify_cb = ipa3_rm_notify;
+ ret = ipa_rm_create_resource(&ipa_rm_params);
+ if (ret) {
+ pr_err("%s: unable to create resourse %d in IPA RM\n",
+ __func__, IPA_RM_RESOURCE_WWAN_0_PROD);
+ return ret;
+ }
+ ret = ipa_rm_inactivity_timer_init(IPA_RM_RESOURCE_WWAN_0_PROD,
+ IPA_RM_INACTIVITY_TIMER);
+ if (ret) {
+ pr_err("%s: ipa rm timer init failed %d on resourse %d\n",
+ __func__, ret, IPA_RM_RESOURCE_WWAN_0_PROD);
+ goto timer_init_err;
+ }
+ /* add dependency */
+ ret = ipa_rm_add_dependency(IPA_RM_RESOURCE_WWAN_0_PROD,
+ IPA_RM_RESOURCE_Q6_CONS);
+ if (ret)
+ goto add_dpnd_err;
+ /* setup Performance profile */
+ memset(&profile, 0, sizeof(profile));
+ profile.max_supported_bandwidth_mbps = IPA_APPS_MAX_BW_IN_MBPS;
+ ret = ipa_rm_set_perf_profile(IPA_RM_RESOURCE_WWAN_0_PROD,
+ &profile);
+ if (ret)
+ goto set_perf_err;
+
+ return 0;
+
+set_perf_err:
+ ipa_rm_delete_dependency(IPA_RM_RESOURCE_WWAN_0_PROD,
+ IPA_RM_RESOURCE_Q6_CONS);
+add_dpnd_err:
+ ipa_rm_inactivity_timer_destroy(
+ IPA_RM_RESOURCE_WWAN_0_PROD); /* IPA_RM */
+timer_init_err:
+ ipa_rm_delete_resource(IPA_RM_RESOURCE_WWAN_0_PROD);
+ return ret;
+}
+
+static void ipa3_wwan_delete_wwan_rm_resource(void)
+{
+ int ret;
+
+ ret = ipa_rm_delete_dependency(IPA_RM_RESOURCE_WWAN_0_PROD,
+ IPA_RM_RESOURCE_Q6_CONS);
+ if (ret < 0)
+ IPAWANERR("Error deleting dependency %d->%d, ret=%d\n",
+ IPA_RM_RESOURCE_WWAN_0_PROD, IPA_RM_RESOURCE_Q6_CONS,
+ ret);
+ ret = ipa_rm_inactivity_timer_destroy(IPA_RM_RESOURCE_WWAN_0_PROD);
+ if (ret < 0)
+ IPAWANERR(
+ "Error ipa_rm_inactivity_timer_destroy resource %d, ret=%d\n",
+ IPA_RM_RESOURCE_WWAN_0_PROD, ret);
+ ret = ipa_rm_delete_resource(IPA_RM_RESOURCE_WWAN_0_PROD);
+ if (ret < 0)
+ IPAWANERR("Error deleting resource %d, ret=%d\n",
+ IPA_RM_RESOURCE_WWAN_0_PROD, ret);
+}
+
/**
* ipa3_wwan_probe() - Initialized the module and registers as a
* network interface to the network stack
@@ -2092,8 +2312,6 @@
{
int ret, i;
struct net_device *dev;
- struct ipa_rm_create_params ipa_rm_params; /* IPA_RM */
- struct ipa_rm_perf_profile profile; /* IPA_RM */
pr_info("rmnet_ipa3 started initialization\n");
@@ -2187,7 +2405,10 @@
if (!atomic_read(&rmnet_ipa3_ctx->is_ssr)) {
/* IPA_RM configuration starts */
- ret = ipa3_q6_initialize_rm();
+ if (ipa3_ctx->use_ipa_pm)
+ ret = ipa3_q6_register_pm();
+ else
+ ret = ipa3_q6_initialize_rm();
if (ret) {
IPAWANERR("%s: ipa3_q6_initialize_rm failed, ret: %d\n",
__func__, ret);
@@ -2195,36 +2416,14 @@
}
}
- memset(&ipa_rm_params, 0, sizeof(struct ipa_rm_create_params));
- ipa_rm_params.name = IPA_RM_RESOURCE_WWAN_0_PROD;
- ipa_rm_params.reg_params.user_data = dev;
- ipa_rm_params.reg_params.notify_cb = ipa3_rm_notify;
- ret = ipa_rm_create_resource(&ipa_rm_params);
+ if (ipa3_ctx->use_ipa_pm)
+ ret = ipa3_wwan_register_netdev_pm_client(dev);
+ else
+ ret = ipa3_wwan_create_wwan_rm_resource(dev);
if (ret) {
- pr_err("%s: unable to create resourse %d in IPA RM\n",
- __func__, IPA_RM_RESOURCE_WWAN_0_PROD);
- goto create_rsrc_err;
+ IPAWANERR("fail to create/register pm resources\n");
+ goto fail_pm;
}
- ret = ipa_rm_inactivity_timer_init(IPA_RM_RESOURCE_WWAN_0_PROD,
- IPA_RM_INACTIVITY_TIMER);
- if (ret) {
- pr_err("%s: ipa rm timer init failed %d on resourse %d\n",
- __func__, ret, IPA_RM_RESOURCE_WWAN_0_PROD);
- goto timer_init_err;
- }
- /* add dependency */
- ret = ipa_rm_add_dependency(IPA_RM_RESOURCE_WWAN_0_PROD,
- IPA_RM_RESOURCE_Q6_CONS);
- if (ret)
- goto add_dpnd_err;
- /* setup Performance profile */
- memset(&profile, 0, sizeof(profile));
- profile.max_supported_bandwidth_mbps = IPA_APPS_MAX_BW_IN_MBPS;
- ret = ipa_rm_set_perf_profile(IPA_RM_RESOURCE_WWAN_0_PROD,
- &profile);
- if (ret)
- goto set_perf_err;
- /* IPA_RM configuration ends */
/* Enable SG support in netdevice. */
if (ipa3_rmnet_res.ipa_advertise_sg_support)
@@ -2260,28 +2459,18 @@
netif_napi_del(&(rmnet_ipa3_ctx->wwan_priv->napi));
unregister_netdev(dev);
set_perf_err:
- ret = ipa_rm_delete_dependency(IPA_RM_RESOURCE_WWAN_0_PROD,
- IPA_RM_RESOURCE_Q6_CONS);
- if (ret)
- IPAWANERR("Error deleting dependency %d->%d, ret=%d\n",
- IPA_RM_RESOURCE_WWAN_0_PROD, IPA_RM_RESOURCE_Q6_CONS,
- ret);
-add_dpnd_err:
- ret = ipa_rm_inactivity_timer_destroy(
- IPA_RM_RESOURCE_WWAN_0_PROD); /* IPA_RM */
- if (ret)
- IPAWANERR("Error ipa_rm_inactivity_timer_destroy %d, ret=%d\n",
- IPA_RM_RESOURCE_WWAN_0_PROD, ret);
-timer_init_err:
- ret = ipa_rm_delete_resource(IPA_RM_RESOURCE_WWAN_0_PROD);
- if (ret)
- IPAWANERR("Error deleting resource %d, ret=%d\n",
- IPA_RM_RESOURCE_WWAN_0_PROD, ret);
-create_rsrc_err:
-
- if (!atomic_read(&rmnet_ipa3_ctx->is_ssr))
- ipa3_q6_deinitialize_rm();
-
+ if (ipa3_ctx->use_ipa_pm)
+ ipa3_wwan_deregister_netdev_pm_client();
+ else
+ ipa3_wwan_delete_wwan_rm_resource();
+fail_pm:
+ if (ipa3_ctx->use_ipa_pm) {
+ if (!atomic_read(&rmnet_ipa3_ctx->is_ssr))
+ ipa3_q6_deregister_pm();
+ } else {
+ if (!atomic_read(&rmnet_ipa3_ctx->is_ssr))
+ ipa3_q6_deinitialize_rm();
+ }
q6_init_err:
free_netdev(dev);
rmnet_ipa3_ctx->wwan_priv = NULL;
@@ -2317,21 +2506,10 @@
netif_napi_del(&(rmnet_ipa3_ctx->wwan_priv->napi));
mutex_unlock(&rmnet_ipa3_ctx->pipe_handle_guard);
unregister_netdev(IPA_NETDEV());
- ret = ipa_rm_delete_dependency(IPA_RM_RESOURCE_WWAN_0_PROD,
- IPA_RM_RESOURCE_Q6_CONS);
- if (ret < 0)
- IPAWANERR("Error deleting dependency %d->%d, ret=%d\n",
- IPA_RM_RESOURCE_WWAN_0_PROD, IPA_RM_RESOURCE_Q6_CONS,
- ret);
- ret = ipa_rm_inactivity_timer_destroy(IPA_RM_RESOURCE_WWAN_0_PROD);
- if (ret < 0)
- IPAWANERR(
- "Error ipa_rm_inactivity_timer_destroy resource %d, ret=%d\n",
- IPA_RM_RESOURCE_WWAN_0_PROD, ret);
- ret = ipa_rm_delete_resource(IPA_RM_RESOURCE_WWAN_0_PROD);
- if (ret < 0)
- IPAWANERR("Error deleting resource %d, ret=%d\n",
- IPA_RM_RESOURCE_WWAN_0_PROD, ret);
+ if (ipa3_ctx->use_ipa_pm)
+ ipa3_wwan_deregister_netdev_pm_client();
+ else
+ ipa3_wwan_delete_wwan_rm_resource();
cancel_work_sync(&ipa3_tx_wakequeue_work);
cancel_delayed_work(&ipa_tether_stats_poll_wakequeue_work);
if (IPA_NETDEV())
@@ -2385,23 +2563,26 @@
if (wwan_ptr == NULL) {
IPAWANERR("wwan_ptr is NULL.\n");
ret = 0;
- goto unlock_and_bail;
+ netif_tx_unlock_bh(netdev);
+ goto bail;
}
/* Do not allow A7 to suspend in case there are oustanding packets */
if (atomic_read(&wwan_ptr->outstanding_pkts) != 0) {
IPAWANDBG("Outstanding packets, postponing AP suspend.\n");
ret = -EAGAIN;
- goto unlock_and_bail;
+ netif_tx_unlock_bh(netdev);
+ goto bail;
}
/* Make sure that there is no Tx operation ongoing */
netif_stop_queue(netdev);
- ipa_rm_release_resource(IPA_RM_RESOURCE_WWAN_0_PROD);
- ret = 0;
-
-unlock_and_bail:
netif_tx_unlock_bh(netdev);
+ if (ipa3_ctx->use_ipa_pm)
+ ipa_pm_deactivate_sync(rmnet_ipa3_ctx->pm_hdl);
+ else
+ ipa_rm_release_resource(IPA_RM_RESOURCE_WWAN_0_PROD);
+ ret = 0;
bail:
IPAWANDBG("Exit with %d\n", ret);
return ret;
diff --git a/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa_fd_ioctl.c b/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa_fd_ioctl.c
index c7a6186..2e43abf 100644
--- a/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa_fd_ioctl.c
+++ b/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa_fd_ioctl.c
@@ -50,6 +50,9 @@
#define WAN_IOC_QUERY_TETHER_STATS_ALL32 _IOWR(WAN_IOC_MAGIC, \
WAN_IOCTL_QUERY_TETHER_STATS_ALL, \
compat_uptr_t)
+#define WAN_IOC_NOTIFY_WAN_STATE32 _IOWR(WAN_IOC_MAGIC, \
+ WAN_IOCTL_NOTIFY_WAN_STATE, \
+ compat_uptr_t)
#endif
static unsigned int dev_num = 1;
@@ -316,6 +319,27 @@
}
break;
+ case WAN_IOC_NOTIFY_WAN_STATE:
+ IPAWANDBG_LOW("device %s got WAN_IOC_NOTIFY_WAN_STATE :>>>\n",
+ DRIVER_NAME);
+ pyld_sz = sizeof(struct wan_ioctl_notify_wan_state);
+ param = kzalloc(pyld_sz, GFP_KERNEL);
+ if (!param) {
+ retval = -ENOMEM;
+ break;
+ }
+ if (copy_from_user(param, (u8 __user *)arg, pyld_sz)) {
+ retval = -EFAULT;
+ break;
+ }
+
+ if (ipa3_wwan_set_modem_state(
+ (struct wan_ioctl_notify_wan_state *)param)) {
+ IPAWANERR("WAN_IOC_NOTIFY_WAN_STATE failed\n");
+ retval = -EFAULT;
+ break;
+ }
+ break;
default:
retval = -ENOTTY;
}
diff --git a/drivers/platform/msm/ipa/ipa_v3/teth_bridge.c b/drivers/platform/msm/ipa/ipa_v3/teth_bridge.c
index 297f932..7496f28 100644
--- a/drivers/platform/msm/ipa/ipa_v3/teth_bridge.c
+++ b/drivers/platform/msm/ipa/ipa_v3/teth_bridge.c
@@ -50,6 +50,7 @@
dev_t dev_num;
struct device *dev;
struct cdev cdev;
+ u32 modem_pm_hdl;
};
static struct ipa3_teth_bridge_ctx *ipa3_teth_ctx;
@@ -118,14 +119,25 @@
*/
int ipa3_teth_bridge_disconnect(enum ipa_client_type client)
{
+ int res = 0;
+
TETH_DBG_FUNC_ENTRY();
- ipa_rm_delete_dependency(IPA_RM_RESOURCE_USB_PROD,
- IPA_RM_RESOURCE_Q6_CONS);
- ipa_rm_delete_dependency(IPA_RM_RESOURCE_Q6_PROD,
- IPA_RM_RESOURCE_USB_CONS);
+ if (ipa_pm_is_used()) {
+ res = ipa_pm_deactivate_sync(ipa3_teth_ctx->modem_pm_hdl);
+ if (res) {
+ TETH_ERR("fail to deactivate modem %d\n", res);
+ return res;
+ }
+ res = ipa_pm_destroy();
+ } else {
+ ipa_rm_delete_dependency(IPA_RM_RESOURCE_USB_PROD,
+ IPA_RM_RESOURCE_Q6_CONS);
+ ipa_rm_delete_dependency(IPA_RM_RESOURCE_Q6_PROD,
+ IPA_RM_RESOURCE_USB_CONS);
+ }
TETH_DBG_FUNC_EXIT();
- return 0;
+ return res;
}
/**
@@ -140,9 +152,27 @@
int ipa3_teth_bridge_connect(struct teth_bridge_connect_params *connect_params)
{
int res = 0;
+ struct ipa_pm_register_params reg_params;
+
+ memset(®_params, 0, sizeof(reg_params));
TETH_DBG_FUNC_ENTRY();
+ if (ipa_pm_is_used()) {
+ reg_params.name = "MODEM (USB RMNET)";
+ reg_params.group = IPA_PM_GROUP_MODEM;
+ reg_params.skip_clk_vote = true;
+ res = ipa_pm_register(®_params,
+ &ipa3_teth_ctx->modem_pm_hdl);
+ if (res) {
+ TETH_ERR("fail to register with PM %d\n", res);
+ return res;
+ }
+
+ res = ipa_pm_activate_sync(ipa3_teth_ctx->modem_pm_hdl);
+ goto bail;
+ }
+
/* Build the dependency graph, first add_dependency call is sync
* in order to make sure the IPA clocks are up before we continue
* and notify the USB driver it may continue.
@@ -234,6 +264,8 @@
res = -ENODEV;
goto fail_cdev_add;
}
+
+ ipa3_teth_ctx->modem_pm_hdl = ~0;
TETH_DBG("Tethering bridge driver init OK\n");
return 0;
diff --git a/drivers/platform/msm/qcom-geni-se.c b/drivers/platform/msm/qcom-geni-se.c
index aafb8fc..707c95e 100644
--- a/drivers/platform/msm/qcom-geni-se.c
+++ b/drivers/platform/msm/qcom-geni-se.c
@@ -1247,6 +1247,79 @@
}
EXPORT_SYMBOL(geni_se_iommu_free_buf);
+/**
+ * geni_se_dump_dbg_regs() - Print relevant registers that capture most
+ * accurately the state of an SE.
+ * @_dev: Pointer to the SE's device.
+ * @iomem: Base address of the SE's register space.
+ * @ipc: IPC log context handle.
+ *
+ * This function is used to print out all the registers that capture the state
+ * of an SE to help debug any errors.
+ *
+ * Return: None
+ */
+void geni_se_dump_dbg_regs(struct se_geni_rsc *rsc, void __iomem *base,
+ void *ipc)
+{
+ u32 m_cmd0 = 0;
+ u32 m_irq_status = 0;
+ u32 geni_status = 0;
+ u32 geni_ios = 0;
+ u32 dma_rx_irq = 0;
+ u32 dma_tx_irq = 0;
+ u32 rx_fifo_status = 0;
+ u32 tx_fifo_status = 0;
+ u32 se_dma_dbg = 0;
+ u32 m_cmd_ctrl = 0;
+ u32 se_dma_rx_len = 0;
+ u32 se_dma_rx_len_in = 0;
+ u32 se_dma_tx_len = 0;
+ u32 se_dma_tx_len_in = 0;
+ struct geni_se_device *geni_se_dev;
+
+ if (!ipc)
+ return;
+
+ geni_se_dev = dev_get_drvdata(rsc->wrapper_dev);
+ if (unlikely(!geni_se_dev || !geni_se_dev->bus_bw))
+ return;
+ mutex_lock(&geni_se_dev->ab_ib_lock);
+ if (unlikely(list_empty(&rsc->ab_list) || list_empty(&rsc->ib_list))) {
+ GENI_SE_DBG(ipc, false, NULL, "%s: Clocks not on\n", __func__);
+ goto exit_geni_se_dump_dbg_regs;
+ }
+ m_cmd0 = geni_read_reg(base, SE_GENI_M_CMD0);
+ m_irq_status = geni_read_reg(base, SE_GENI_M_IRQ_STATUS);
+ geni_status = geni_read_reg(base, SE_GENI_STATUS);
+ geni_ios = geni_read_reg(base, SE_GENI_IOS);
+ dma_rx_irq = geni_read_reg(base, SE_DMA_TX_IRQ_STAT);
+ dma_tx_irq = geni_read_reg(base, SE_DMA_RX_IRQ_STAT);
+ rx_fifo_status = geni_read_reg(base, SE_GENI_RX_FIFO_STATUS);
+ tx_fifo_status = geni_read_reg(base, SE_GENI_TX_FIFO_STATUS);
+ se_dma_dbg = geni_read_reg(base, SE_DMA_DEBUG_REG0);
+ m_cmd_ctrl = geni_read_reg(base, SE_GENI_M_CMD_CTRL_REG);
+ se_dma_rx_len = geni_read_reg(base, SE_DMA_RX_LEN);
+ se_dma_rx_len_in = geni_read_reg(base, SE_DMA_RX_LEN_IN);
+ se_dma_tx_len = geni_read_reg(base, SE_DMA_TX_LEN);
+ se_dma_tx_len_in = geni_read_reg(base, SE_DMA_TX_LEN_IN);
+
+ GENI_SE_DBG(ipc, false, NULL,
+ "%s: m_cmd0:0x%x, m_irq_status:0x%x, geni_status:0x%x, geni_ios:0x%x\n",
+ __func__, m_cmd0, m_irq_status, geni_status, geni_ios);
+ GENI_SE_DBG(ipc, false, NULL,
+ "dma_rx_irq:0x%x, dma_tx_irq:0x%x, rx_fifo_sts:0x%x, tx_fifo_sts:0x%x\n"
+ , dma_rx_irq, dma_tx_irq, rx_fifo_status, tx_fifo_status);
+ GENI_SE_DBG(ipc, false, NULL,
+ "se_dma_dbg:0x%x, m_cmd_ctrl:0x%x, dma_rxlen:0x%x, dma_rxlen_in:0x%x\n",
+ se_dma_dbg, m_cmd_ctrl, se_dma_rx_len, se_dma_rx_len_in);
+ GENI_SE_DBG(ipc, false, NULL,
+ "dma_txlen:0x%x, dma_txlen_in:0x%x\n", se_dma_tx_len, se_dma_tx_len_in);
+exit_geni_se_dump_dbg_regs:
+ mutex_unlock(&geni_se_dev->ab_ib_lock);
+}
+EXPORT_SYMBOL(geni_se_dump_dbg_regs);
+
static const struct of_device_id geni_se_dt_match[] = {
{ .compatible = "qcom,qupv3-geni-se", },
{ .compatible = "qcom,qupv3-geni-se-cb", },
diff --git a/drivers/power/supply/qcom/battery.c b/drivers/power/supply/qcom/battery.c
index 7f6d346..f6e81d8 100644
--- a/drivers/power/supply/qcom/battery.c
+++ b/drivers/power/supply/qcom/battery.c
@@ -348,7 +348,7 @@
}
#define MINIMUM_PARALLEL_FCC_UA 500000
-#define PL_TAPER_WORK_DELAY_MS 100
+#define PL_TAPER_WORK_DELAY_MS 500
#define TAPER_RESIDUAL_PCT 90
static void pl_taper_work(struct work_struct *work)
{
diff --git a/drivers/power/supply/qcom/smb-lib.c b/drivers/power/supply/qcom/smb-lib.c
index 1b890d5..60f4df8 100644
--- a/drivers/power/supply/qcom/smb-lib.c
+++ b/drivers/power/supply/qcom/smb-lib.c
@@ -2250,12 +2250,6 @@
int smblib_get_prop_usb_voltage_now(struct smb_charger *chg,
union power_supply_propval *val)
{
- int rc = 0;
-
- rc = smblib_get_prop_usb_present(chg, val);
- if (rc < 0 || !val->intval)
- return rc;
-
if (!chg->iio.usbin_v_chan ||
PTR_ERR(chg->iio.usbin_v_chan) == -EPROBE_DEFER)
chg->iio.usbin_v_chan = iio_channel_get(chg->dev, "usbin_v");
diff --git a/drivers/pwm/pwm-qpnp.c b/drivers/pwm/pwm-qpnp.c
index 86f08d2..e7267de 100644
--- a/drivers/pwm/pwm-qpnp.c
+++ b/drivers/pwm/pwm-qpnp.c
@@ -317,6 +317,7 @@
struct pwm_period_config period;
int supported_sizes;
int force_pwm_size;
+ bool update_period;
};
/* Public facing structure */
@@ -327,6 +328,7 @@
bool enabled;
struct _qpnp_pwm_config pwm_config;
struct qpnp_lpg_config lpg_config;
+ enum pm_pwm_mode pwm_mode;
spinlock_t lpg_lock;
enum qpnp_lpg_revision revision;
u8 sub_type;
@@ -1211,28 +1213,32 @@
rc = qpnp_lpg_save_pwm_value(chip);
if (rc)
goto out;
- rc = qpnp_lpg_configure_pwm(chip);
- if (rc)
- goto out;
- rc = qpnp_configure_pwm_control(chip);
- if (rc)
- goto out;
- if (!rc && chip->enabled) {
- rc = qpnp_lpg_configure_pwm_state(chip, QPNP_PWM_ENABLE);
- if (rc) {
- pr_err("Error in configuring pwm state, rc=%d\n", rc);
- return rc;
- }
+ if (pwm_config->update_period) {
+ rc = qpnp_lpg_configure_pwm(chip);
+ if (rc)
+ goto out;
+ rc = qpnp_configure_pwm_control(chip);
+ if (rc)
+ goto out;
+ if (!rc && chip->enabled) {
+ rc = qpnp_lpg_configure_pwm_state(chip,
+ QPNP_PWM_ENABLE);
+ if (rc) {
+ pr_err("Error in configuring pwm state, rc=%d\n",
+ rc);
+ return rc;
+ }
- /* Enable the glitch removal after PWM is enabled */
- rc = qpnp_lpg_glitch_removal(chip, true);
- if (rc) {
- pr_err("Error in enabling glitch control, rc=%d\n", rc);
- return rc;
+ /* Enable the glitch removal after PWM is enabled */
+ rc = qpnp_lpg_glitch_removal(chip, true);
+ if (rc) {
+ pr_err("Error in enabling glitch control, rc=%d\n",
+ rc);
+ return rc;
+ }
}
}
-
pr_debug("duty/period=%u/%u %s: pwm_value=%d (of %d)\n",
(unsigned int)duty_value, (unsigned int)period_value,
(tm_lvl == LVL_USEC) ? "usec" : "nsec",
@@ -1309,12 +1315,10 @@
return rc;
}
+/* lpg_lock should be held while calling _pwm_enable() */
static int _pwm_enable(struct qpnp_pwm_chip *chip)
{
int rc = 0;
- unsigned long flags;
-
- spin_lock_irqsave(&chip->lpg_lock, flags);
if (QPNP_IS_PWM_CONFIG_SELECTED(
chip->qpnp_lpg_registers[QPNP_ENABLE_CONTROL]) ||
@@ -1327,8 +1331,21 @@
if (!rc)
chip->enabled = true;
- spin_unlock_irqrestore(&chip->lpg_lock, flags);
+ return rc;
+}
+/* lpg_lock should be held while calling _pwm_change_mode() */
+static int _pwm_change_mode(struct qpnp_pwm_chip *chip, enum pm_pwm_mode mode)
+{
+ int rc;
+
+ if (mode == PM_PWM_MODE_LPG)
+ rc = qpnp_configure_lpg_control(chip);
+ else
+ rc = qpnp_configure_pwm_control(chip);
+
+ if (rc)
+ pr_err("Failed to change the mode\n");
return rc;
}
@@ -1375,12 +1392,14 @@
spin_lock_irqsave(&chip->lpg_lock, flags);
+ chip->pwm_config.update_period = false;
if (prev_period_us > INT_MAX / NSEC_PER_USEC ||
prev_period_us * NSEC_PER_USEC != period_ns) {
qpnp_lpg_calc_period(LVL_NSEC, period_ns, chip);
qpnp_lpg_save_period(chip);
pwm->state.period = period_ns;
chip->pwm_config.pwm_period = period_ns / NSEC_PER_USEC;
+ chip->pwm_config.update_period = true;
}
rc = _pwm_config(chip, LVL_NSEC, duty_ns, period_ns);
@@ -1403,11 +1422,15 @@
{
int rc;
struct qpnp_pwm_chip *chip = qpnp_pwm_from_pwm_chip(pwm_chip);
+ unsigned long flags;
+ spin_lock_irqsave(&chip->lpg_lock, flags);
rc = _pwm_enable(chip);
if (rc)
pr_err("Failed to enable PWM channel: %d\n", chip->channel_id);
+ spin_unlock_irqrestore(&chip->lpg_lock, flags);
+
return rc;
}
@@ -1445,20 +1468,6 @@
chip->channel_id);
}
-static int _pwm_change_mode(struct qpnp_pwm_chip *chip, enum pm_pwm_mode mode)
-{
- int rc;
-
- if (mode)
- rc = qpnp_configure_lpg_control(chip);
- else
- rc = qpnp_configure_pwm_control(chip);
-
- if (rc)
- pr_err("Failed to change the mode\n");
- return rc;
-}
-
/**
* pwm_change_mode - Change the PWM mode configuration
* @pwm: the PWM device
@@ -1466,7 +1475,7 @@
*/
int pwm_change_mode(struct pwm_device *pwm, enum pm_pwm_mode mode)
{
- int rc;
+ int rc = 0;
unsigned long flags;
struct qpnp_pwm_chip *chip;
@@ -1483,7 +1492,22 @@
chip = qpnp_pwm_from_pwm_dev(pwm);
spin_lock_irqsave(&chip->lpg_lock, flags);
- rc = _pwm_change_mode(chip, mode);
+ if (chip->pwm_mode != mode) {
+ rc = _pwm_change_mode(chip, mode);
+ if (rc) {
+ pr_err("Failed to change mode: %d, rc=%d\n", mode, rc);
+ goto unlock;
+ }
+ chip->pwm_mode = mode;
+ if (chip->enabled) {
+ rc = _pwm_enable(chip);
+ if (rc) {
+ pr_err("Failed to enable PWM, rc=%d\n", rc);
+ goto unlock;
+ }
+ }
+ }
+unlock:
spin_unlock_irqrestore(&chip->lpg_lock, flags);
return rc;
@@ -1619,6 +1643,7 @@
spin_lock_irqsave(&chip->lpg_lock, flags);
+ chip->pwm_config.update_period = false;
if (chip->pwm_config.pwm_period != period_us) {
qpnp_lpg_calc_period(LVL_USEC, period_us, chip);
qpnp_lpg_save_period(chip);
@@ -1629,6 +1654,7 @@
else
pwm->state.period
= (unsigned int)period_us * NSEC_PER_USEC;
+ chip->pwm_config.update_period = true;
}
rc = _pwm_config(chip, LVL_USEC, duty_us, period_us);
@@ -1735,6 +1761,7 @@
qpnp_lpg_calc_period(LVL_USEC, period, chip);
qpnp_lpg_save_period(chip);
chip->pwm_config.pwm_period = period;
+ chip->pwm_config.update_period = true;
rc = _pwm_config(chip, LVL_USEC, chip->pwm_config.pwm_duty, period);
@@ -1885,7 +1912,7 @@
static int qpnp_parse_dt_config(struct platform_device *pdev,
struct qpnp_pwm_chip *chip)
{
- int rc, enable, lut_entry_size, list_size, i;
+ int rc, mode, lut_entry_size, list_size, i;
const char *label;
const __be32 *prop;
u32 size;
@@ -2069,18 +2096,20 @@
}
}
- rc = of_property_read_u32(of_node, "qcom,mode-select", &enable);
+ rc = of_property_read_u32(of_node, "qcom,mode-select", &mode);
if (rc)
goto read_opt_props;
- if ((enable == PM_PWM_MODE_PWM && found_pwm_subnode == 0) ||
- (enable == PM_PWM_MODE_LPG && found_lpg_subnode == 0)) {
+ if (mode > PM_PWM_MODE_LPG ||
+ (mode == PM_PWM_MODE_PWM && found_pwm_subnode == 0) ||
+ (mode == PM_PWM_MODE_LPG && found_lpg_subnode == 0)) {
dev_err(&pdev->dev, "%s: Invalid mode select\n", __func__);
rc = -EINVAL;
goto out;
}
- _pwm_change_mode(chip, enable);
+ chip->pwm_mode = mode;
+ _pwm_change_mode(chip, mode);
_pwm_enable(chip);
read_opt_props:
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index ecc6aad..c5118b4 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -1248,6 +1248,7 @@
unsigned long req_sz, len, sa;
Sg_scatter_hold *rsv_schp;
int k, length;
+ int ret = 0;
if ((!filp) || (!vma) || (!(sfp = (Sg_fd *) filp->private_data)))
return -ENXIO;
@@ -1258,8 +1259,11 @@
if (vma->vm_pgoff)
return -EINVAL; /* want no offset */
rsv_schp = &sfp->reserve;
- if (req_sz > rsv_schp->bufflen)
- return -ENOMEM; /* cannot map more than reserved buffer */
+ mutex_lock(&sfp->f_mutex);
+ if (req_sz > rsv_schp->bufflen) {
+ ret = -ENOMEM; /* cannot map more than reserved buffer */
+ goto out;
+ }
sa = vma->vm_start;
length = 1 << (PAGE_SHIFT + rsv_schp->page_order);
@@ -1273,7 +1277,9 @@
vma->vm_flags |= VM_IO | VM_DONTEXPAND | VM_DONTDUMP;
vma->vm_private_data = sfp;
vma->vm_ops = &sg_mmap_vm_ops;
- return 0;
+out:
+ mutex_unlock(&sfp->f_mutex);
+ return ret;
}
static void
@@ -1742,9 +1748,12 @@
!sfp->res_in_use) {
sfp->res_in_use = 1;
sg_link_reserve(sfp, srp, dxfer_len);
- } else if ((hp->flags & SG_FLAG_MMAP_IO) && sfp->res_in_use) {
+ } else if (hp->flags & SG_FLAG_MMAP_IO) {
+ res = -EBUSY; /* sfp->res_in_use == 1 */
+ if (dxfer_len > rsv_schp->bufflen)
+ res = -ENOMEM;
mutex_unlock(&sfp->f_mutex);
- return -EBUSY;
+ return res;
} else {
res = sg_build_indirect(req_schp, sfp, dxfer_len);
if (res) {
diff --git a/drivers/scsi/ufs/ufs-debugfs.c b/drivers/scsi/ufs/ufs-debugfs.c
index 557ca19..11e11e4 100644
--- a/drivers/scsi/ufs/ufs-debugfs.c
+++ b/drivers/scsi/ufs/ufs-debugfs.c
@@ -950,6 +950,10 @@
seq_printf(file, "hba->saved_err = 0x%x\n", hba->saved_err);
seq_printf(file, "hba->saved_uic_err = 0x%x\n", hba->saved_uic_err);
+ seq_printf(file, "power_mode_change_cnt = %d\n",
+ hba->ufs_stats.power_mode_change_cnt);
+ seq_printf(file, "hibern8_exit_cnt = %d\n",
+ hba->ufs_stats.hibern8_exit_cnt);
return 0;
}
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index e1e9402..b6ba4c4 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -4875,6 +4875,7 @@
memcpy(&hba->pwr_info, pwr_mode,
sizeof(struct ufs_pa_layer_attr));
+ hba->ufs_stats.power_mode_change_cnt++;
}
return ret;
@@ -7170,6 +7171,12 @@
} while (err && --retries);
/*
+ * There is no point proceeding even after failing
+ * to recover after multiple retries.
+ */
+ if (err && ufshcd_is_embedded_dev(hba))
+ BUG();
+ /*
* After reset the door-bell might be cleared, complete
* outstanding requests in s/w here.
*/
@@ -7634,9 +7641,6 @@
{
int err_reg_hist_size = sizeof(struct ufs_uic_err_reg_hist);
- hba->ufs_stats.hibern8_exit_cnt = 0;
- hba->ufs_stats.last_hibern8_exit_tstamp = ktime_set(0, 0);
-
memset(&hba->ufs_stats.pa_err, 0, err_reg_hist_size);
memset(&hba->ufs_stats.dl_err, 0, err_reg_hist_size);
memset(&hba->ufs_stats.nl_err, 0, err_reg_hist_size);
diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
index fc855db..1b21238 100644
--- a/drivers/scsi/ufs/ufshcd.h
+++ b/drivers/scsi/ufs/ufshcd.h
@@ -644,6 +644,7 @@
struct ufshcd_clk_ctx clk_rel;
u32 hibern8_exit_cnt;
ktime_t last_hibern8_exit_tstamp;
+ u32 power_mode_change_cnt;
struct ufs_uic_err_reg_hist pa_err;
struct ufs_uic_err_reg_hist dl_err;
struct ufs_uic_err_reg_hist nl_err;
@@ -1198,6 +1199,14 @@
pwr_info->pwr_tx == FASTAUTO_MODE);
}
+static inline bool ufshcd_is_embedded_dev(struct ufs_hba *hba)
+{
+ if ((hba->dev_info.b_device_sub_class == UFS_DEV_EMBEDDED_BOOTABLE) ||
+ (hba->dev_info.b_device_sub_class == UFS_DEV_EMBEDDED_NON_BOOTABLE))
+ return true;
+ return false;
+}
+
#ifdef CONFIG_DEBUG_FS
static inline void ufshcd_init_req_stats(struct ufs_hba *hba)
{
diff --git a/drivers/slimbus/slimbus.c b/drivers/slimbus/slimbus.c
index 567f290..3ae9a10 100644
--- a/drivers/slimbus/slimbus.c
+++ b/drivers/slimbus/slimbus.c
@@ -2397,6 +2397,8 @@
bool opensl1valid = false;
int maxctrlw1, maxctrlw3, i;
+ /* intitalize array to zero */
+ memset(opensl1, 0x0, sizeof(opensl1));
finalexp = (ctrl->sched.chc3[last3])->rootexp;
if (last1 >= 0) {
slc1 = ctrl->sched.chc1[coeff1];
diff --git a/drivers/soc/qcom/llcc-sdm845.c b/drivers/soc/qcom/llcc-sdm845.c
index 3863b09..5234580 100644
--- a/drivers/soc/qcom/llcc-sdm845.c
+++ b/drivers/soc/qcom/llcc-sdm845.c
@@ -73,7 +73,7 @@
SCT_ENTRY("display", 16, 16, 2816, 1, 0, 0xFFC, 0x2, 0, 0, 1, 1, 0),
SCT_ENTRY("videofw", 17, 17, 2816, 1, 0, 0xFFC, 0x2, 0, 0, 1, 1, 0),
SCT_ENTRY("modemhp_fix", 20, 20, 1024, 2, 1, 0x0, 0xF00, 0, 0, 1, 1, 0),
- SCT_ENTRY("modem_paging", 21, 21, 1024, 0, 1, 0x0, 0xF, 0, 0, 1, 1, 0),
+ SCT_ENTRY("modem_paging", 21, 21, 1024, 0, 1, 0x1e, 0x0, 0, 0, 1, 1, 0),
SCT_ENTRY("audiohw", 22, 22, 1024, 1, 1, 0xFFC, 0x2, 0, 0, 1, 1, 0),
};
diff --git a/drivers/soc/qcom/msm_bus/msm_bus_bimc_rpmh.c b/drivers/soc/qcom/msm_bus/msm_bus_bimc_rpmh.c
index c1e8feb..dafae4c 100644
--- a/drivers/soc/qcom/msm_bus/msm_bus_bimc_rpmh.c
+++ b/drivers/soc/qcom/msm_bus/msm_bus_bimc_rpmh.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2017, 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
@@ -242,7 +242,7 @@
(M_BKE_GC_GC_BMSK >> \
(M_BKE_GC_GC_SHFT + 1))
-static int bimc_div(int64_t *a, uint32_t b)
+static int bimc_div(uint64_t *a, uint32_t b)
{
if ((*a > 0) && (*a < b)) {
*a = 0;
diff --git a/drivers/soc/qcom/msm_bus/msm_bus_fabric_rpmh.c b/drivers/soc/qcom/msm_bus/msm_bus_fabric_rpmh.c
index 077d8cd..5a110bb 100644
--- a/drivers/soc/qcom/msm_bus/msm_bus_fabric_rpmh.c
+++ b/drivers/soc/qcom/msm_bus/msm_bus_fabric_rpmh.c
@@ -566,6 +566,11 @@
bcm_clist_add(node);
}
+ if (!cur_rsc) {
+ MSM_BUS_ERR("%s: Error for cur_rsc is NULL.\n", __func__);
+ return ret;
+ }
+
cur_mbox = cur_rsc->rscdev->mbox;
cur_bcm_clist = cur_rsc->rscdev->bcm_clist;
diff --git a/drivers/soc/qcom/socinfo.c b/drivers/soc/qcom/socinfo.c
index 417b0b2..c35119c 100644
--- a/drivers/soc/qcom/socinfo.c
+++ b/drivers/soc/qcom/socinfo.c
@@ -572,6 +572,12 @@
/* SDM670 ID */
[336] = {MSM_CPU_SDM670, "SDM670"},
+ /* QCS605 ID */
+ [347] = {MSM_CPU_QCS605, "QCS605"},
+
+ /* SDA670 ID */
+ [337] = {MSM_CPU_SDA670, "SDA670"},
+
/* Uninitialized IDs are not known to run Linux.
* MSM_CPU_UNKNOWN is set to 0 to ensure these IDs are
* considered as unknown CPU.
@@ -1434,6 +1440,14 @@
dummy_socinfo.id = 336;
strlcpy(dummy_socinfo.build_id, "sdm670 - ",
sizeof(dummy_socinfo.build_id));
+ } else if (early_machine_is_sda670()) {
+ dummy_socinfo.id = 337;
+ strlcpy(dummy_socinfo.build_id, "sda670 - ",
+ sizeof(dummy_socinfo.build_id));
+ } else if (early_machine_is_qcs605()) {
+ dummy_socinfo.id = 347;
+ strlcpy(dummy_socinfo.build_id, "qcs605 - ",
+ sizeof(dummy_socinfo.build_id));
} else if (early_machine_is_sdxpoorwills()) {
dummy_socinfo.id = 334;
strlcpy(dummy_socinfo.build_id, "sdxpoorwills - ",
diff --git a/drivers/spi/spi-geni-qcom.c b/drivers/spi/spi-geni-qcom.c
index de3dc69..e46bc98 100644
--- a/drivers/spi/spi-geni-qcom.c
+++ b/drivers/spi/spi-geni-qcom.c
@@ -298,7 +298,7 @@
*/
if (fifo_disable && !dma_chan_valid)
mode = -EINVAL;
- else if (fifo_disable)
+ else if (dma_chan_valid)
mode = GSI_DMA;
else
mode = FIFO_MODE;
@@ -617,30 +617,32 @@
struct spi_message *msg)
{
struct spi_transfer *xfer;
- struct device *gsi_dev = mas->dev;
+ int ret = 0;
list_for_each_entry(xfer, &msg->transfers, transfer_list) {
if (xfer->rx_buf) {
- xfer->rx_dma = dma_map_single(gsi_dev, xfer->rx_buf,
+ ret = geni_se_iommu_map_buf(mas->wrapper_dev,
+ &xfer->rx_dma, xfer->rx_buf,
xfer->len, DMA_FROM_DEVICE);
- if (dma_mapping_error(mas->dev, xfer->rx_dma)) {
- dev_err(mas->dev, "Err mapping buf\n");
- return -ENOMEM;
+ if (ret) {
+ GENI_SE_ERR(mas->ipc, true, mas->dev,
+ "%s: Mapping Rx buffer %d\n", __func__, ret);
+ return ret;
}
}
if (xfer->tx_buf) {
- xfer->tx_dma = dma_map_single(gsi_dev,
- (void *)xfer->tx_buf, xfer->len, DMA_TO_DEVICE);
- if (dma_mapping_error(gsi_dev, xfer->tx_dma)) {
- dev_err(mas->dev, "Err mapping buf\n");
- dma_unmap_single(gsi_dev, xfer->rx_dma,
- xfer->len, DMA_FROM_DEVICE);
- return -ENOMEM;
+ ret = geni_se_iommu_map_buf(mas->wrapper_dev,
+ &xfer->tx_dma,
+ (void *)xfer->tx_buf,
+ xfer->len, DMA_TO_DEVICE);
+ if (ret) {
+ GENI_SE_ERR(mas->ipc, true, mas->dev,
+ "%s: Mapping Tx buffer %d\n", __func__, ret);
+ return ret;
}
}
};
-
return 0;
}
@@ -648,14 +650,13 @@
struct spi_message *msg)
{
struct spi_transfer *xfer;
- struct device *gsi_dev = mas->dev;
list_for_each_entry(xfer, &msg->transfers, transfer_list) {
if (xfer->rx_buf)
- dma_unmap_single(gsi_dev, xfer->rx_dma,
+ geni_se_iommu_unmap_buf(mas->wrapper_dev, &xfer->rx_dma,
xfer->len, DMA_FROM_DEVICE);
if (xfer->tx_buf)
- dma_unmap_single(gsi_dev, xfer->tx_dma,
+ geni_se_iommu_unmap_buf(mas->wrapper_dev, &xfer->tx_dma,
xfer->len, DMA_TO_DEVICE);
};
}
@@ -709,7 +710,12 @@
{
struct spi_geni_master *mas = spi_master_get_devdata(spi);
int ret = 0;
+ u32 max_speed = spi->cur_msg->spi->max_speed_hz;
+ struct se_geni_rsc *rsc = &mas->spi_rsc;
+ /* Adjust the AB/IB based on the max speed of the slave.*/
+ rsc->ib = max_speed * DEFAULT_BUS_WIDTH;
+ rsc->ab = max_speed * DEFAULT_BUS_WIDTH;
ret = pm_runtime_get_sync(mas->dev);
if (ret < 0) {
dev_err(mas->dev, "Error enabling SE resources\n");
@@ -900,6 +906,7 @@
{
unsigned long timeout;
+ geni_se_dump_dbg_regs(&mas->spi_rsc, mas->base, mas->ipc);
reinit_completion(&mas->xfer_done);
geni_cancel_m_cmd(mas->base);
geni_write_reg(0, mas->base, SE_GENI_TX_WATERMARK_REG);
@@ -986,6 +993,7 @@
}
return ret;
err_gsi_geni_transfer_one:
+ geni_se_dump_dbg_regs(&mas->spi_rsc, mas->base, mas->ipc);
dmaengine_terminate_all(mas->tx);
return ret;
err_fifo_geni_transfer_one:
diff --git a/drivers/staging/rts5208/rtsx_scsi.c b/drivers/staging/rts5208/rtsx_scsi.c
index 01438fa..f50076d 100644
--- a/drivers/staging/rts5208/rtsx_scsi.c
+++ b/drivers/staging/rts5208/rtsx_scsi.c
@@ -414,7 +414,7 @@
sense->ascq = ascq;
if (sns_key_info0 != 0) {
sense->sns_key_info[0] = SKSV | sns_key_info0;
- sense->sns_key_info[1] = (sns_key_info1 & 0xf0) >> 8;
+ sense->sns_key_info[1] = (sns_key_info1 & 0xf0) >> 4;
sense->sns_key_info[2] = sns_key_info1 & 0x0f;
}
}
diff --git a/drivers/tty/serial/msm_geni_serial.c b/drivers/tty/serial/msm_geni_serial.c
index c5e2703..79788eb 100644
--- a/drivers/tty/serial/msm_geni_serial.c
+++ b/drivers/tty/serial/msm_geni_serial.c
@@ -1264,6 +1264,13 @@
goto exit_geni_serial_isr;
}
+ if (s_irq_status & S_RX_FIFO_WR_ERR_EN) {
+ uport->icount.buf_overrun++;
+ IPC_LOG_MSG(msm_port->ipc_log_misc,
+ "%s.sirq 0x%x buf_overrun:%d\n",
+ __func__, s_irq_status, uport->icount.buf_overrun);
+ }
+
if (!dma) {
if ((m_irq_status & m_irq_en) &
(M_TX_FIFO_WATERMARK_EN | M_CMD_DONE_EN))
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
index 840930b0..c8075eb 100644
--- a/drivers/usb/core/devio.c
+++ b/drivers/usb/core/devio.c
@@ -629,6 +629,8 @@
if (as->status < 0 && as->bulk_addr && as->status != -ECONNRESET &&
as->status != -ENOENT)
cancel_bulk_urbs(ps, as->bulk_addr);
+
+ wake_up(&ps->wait);
spin_unlock(&ps->lock);
if (signr) {
@@ -636,8 +638,6 @@
put_pid(pid);
put_cred(cred);
}
-
- wake_up(&ps->wait);
}
static void destroy_async(struct usb_dev_state *ps, struct list_head *list)
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c
index 574da2b..82806e3 100644
--- a/drivers/usb/core/quirks.c
+++ b/drivers/usb/core/quirks.c
@@ -57,8 +57,9 @@
/* Microsoft LifeCam-VX700 v2.0 */
{ USB_DEVICE(0x045e, 0x0770), .driver_info = USB_QUIRK_RESET_RESUME },
- /* Logitech HD Pro Webcams C920 and C930e */
+ /* Logitech HD Pro Webcams C920, C920-C and C930e */
{ USB_DEVICE(0x046d, 0x082d), .driver_info = USB_QUIRK_DELAY_INIT },
+ { USB_DEVICE(0x046d, 0x0841), .driver_info = USB_QUIRK_DELAY_INIT },
{ USB_DEVICE(0x046d, 0x0843), .driver_info = USB_QUIRK_DELAY_INIT },
/* Logitech ConferenceCam CC3000e */
@@ -217,6 +218,9 @@
{ USB_DEVICE(0x1a0a, 0x0200), .driver_info =
USB_QUIRK_LINEAR_UFRAME_INTR_BINTERVAL },
+ /* Corsair Strafe RGB */
+ { USB_DEVICE(0x1b1c, 0x1b20), .driver_info = USB_QUIRK_DELAY_INIT },
+
/* Acer C120 LED Projector */
{ USB_DEVICE(0x1de1, 0xc102), .driver_info = USB_QUIRK_NO_LPM },
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index 8a6ae0b..02adc93 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -2155,7 +2155,7 @@
struct usb_gadget *gadget = dev_to_usb_gadget(dev);
struct usb_composite_dev *cdev = get_gadget_data(gadget);
- return sprintf(buf, "%d\n", cdev->suspended);
+ return snprintf(buf, PAGE_SIZE, "%d\n", cdev->suspended);
}
static DEVICE_ATTR_RO(suspended);
diff --git a/drivers/usb/gadget/function/f_gsi.h b/drivers/usb/gadget/function/f_gsi.h
index 48454b7..a560083 100644
--- a/drivers/usb/gadget/function/f_gsi.h
+++ b/drivers/usb/gadget/function/f_gsi.h
@@ -1393,7 +1393,7 @@
/* string descriptors: */
static struct usb_string qdss_gsi_string_defs[] = {
- [0].s = "QDSS DATA",
+ [0].s = "Qualcomm DPL Data",
{}, /* end of list */
};
diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c
index 5f4ca78..58b9685 100644
--- a/drivers/usb/host/pci-quirks.c
+++ b/drivers/usb/host/pci-quirks.c
@@ -142,29 +142,30 @@
pinfo->sb_type.gen = AMD_CHIPSET_SB700;
else if (rev >= 0x40 && rev <= 0x4f)
pinfo->sb_type.gen = AMD_CHIPSET_SB800;
- }
- pinfo->smbus_dev = pci_get_device(PCI_VENDOR_ID_AMD,
- 0x145c, NULL);
- if (pinfo->smbus_dev) {
- pinfo->sb_type.gen = AMD_CHIPSET_TAISHAN;
} else {
pinfo->smbus_dev = pci_get_device(PCI_VENDOR_ID_AMD,
PCI_DEVICE_ID_AMD_HUDSON2_SMBUS, NULL);
- if (!pinfo->smbus_dev) {
- pinfo->sb_type.gen = NOT_AMD_CHIPSET;
- return 0;
+ if (pinfo->smbus_dev) {
+ rev = pinfo->smbus_dev->revision;
+ if (rev >= 0x11 && rev <= 0x14)
+ pinfo->sb_type.gen = AMD_CHIPSET_HUDSON2;
+ else if (rev >= 0x15 && rev <= 0x18)
+ pinfo->sb_type.gen = AMD_CHIPSET_BOLTON;
+ else if (rev >= 0x39 && rev <= 0x3a)
+ pinfo->sb_type.gen = AMD_CHIPSET_YANGTZE;
+ } else {
+ pinfo->smbus_dev = pci_get_device(PCI_VENDOR_ID_AMD,
+ 0x145c, NULL);
+ if (pinfo->smbus_dev) {
+ rev = pinfo->smbus_dev->revision;
+ pinfo->sb_type.gen = AMD_CHIPSET_TAISHAN;
+ } else {
+ pinfo->sb_type.gen = NOT_AMD_CHIPSET;
+ return 0;
+ }
}
-
- rev = pinfo->smbus_dev->revision;
- if (rev >= 0x11 && rev <= 0x14)
- pinfo->sb_type.gen = AMD_CHIPSET_HUDSON2;
- else if (rev >= 0x15 && rev <= 0x18)
- pinfo->sb_type.gen = AMD_CHIPSET_BOLTON;
- else if (rev >= 0x39 && rev <= 0x3a)
- pinfo->sb_type.gen = AMD_CHIPSET_YANGTZE;
}
-
pinfo->sb_type.rev = rev;
return 1;
}
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index 261ed2c..a6b6b1c 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -2655,6 +2655,13 @@
{
struct musb *musb = dev_to_musb(dev);
unsigned long flags;
+ int ret;
+
+ ret = pm_runtime_get_sync(dev);
+ if (ret < 0) {
+ pm_runtime_put_noidle(dev);
+ return ret;
+ }
musb_platform_disable(musb);
musb_generic_disable(musb);
@@ -2703,14 +2710,6 @@
if ((devctl & mask) != (musb->context.devctl & mask))
musb->port1_status = 0;
- /*
- * The USB HUB code expects the device to be in RPM_ACTIVE once it came
- * out of suspend
- */
- pm_runtime_disable(dev);
- pm_runtime_set_active(dev);
- pm_runtime_enable(dev);
-
musb_start(musb);
spin_lock_irqsave(&musb->lock, flags);
@@ -2720,6 +2719,9 @@
error);
spin_unlock_irqrestore(&musb->lock, flags);
+ pm_runtime_mark_last_busy(dev);
+ pm_runtime_put_autosuspend(dev);
+
return 0;
}
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index fe12315..2a99443 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -2023,6 +2023,7 @@
{ USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d03, 0xff, 0x02, 0x01) },
{ USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d03, 0xff, 0x00, 0x00) },
{ USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7d04, 0xff) }, /* D-Link DWM-158 */
+ { USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7d0e, 0xff) }, /* D-Link DWM-157 C1 */
{ USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7e19, 0xff), /* D-Link DWM-221 B1 */
.driver_info = (kernel_ulong_t)&net_intf4_blacklist },
{ USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7e35, 0xff), /* D-Link DWM-222 */
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index 74ed5aa..f6e1119 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -1834,6 +1834,8 @@
goto restore;
}
+ btrfs_qgroup_rescan_resume(fs_info);
+
if (!fs_info->uuid_root) {
btrfs_info(fs_info, "creating UUID tree");
ret = btrfs_create_uuid_tree(fs_info);
diff --git a/fs/dlm/user.c b/fs/dlm/user.c
index 58c2f4a..9ac6591 100644
--- a/fs/dlm/user.c
+++ b/fs/dlm/user.c
@@ -355,6 +355,10 @@
error = misc_register(&ls->ls_device);
if (error) {
kfree(ls->ls_device.name);
+ /* this has to be set to NULL
+ * to avoid a double-free in dlm_device_deregister
+ */
+ ls->ls_device.name = NULL;
}
fail:
return error;
diff --git a/fs/namespace.c b/fs/namespace.c
index 7731f77..2160bb9 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -227,6 +227,7 @@
mnt->mnt_count = 1;
mnt->mnt_writers = 0;
#endif
+ mnt->mnt.data = NULL;
INIT_HLIST_NODE(&mnt->mnt_hash);
INIT_LIST_HEAD(&mnt->mnt_child);
@@ -976,7 +977,6 @@
if (!mnt)
return ERR_PTR(-ENOMEM);
- mnt->mnt.data = NULL;
if (type->alloc_mnt_data) {
mnt->mnt.data = type->alloc_mnt_data();
if (!mnt->mnt.data) {
@@ -990,7 +990,6 @@
root = mount_fs(type, flags, name, &mnt->mnt, data);
if (IS_ERR(root)) {
- kfree(mnt->mnt.data);
mnt_free_id(mnt);
free_vfsmnt(mnt);
return ERR_CAST(root);
@@ -1109,7 +1108,6 @@
return mnt;
out_free:
- kfree(mnt->mnt.data);
mnt_free_id(mnt);
free_vfsmnt(mnt);
return ERR_PTR(err);
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index 84c1cb9..1eec947 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -636,11 +636,11 @@
if (result <= 0)
goto out;
- result = generic_write_sync(iocb, result);
- if (result < 0)
- goto out;
written = result;
iocb->ki_pos += written;
+ result = generic_write_sync(iocb, written);
+ if (result < 0)
+ goto out;
/* Return error values */
if (nfs_need_check_write(file, inode)) {
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index 80bcc0b..52ea41b 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -248,7 +248,6 @@
extern const struct nfs_pageio_ops nfs_pgio_rw_ops;
struct nfs_pgio_header *nfs_pgio_header_alloc(const struct nfs_rw_ops *);
void nfs_pgio_header_free(struct nfs_pgio_header *);
-void nfs_pgio_data_destroy(struct nfs_pgio_header *);
int nfs_generic_pgio(struct nfs_pageio_descriptor *, struct nfs_pgio_header *);
int nfs_initiate_pgio(struct rpc_clnt *clnt, struct nfs_pgio_header *hdr,
struct rpc_cred *cred, const struct nfs_rpc_ops *rpc_ops,
diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c
index 142a74f..3d17fc8 100644
--- a/fs/nfs/pagelist.c
+++ b/fs/nfs/pagelist.c
@@ -497,16 +497,6 @@
}
EXPORT_SYMBOL_GPL(nfs_pgio_header_alloc);
-/*
- * nfs_pgio_header_free - Free a read or write header
- * @hdr: The header to free
- */
-void nfs_pgio_header_free(struct nfs_pgio_header *hdr)
-{
- hdr->rw_ops->rw_free_header(hdr);
-}
-EXPORT_SYMBOL_GPL(nfs_pgio_header_free);
-
/**
* nfs_pgio_data_destroy - make @hdr suitable for reuse
*
@@ -515,14 +505,24 @@
*
* @hdr: A header that has had nfs_generic_pgio called
*/
-void nfs_pgio_data_destroy(struct nfs_pgio_header *hdr)
+static void nfs_pgio_data_destroy(struct nfs_pgio_header *hdr)
{
if (hdr->args.context)
put_nfs_open_context(hdr->args.context);
if (hdr->page_array.pagevec != hdr->page_array.page_array)
kfree(hdr->page_array.pagevec);
}
-EXPORT_SYMBOL_GPL(nfs_pgio_data_destroy);
+
+/*
+ * nfs_pgio_header_free - Free a read or write header
+ * @hdr: The header to free
+ */
+void nfs_pgio_header_free(struct nfs_pgio_header *hdr)
+{
+ nfs_pgio_data_destroy(hdr);
+ hdr->rw_ops->rw_free_header(hdr);
+}
+EXPORT_SYMBOL_GPL(nfs_pgio_header_free);
/**
* nfs_pgio_rpcsetup - Set up arguments for a pageio call
@@ -636,7 +636,6 @@
static void nfs_pgio_error(struct nfs_pgio_header *hdr)
{
set_bit(NFS_IOHDR_REDO, &hdr->flags);
- nfs_pgio_data_destroy(hdr);
hdr->completion_ops->completion(hdr);
}
@@ -647,7 +646,6 @@
static void nfs_pgio_release(void *calldata)
{
struct nfs_pgio_header *hdr = calldata;
- nfs_pgio_data_destroy(hdr);
hdr->completion_ops->completion(hdr);
}
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
index 415d7e6..b7a07ba 100644
--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -2145,7 +2145,6 @@
nfs_pageio_reset_write_mds(desc);
mirror->pg_recoalesce = 1;
}
- nfs_pgio_data_destroy(hdr);
hdr->release(hdr);
}
@@ -2257,7 +2256,6 @@
nfs_pageio_reset_read_mds(desc);
mirror->pg_recoalesce = 1;
}
- nfs_pgio_data_destroy(hdr);
hdr->release(hdr);
}
diff --git a/fs/sdcardfs/derived_perm.c b/fs/sdcardfs/derived_perm.c
index 1239d1c..fffaad4 100644
--- a/fs/sdcardfs/derived_perm.c
+++ b/fs/sdcardfs/derived_perm.c
@@ -176,6 +176,9 @@
gid_t gid = sbi->options.fs_low_gid;
struct iattr newattrs;
+ if (!sbi->options.gid_derivation)
+ return;
+
info = SDCARDFS_I(d_inode(dentry));
info_d = info->data;
perm = info_d->perm;
diff --git a/fs/sdcardfs/inode.c b/fs/sdcardfs/inode.c
index 683b492..4a971e2 100644
--- a/fs/sdcardfs/inode.c
+++ b/fs/sdcardfs/inode.c
@@ -34,10 +34,14 @@
if (!cred)
return NULL;
- if (data->under_obb)
- uid = AID_MEDIA_OBB;
- else
- uid = multiuser_get_uid(data->userid, sbi->options.fs_low_uid);
+ if (sbi->options.gid_derivation) {
+ if (data->under_obb)
+ uid = AID_MEDIA_OBB;
+ else
+ uid = multiuser_get_uid(data->userid, sbi->options.fs_low_uid);
+ } else {
+ uid = sbi->options.fs_low_uid;
+ }
cred->fsuid = make_kuid(&init_user_ns, uid);
cred->fsgid = make_kgid(&init_user_ns, sbi->options.fs_low_gid);
diff --git a/fs/sdcardfs/main.c b/fs/sdcardfs/main.c
index 80825b2..0a2b516 100644
--- a/fs/sdcardfs/main.c
+++ b/fs/sdcardfs/main.c
@@ -32,6 +32,7 @@
Opt_multiuser,
Opt_userid,
Opt_reserved_mb,
+ Opt_gid_derivation,
Opt_err,
};
@@ -43,6 +44,7 @@
{Opt_mask, "mask=%u"},
{Opt_userid, "userid=%d"},
{Opt_multiuser, "multiuser"},
+ {Opt_gid_derivation, "derive_gid"},
{Opt_reserved_mb, "reserved_mb=%u"},
{Opt_err, NULL}
};
@@ -64,6 +66,8 @@
vfsopts->gid = 0;
/* by default, 0MB is reserved */
opts->reserved_mb = 0;
+ /* by default, gid derivation is off */
+ opts->gid_derivation = false;
*debug = 0;
@@ -115,6 +119,9 @@
return 0;
opts->reserved_mb = option;
break;
+ case Opt_gid_derivation:
+ opts->gid_derivation = true;
+ break;
/* unknown option */
default:
if (!silent)
diff --git a/fs/sdcardfs/sdcardfs.h b/fs/sdcardfs/sdcardfs.h
index 4e0ce49..d1d8bab 100644
--- a/fs/sdcardfs/sdcardfs.h
+++ b/fs/sdcardfs/sdcardfs.h
@@ -219,6 +219,7 @@
gid_t fs_low_gid;
userid_t fs_user_id;
bool multiuser;
+ bool gid_derivation;
unsigned int reserved_mb;
};
diff --git a/fs/sdcardfs/super.c b/fs/sdcardfs/super.c
index 7f4539b..b89947d 100644
--- a/fs/sdcardfs/super.c
+++ b/fs/sdcardfs/super.c
@@ -302,6 +302,8 @@
seq_printf(m, ",mask=%u", vfsopts->mask);
if (opts->fs_user_id)
seq_printf(m, ",userid=%u", opts->fs_user_id);
+ if (opts->gid_derivation)
+ seq_puts(m, ",derive_gid");
if (opts->reserved_mb != 0)
seq_printf(m, ",reserved=%uMB", opts->reserved_mb);
diff --git a/fs/xfs/xfs_linux.h b/fs/xfs/xfs_linux.h
index 1455b2520..3ebed16 100644
--- a/fs/xfs/xfs_linux.h
+++ b/fs/xfs/xfs_linux.h
@@ -363,7 +363,14 @@
#endif /* DEBUG */
#ifdef CONFIG_XFS_RT
-#define XFS_IS_REALTIME_INODE(ip) ((ip)->i_d.di_flags & XFS_DIFLAG_REALTIME)
+
+/*
+ * make sure we ignore the inode flag if the filesystem doesn't have a
+ * configured realtime device.
+ */
+#define XFS_IS_REALTIME_INODE(ip) \
+ (((ip)->i_d.di_flags & XFS_DIFLAG_REALTIME) && \
+ (ip)->i_mount->m_rtdev_targp)
#else
#define XFS_IS_REALTIME_INODE(ip) (0)
#endif
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index 3e5dbbe..4308204 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -574,6 +574,7 @@
#define PCI_DEVICE_ID_AMD_CS5536_EHC 0x2095
#define PCI_DEVICE_ID_AMD_CS5536_UDC 0x2096
#define PCI_DEVICE_ID_AMD_CS5536_UOC 0x2097
+#define PCI_DEVICE_ID_AMD_CS5536_DEV_IDE 0x2092
#define PCI_DEVICE_ID_AMD_CS5536_IDE 0x209A
#define PCI_DEVICE_ID_AMD_LX_VIDEO 0x2081
#define PCI_DEVICE_ID_AMD_LX_AES 0x2082
diff --git a/include/linux/qcom-geni-se.h b/include/linux/qcom-geni-se.h
index aa4c1ed..463785d 100644
--- a/include/linux/qcom-geni-se.h
+++ b/include/linux/qcom-geni-se.h
@@ -117,6 +117,7 @@
#define SE_HW_PARAM_0 (0xE24)
#define SE_HW_PARAM_1 (0xE28)
#define SE_DMA_GENERAL_CFG (0xE30)
+#define SE_DMA_DEBUG_REG0 (0xE40)
/* GENI_OUTPUT_CTRL fields */
#define DEFAULT_IO_OUTPUT_CTRL_MSK (GENMASK(6, 0))
@@ -736,6 +737,22 @@
int geni_se_iommu_free_buf(struct device *wrapper_dev, dma_addr_t *iova,
void *buf, size_t size);
+
+/**
+ * geni_se_dump_dbg_regs() - Print relevant registers that capture most
+ * accurately the state of an SE; meant to be called
+ * in case of errors to help debug.
+ * @_dev: Pointer to the SE's device.
+ * @iomem: Base address of the SE's register space.
+ * @ipc: IPC log context handle.
+ *
+ * This function is used to print out all the registers that capture the state
+ * of an SE to help debug any errors.
+ *
+ * Return: None
+ */
+void geni_se_dump_dbg_regs(struct se_geni_rsc *rsc, void __iomem *base,
+ void *ipc);
#else
static inline unsigned int geni_read_reg_nolog(void __iomem *base, int offset)
{
@@ -907,5 +924,10 @@
return -ENXIO;
}
+void geni_se_dump_dbg_regs(struct se_geni_rsc *rsc, void __iomem *base,
+ void *ipc)
+{
+}
+
#endif
#endif
diff --git a/include/linux/string.h b/include/linux/string.h
index 4e510df..0463dfb 100644
--- a/include/linux/string.h
+++ b/include/linux/string.h
@@ -178,17 +178,6 @@
void __write_overflow(void) __compiletime_error("detected write beyond size of object passed as 1st parameter");
#if !defined(__NO_FORTIFY) && defined(__OPTIMIZE__) && defined(CONFIG_FORTIFY_SOURCE)
-__FORTIFY_INLINE char *strcpy(char *p, const char *q)
-{
- size_t p_size = __builtin_object_size(p, 0);
- size_t q_size = __builtin_object_size(q, 0);
- if (p_size == (size_t)-1 && q_size == (size_t)-1)
- return __builtin_strcpy(p, q);
- if (strscpy(p, q, p_size < q_size ? p_size : q_size) < 0)
- fortify_panic(__func__);
- return p;
-}
-
__FORTIFY_INLINE char *strncpy(char *p, const char *q, __kernel_size_t size)
{
size_t p_size = __builtin_object_size(p, 0);
@@ -367,6 +356,18 @@
fortify_panic(__func__);
return __real_kmemdup(p, size, gfp);
}
+
+/* defined after fortified strlen and memcpy to reuse them */
+__FORTIFY_INLINE char *strcpy(char *p, const char *q)
+{
+ size_t p_size = __builtin_object_size(p, 0);
+ size_t q_size = __builtin_object_size(q, 0);
+ if (p_size == (size_t)-1 && q_size == (size_t)-1)
+ return __builtin_strcpy(p, q);
+ memcpy(p, q, strlen(q) + 1);
+ return p;
+}
+
#endif
#endif /* _LINUX_STRING_H_ */
diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h
index 733a21e..1061add 100644
--- a/include/linux/workqueue.h
+++ b/include/linux/workqueue.h
@@ -311,8 +311,8 @@
__WQ_DRAINING = 1 << 16, /* internal: workqueue is draining */
__WQ_ORDERED = 1 << 17, /* internal: workqueue is ordered */
- __WQ_ORDERED_EXPLICIT = 1 << 18, /* internal: alloc_ordered_workqueue() */
__WQ_LEGACY = 1 << 18, /* internal: create*_workqueue() */
+ __WQ_ORDERED_EXPLICIT = 1 << 19, /* internal: alloc_ordered_workqueue() */
WQ_MAX_ACTIVE = 512, /* I like 512, better ideas? */
WQ_MAX_UNBOUND_PER_CPU = 4, /* 4 * #cpus for unbound wq */
diff --git a/include/soc/qcom/socinfo.h b/include/soc/qcom/socinfo.h
index f196d40..71bd075 100644
--- a/include/soc/qcom/socinfo.h
+++ b/include/soc/qcom/socinfo.h
@@ -102,6 +102,10 @@
of_flat_dt_is_compatible(of_get_flat_dt_root(), "qcom,sdm845")
#define early_machine_is_sdm670() \
of_flat_dt_is_compatible(of_get_flat_dt_root(), "qcom,sdm670")
+#define early_machine_is_qcs605() \
+ of_flat_dt_is_compatible(of_get_flat_dt_root(), "qcom,qcs605")
+#define early_machine_is_sda670() \
+ of_flat_dt_is_compatible(of_get_flat_dt_root(), "qcom,sda670")
#else
#define of_board_is_sim() 0
#define of_board_is_rumi() 0
@@ -142,6 +146,8 @@
#define early_machine_is_sdxpoorwills() 0
#define early_machine_is_sdm845() 0
#define early_machine_is_sdm670() 0
+#define early_machine_is_qcs605() 0
+#define early_machine_is_sda670() 0
#endif
#define PLATFORM_SUBTYPE_MDM 1
@@ -204,6 +210,8 @@
SDX_CPU_SDXPOORWILLS,
MSM_CPU_SDM845,
MSM_CPU_SDM670,
+ MSM_CPU_QCS605,
+ MSM_CPU_SDA670,
};
struct msm_soc_info {
diff --git a/include/uapi/linux/rmnet_ipa_fd_ioctl.h b/include/uapi/linux/rmnet_ipa_fd_ioctl.h
index f04ac49..04aaaad 100644
--- a/include/uapi/linux/rmnet_ipa_fd_ioctl.h
+++ b/include/uapi/linux/rmnet_ipa_fd_ioctl.h
@@ -33,6 +33,7 @@
#define WAN_IOCTL_QUERY_DL_FILTER_STATS 8
#define WAN_IOCTL_ADD_FLT_RULE_EX 9
#define WAN_IOCTL_QUERY_TETHER_STATS_ALL 10
+#define WAN_IOCTL_NOTIFY_WAN_STATE 11
/* User space may not have this defined. */
#ifndef IFNAMSIZ
@@ -126,6 +127,10 @@
uint32_t index;
};
+struct wan_ioctl_notify_wan_state {
+ uint8_t up;
+};
+
#define WAN_IOC_ADD_FLT_RULE _IOWR(WAN_IOC_MAGIC, \
WAN_IOCTL_ADD_FLT_RULE, \
struct ipa_install_fltr_rule_req_msg_v01 *)
@@ -170,4 +175,8 @@
WAN_IOCTL_QUERY_TETHER_STATS_ALL, \
struct wan_ioctl_query_tether_stats_all *)
+#define WAN_IOC_NOTIFY_WAN_STATE _IOWR(WAN_IOC_MAGIC, \
+ WAN_IOCTL_NOTIFY_WAN_STATE, \
+ struct wan_ioctl_notify_wan_state *)
+
#endif /* _RMNET_IPA_FD_IOCTL_H */
diff --git a/kernel/configs/android-base.config b/kernel/configs/android-base.config
index 7dc5b07..cf1d104 100644
--- a/kernel/configs/android-base.config
+++ b/kernel/configs/android-base.config
@@ -150,6 +150,7 @@
CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y
CONFIG_SECURITY_SELINUX=y
CONFIG_STAGING=y
+CONFIG_SYNC_FILE=y
CONFIG_TUN=y
CONFIG_UID_SYS_STATS=y
CONFIG_UNIX=y
diff --git a/kernel/kcov.c b/kernel/kcov.c
index 3cbb0c8..f8f3f4c 100644
--- a/kernel/kcov.c
+++ b/kernel/kcov.c
@@ -14,6 +14,7 @@
#include <linux/debugfs.h>
#include <linux/uaccess.h>
#include <linux/kcov.h>
+#include <asm/setup.h>
/*
* kcov descriptor (one per opened debugfs file).
@@ -68,6 +69,11 @@
if (mode == KCOV_MODE_TRACE) {
unsigned long *area;
unsigned long pos;
+ unsigned long ip = _RET_IP_;
+
+#ifdef CONFIG_RANDOMIZE_BASE
+ ip -= kaslr_offset();
+#endif
/*
* There is some code that runs in interrupts but for which
@@ -81,7 +87,7 @@
/* The first word is number of subsequent PCs. */
pos = READ_ONCE(area[0]) + 1;
if (likely(pos < t->kcov_size)) {
- area[pos] = _RET_IP_;
+ area[pos] = ip;
WRITE_ONCE(area[0], pos);
}
}
diff --git a/kernel/locking/locktorture.c b/kernel/locking/locktorture.c
index f8c5af5..d3de04b 100644
--- a/kernel/locking/locktorture.c
+++ b/kernel/locking/locktorture.c
@@ -780,6 +780,10 @@
else
lock_torture_print_module_parms(cxt.cur_ops,
"End of test: SUCCESS");
+
+ kfree(cxt.lwsa);
+ kfree(cxt.lrsa);
+
end:
torture_cleanup_end();
}
@@ -924,6 +928,8 @@
GFP_KERNEL);
if (reader_tasks == NULL) {
VERBOSE_TOROUT_ERRSTRING("reader_tasks: Out of memory");
+ kfree(writer_tasks);
+ writer_tasks = NULL;
firsterr = -ENOMEM;
goto unwind;
}
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index ccfb9bf..352cfca 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -9620,4 +9620,4 @@
}
#endif /* CONFIG_SCHED_WALT */
-__read_mostly bool sched_predl;
+__read_mostly bool sched_predl = 1;
diff --git a/kernel/sched/tune.c b/kernel/sched/tune.c
index 217bafe..93643ba 100644
--- a/kernel/sched/tune.c
+++ b/kernel/sched/tune.c
@@ -838,7 +838,6 @@
bg = &per_cpu(cpu_boost_groups, cpu);
bg->group[st->idx].boost = 0;
bg->group[st->idx].tasks = 0;
- raw_spin_lock_init(&bg->lock);
}
return 0;
diff --git a/mm/memory.c b/mm/memory.c
index b5e0ed3..378ebc0 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -3596,6 +3596,11 @@
/* do counter updates before entering really critical section. */
check_sync_rss_stat(current);
+ if (!arch_vma_access_permitted(vma, flags & FAULT_FLAG_WRITE,
+ flags & FAULT_FLAG_INSTRUCTION,
+ flags & FAULT_FLAG_REMOTE))
+ return VM_FAULT_SIGSEGV;
+
/*
* Enable the memcg OOM handling for faults triggered in user
* space. Kernel faults are handled more gracefully.
@@ -3603,11 +3608,6 @@
if (flags & FAULT_FLAG_USER)
mem_cgroup_oom_enable();
- if (!arch_vma_access_permitted(vma, flags & FAULT_FLAG_WRITE,
- flags & FAULT_FLAG_INSTRUCTION,
- flags & FAULT_FLAG_REMOTE))
- return VM_FAULT_SIGSEGV;
-
if (unlikely(is_vm_hugetlb_page(vma)))
ret = hugetlb_fault(vma->vm_mm, vma, address, flags);
else
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 577f1c0..ffd09c1 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -58,7 +58,7 @@
u8 code, u8 ident, u16 dlen, void *data);
static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len,
void *data);
-static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data);
+static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data, size_t data_size);
static void l2cap_send_disconn_req(struct l2cap_chan *chan, int err);
static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
@@ -1473,7 +1473,7 @@
set_bit(CONF_REQ_SENT, &chan->conf_state);
l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
- l2cap_build_conf_req(chan, buf), buf);
+ l2cap_build_conf_req(chan, buf, sizeof(buf)), buf);
chan->num_conf_req++;
}
@@ -2977,12 +2977,15 @@
return len;
}
-static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val)
+static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val, size_t size)
{
struct l2cap_conf_opt *opt = *ptr;
BT_DBG("type 0x%2.2x len %u val 0x%lx", type, len, val);
+ if (size < L2CAP_CONF_OPT_SIZE + len)
+ return;
+
opt->type = type;
opt->len = len;
@@ -3007,7 +3010,7 @@
*ptr += L2CAP_CONF_OPT_SIZE + len;
}
-static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan)
+static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan, size_t size)
{
struct l2cap_conf_efs efs;
@@ -3035,7 +3038,7 @@
}
l2cap_add_conf_opt(ptr, L2CAP_CONF_EFS, sizeof(efs),
- (unsigned long) &efs);
+ (unsigned long) &efs, size);
}
static void l2cap_ack_timeout(struct work_struct *work)
@@ -3181,11 +3184,12 @@
chan->ack_win = chan->tx_win;
}
-static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data)
+static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data, size_t data_size)
{
struct l2cap_conf_req *req = data;
struct l2cap_conf_rfc rfc = { .mode = chan->mode };
void *ptr = req->data;
+ void *endptr = data + data_size;
u16 size;
BT_DBG("chan %p", chan);
@@ -3210,7 +3214,7 @@
done:
if (chan->imtu != L2CAP_DEFAULT_MTU)
- l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
+ l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu, endptr - ptr);
switch (chan->mode) {
case L2CAP_MODE_BASIC:
@@ -3229,7 +3233,7 @@
rfc.max_pdu_size = 0;
l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
- (unsigned long) &rfc);
+ (unsigned long) &rfc, endptr - ptr);
break;
case L2CAP_MODE_ERTM:
@@ -3249,21 +3253,21 @@
L2CAP_DEFAULT_TX_WINDOW);
l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
- (unsigned long) &rfc);
+ (unsigned long) &rfc, endptr - ptr);
if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
- l2cap_add_opt_efs(&ptr, chan);
+ l2cap_add_opt_efs(&ptr, chan, endptr - ptr);
if (test_bit(FLAG_EXT_CTRL, &chan->flags))
l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
- chan->tx_win);
+ chan->tx_win, endptr - ptr);
if (chan->conn->feat_mask & L2CAP_FEAT_FCS)
if (chan->fcs == L2CAP_FCS_NONE ||
test_bit(CONF_RECV_NO_FCS, &chan->conf_state)) {
chan->fcs = L2CAP_FCS_NONE;
l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1,
- chan->fcs);
+ chan->fcs, endptr - ptr);
}
break;
@@ -3281,17 +3285,17 @@
rfc.max_pdu_size = cpu_to_le16(size);
l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
- (unsigned long) &rfc);
+ (unsigned long) &rfc, endptr - ptr);
if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
- l2cap_add_opt_efs(&ptr, chan);
+ l2cap_add_opt_efs(&ptr, chan, endptr - ptr);
if (chan->conn->feat_mask & L2CAP_FEAT_FCS)
if (chan->fcs == L2CAP_FCS_NONE ||
test_bit(CONF_RECV_NO_FCS, &chan->conf_state)) {
chan->fcs = L2CAP_FCS_NONE;
l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1,
- chan->fcs);
+ chan->fcs, endptr - ptr);
}
break;
}
@@ -3302,10 +3306,11 @@
return ptr - data;
}
-static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
+static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data, size_t data_size)
{
struct l2cap_conf_rsp *rsp = data;
void *ptr = rsp->data;
+ void *endptr = data + data_size;
void *req = chan->conf_req;
int len = chan->conf_len;
int type, hint, olen;
@@ -3407,7 +3412,7 @@
return -ECONNREFUSED;
l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
- (unsigned long) &rfc);
+ (unsigned long) &rfc, endptr - ptr);
}
if (result == L2CAP_CONF_SUCCESS) {
@@ -3420,7 +3425,7 @@
chan->omtu = mtu;
set_bit(CONF_MTU_DONE, &chan->conf_state);
}
- l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->omtu);
+ l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->omtu, endptr - ptr);
if (remote_efs) {
if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
@@ -3434,7 +3439,7 @@
l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
sizeof(efs),
- (unsigned long) &efs);
+ (unsigned long) &efs, endptr - ptr);
} else {
/* Send PENDING Conf Rsp */
result = L2CAP_CONF_PENDING;
@@ -3467,7 +3472,7 @@
set_bit(CONF_MODE_DONE, &chan->conf_state);
l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
- sizeof(rfc), (unsigned long) &rfc);
+ sizeof(rfc), (unsigned long) &rfc, endptr - ptr);
if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) {
chan->remote_id = efs.id;
@@ -3481,7 +3486,7 @@
le32_to_cpu(efs.sdu_itime);
l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS,
sizeof(efs),
- (unsigned long) &efs);
+ (unsigned long) &efs, endptr - ptr);
}
break;
@@ -3495,7 +3500,7 @@
set_bit(CONF_MODE_DONE, &chan->conf_state);
l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
- (unsigned long) &rfc);
+ (unsigned long) &rfc, endptr - ptr);
break;
@@ -3517,10 +3522,11 @@
}
static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len,
- void *data, u16 *result)
+ void *data, size_t size, u16 *result)
{
struct l2cap_conf_req *req = data;
void *ptr = req->data;
+ void *endptr = data + size;
int type, olen;
unsigned long val;
struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
@@ -3538,13 +3544,13 @@
chan->imtu = L2CAP_DEFAULT_MIN_MTU;
} else
chan->imtu = val;
- l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu);
+ l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu, endptr - ptr);
break;
case L2CAP_CONF_FLUSH_TO:
chan->flush_to = val;
l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
- 2, chan->flush_to);
+ 2, chan->flush_to, endptr - ptr);
break;
case L2CAP_CONF_RFC:
@@ -3558,13 +3564,13 @@
chan->fcs = 0;
l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
- sizeof(rfc), (unsigned long) &rfc);
+ sizeof(rfc), (unsigned long) &rfc, endptr - ptr);
break;
case L2CAP_CONF_EWS:
chan->ack_win = min_t(u16, val, chan->ack_win);
l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
- chan->tx_win);
+ chan->tx_win, endptr - ptr);
break;
case L2CAP_CONF_EFS:
@@ -3577,7 +3583,7 @@
return -ECONNREFUSED;
l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, sizeof(efs),
- (unsigned long) &efs);
+ (unsigned long) &efs, endptr - ptr);
break;
case L2CAP_CONF_FCS:
@@ -3682,7 +3688,7 @@
return;
l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
- l2cap_build_conf_req(chan, buf), buf);
+ l2cap_build_conf_req(chan, buf, sizeof(buf)), buf);
chan->num_conf_req++;
}
@@ -3890,7 +3896,7 @@
u8 buf[128];
set_bit(CONF_REQ_SENT, &chan->conf_state);
l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
- l2cap_build_conf_req(chan, buf), buf);
+ l2cap_build_conf_req(chan, buf, sizeof(buf)), buf);
chan->num_conf_req++;
}
@@ -3968,7 +3974,7 @@
break;
l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
- l2cap_build_conf_req(chan, req), req);
+ l2cap_build_conf_req(chan, req, sizeof(req)), req);
chan->num_conf_req++;
break;
@@ -4080,7 +4086,7 @@
}
/* Complete config. */
- len = l2cap_parse_conf_req(chan, rsp);
+ len = l2cap_parse_conf_req(chan, rsp, sizeof(rsp));
if (len < 0) {
l2cap_send_disconn_req(chan, ECONNRESET);
goto unlock;
@@ -4114,7 +4120,7 @@
if (!test_and_set_bit(CONF_REQ_SENT, &chan->conf_state)) {
u8 buf[64];
l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
- l2cap_build_conf_req(chan, buf), buf);
+ l2cap_build_conf_req(chan, buf, sizeof(buf)), buf);
chan->num_conf_req++;
}
@@ -4174,7 +4180,7 @@
char buf[64];
len = l2cap_parse_conf_rsp(chan, rsp->data, len,
- buf, &result);
+ buf, sizeof(buf), &result);
if (len < 0) {
l2cap_send_disconn_req(chan, ECONNRESET);
goto done;
@@ -4204,7 +4210,7 @@
/* throw out any old stored conf requests */
result = L2CAP_CONF_SUCCESS;
len = l2cap_parse_conf_rsp(chan, rsp->data, len,
- req, &result);
+ req, sizeof(req), &result);
if (len < 0) {
l2cap_send_disconn_req(chan, ECONNRESET);
goto done;
@@ -4781,7 +4787,7 @@
set_bit(CONF_REQ_SENT, &chan->conf_state);
l2cap_send_cmd(chan->conn, l2cap_get_ident(chan->conn),
L2CAP_CONF_REQ,
- l2cap_build_conf_req(chan, buf), buf);
+ l2cap_build_conf_req(chan, buf, sizeof(buf)), buf);
chan->num_conf_req++;
}
}
@@ -7457,7 +7463,7 @@
set_bit(CONF_REQ_SENT, &chan->conf_state);
l2cap_send_cmd(conn, l2cap_get_ident(conn),
L2CAP_CONF_REQ,
- l2cap_build_conf_req(chan, buf),
+ l2cap_build_conf_req(chan, buf, sizeof(buf)),
buf);
chan->num_conf_req++;
}
diff --git a/net/netfilter/xt_qtaguid.c b/net/netfilter/xt_qtaguid.c
index ade9306..1cf2874 100644
--- a/net/netfilter/xt_qtaguid.c
+++ b/net/netfilter/xt_qtaguid.c
@@ -1772,7 +1772,7 @@
kgid_t gid_max = make_kgid(&init_user_ns, info->gid_max);
set_sk_callback_lock = true;
read_lock_bh(&sk->sk_callback_lock);
- MT_DEBUG("qtaguid[%d]: sk=%p->sk_socket=%p->file=%p\n",
+ MT_DEBUG("qtaguid[%d]: sk=%pK->sk_socket=%pK->file=%pK\n",
par->hooknum, sk, sk->sk_socket,
sk->sk_socket ? sk->sk_socket->file : (void *)-1LL);
filp = sk->sk_socket ? sk->sk_socket->file : NULL;
diff --git a/net/wireless/db.txt b/net/wireless/db.txt
index 413deff..cad82a4 100644
--- a/net/wireless/db.txt
+++ b/net/wireless/db.txt
@@ -223,17 +223,16 @@
(5490 - 5710 @ 160), (30), DFS
country BZ:
- (2402 - 2482 @ 40), (36)
- (5170 - 5330 @ 160), (27)
- (5490 - 5730 @ 160), (36)
- (5735 - 5835 @ 80), (36)
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5330 @ 160), (23)
+ (5490 - 5730 @ 160), (30)
+ (5735 - 5835 @ 80), (30)
country CA: DFS-FCC
(2402 - 2472 @ 40), (30)
(5170 - 5250 @ 80), (24), AUTO-BW
(5250 - 5330 @ 80), (24), DFS, AUTO-BW
- (5490 - 5590 @ 80), (24), DFS
- (5650 - 5730 @ 80), (24), DFS
+ (5490 - 5730 @ 160), (24), DFS
(5735 - 5835 @ 80), (30)
# 60 gHz band channels 1-3
(57240 - 63720 @ 2160), (40)
@@ -682,7 +681,13 @@
country IN:
(2402 - 2482 @ 40), (20)
(5170 - 5330 @ 160), (23)
- (5735 - 5835 @ 80), (30)
+ (5735 - 5835 @ 80), (33)
+
+country IQ: DFS-ETSI
+ (2402 - 2482 @ 40), (20)
+ (5170 - 5250 @ 80), (23), AUTO-BW
+ (5250 - 5330 @ 80), (23), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (30), DFS
country IS: DFS-ETSI
(2402 - 2482 @ 40), (20)
@@ -736,7 +741,6 @@
country JP: DFS-JP
(2402 - 2482 @ 40), (20)
- (2474 - 2494 @ 20), (20), NO-OFDM
(5170 - 5250 @ 80), (20), AUTO-BW, NO-OUTDOOR
(5250 - 5330 @ 80), (20), DFS, AUTO-BW, NO-OUTDOOR
(5490 - 5710 @ 160), (20), DFS
@@ -758,7 +762,7 @@
country KN: DFS-FCC
(2402 - 2482 @ 40), (20)
(5170 - 5250 @ 80), (23), AUTO-BW
- (5250 - 5330 @ 80), (23), DFS, AUTO-BW
+ (5250 - 5330 @ 80), (30), DFS, AUTO-BW
(5490 - 5710 @ 160), (30), DFS
(5735 - 5815 @ 80), (30)
@@ -1009,7 +1013,7 @@
(5170 - 5250 @ 80), (24), AUTO-BW
(5250 - 5330 @ 80), (24), DFS, AUTO-BW
(5490 - 5650 @ 160), (24), DFS
- (5735 - 5815 @ 80), (24)
+ (5735 - 5835 @ 80), (24)
# 60 gHz band channels 1-3
(57240 - 63720 @ 2160), (40)
@@ -1089,7 +1093,7 @@
(5490 - 5710 @ 160), (30), DFS
country PA:
- (2402 - 2472 @ 40), (30)
+ (2402 - 2472 @ 40), (36)
(5170 - 5250 @ 80), (23), AUT0-BW
(5250 - 5330 @ 80), (30), AUTO-BW
(5735 - 5835 @ 80), (36)
@@ -1374,9 +1378,9 @@
country TT:
(2402 - 2482 @ 40), (20)
- (5170 - 5330 @ 160), (27)
- (5490 - 5730 @ 160), (36)
- (5735 - 5835 @ 80), (36)
+ (5170 - 5330 @ 160), (24)
+ (5490 - 5730 @ 160), (24)
+ (5735 - 5835 @ 80), (30)
# 60 gHz band channels 1-3, FCC
(57240 - 63720 @ 2160), (40)
@@ -1450,7 +1454,7 @@
country UZ: DFS-ETSI
(2402 - 2482 @ 40), (20)
(5170 - 5250 @ 80), (23), AUTO-BW
- (5250 - 5330 @ 80), (20), DFS, AUTO-BW
+ (5250 - 5330 @ 80), (23), DFS, AUTO-BW
country VC: DFS-ETSI
(2402 - 2482 @ 40), (20)
diff --git a/security/commoncap.c b/security/commoncap.c
index 3e44d01..b5aca42 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -58,7 +58,7 @@
}
/**
- * cap_capable - Determine whether a task has a particular effective capability
+ * __cap_capable - Determine whether a task has a particular effective capability
* @cred: The credentials to use
* @ns: The user namespace in which we need the capability
* @cap: The capability to check for
@@ -72,18 +72,11 @@
* cap_has_capability() returns 0 when a task has a capability, but the
* kernel's capable() and has_capability() returns 1 for this case.
*/
-int cap_capable(const struct cred *cred, struct user_namespace *targ_ns,
+int __cap_capable(const struct cred *cred, struct user_namespace *targ_ns,
int cap, int audit)
{
struct user_namespace *ns = targ_ns;
-#ifdef CONFIG_ANDROID_PARANOID_NETWORK
- if (cap == CAP_NET_RAW && in_egroup_p(AID_NET_RAW))
- return 0;
- if (cap == CAP_NET_ADMIN && in_egroup_p(AID_NET_ADMIN))
- return 0;
-#endif
-
/* See if cred has the capability in the target user namespace
* by examining the target user namespace and all of the target
* user namespace's parents.
@@ -114,6 +107,27 @@
/* We never get here */
}
+int cap_capable(const struct cred *cred, struct user_namespace *targ_ns,
+ int cap, int audit)
+{
+ int ret = __cap_capable(cred, targ_ns, cap, audit);
+
+#ifdef CONFIG_ANDROID_PARANOID_NETWORK
+ if (ret != 0 && cap == CAP_NET_RAW && in_egroup_p(AID_NET_RAW)) {
+ printk("Process %s granted CAP_NET_RAW from Android group net_raw.\n", current->comm);
+ printk(" Please update the .rc file to explictly set 'capabilities NET_RAW'\n");
+ printk(" Implicit grants are deprecated and will be removed in the future.\n");
+ return 0;
+ }
+ if (ret != 0 && cap == CAP_NET_ADMIN && in_egroup_p(AID_NET_ADMIN)) {
+ printk("Process %s granted CAP_NET_ADMIN from Android group net_admin.\n", current->comm);
+ printk(" Please update the .rc file to explictly set 'capabilities NET_ADMIN'\n");
+ printk(" Implicit grants are deprecated and will be removed in the future.\n");
+ return 0;
+ }
+#endif
+ return ret;
+}
/**
* cap_settime - Determine whether the current process may set the system clock
* @ts: The time to set
diff --git a/sound/isa/msnd/msnd_midi.c b/sound/isa/msnd/msnd_midi.c
index ffc67fd..58e59cd 100644
--- a/sound/isa/msnd/msnd_midi.c
+++ b/sound/isa/msnd/msnd_midi.c
@@ -120,24 +120,24 @@
unsigned long flags;
struct snd_msndmidi *mpu = mpuv;
void *pwMIDQData = mpu->dev->mappedbase + MIDQ_DATA_BUFF;
+ u16 head, tail, size;
spin_lock_irqsave(&mpu->input_lock, flags);
- while (readw(mpu->dev->MIDQ + JQS_wTail) !=
- readw(mpu->dev->MIDQ + JQS_wHead)) {
- u16 wTmp, val;
- val = readw(pwMIDQData + 2 * readw(mpu->dev->MIDQ + JQS_wHead));
+ head = readw(mpu->dev->MIDQ + JQS_wHead);
+ tail = readw(mpu->dev->MIDQ + JQS_wTail);
+ size = readw(mpu->dev->MIDQ + JQS_wSize);
+ if (head > size || tail > size)
+ goto out;
+ while (head != tail) {
+ unsigned char val = readw(pwMIDQData + 2 * head);
- if (test_bit(MSNDMIDI_MODE_BIT_INPUT_TRIGGER,
- &mpu->mode))
- snd_rawmidi_receive(mpu->substream_input,
- (unsigned char *)&val, 1);
-
- wTmp = readw(mpu->dev->MIDQ + JQS_wHead) + 1;
- if (wTmp > readw(mpu->dev->MIDQ + JQS_wSize))
- writew(0, mpu->dev->MIDQ + JQS_wHead);
- else
- writew(wTmp, mpu->dev->MIDQ + JQS_wHead);
+ if (test_bit(MSNDMIDI_MODE_BIT_INPUT_TRIGGER, &mpu->mode))
+ snd_rawmidi_receive(mpu->substream_input, &val, 1);
+ if (++head > size)
+ head = 0;
+ writew(head, mpu->dev->MIDQ + JQS_wHead);
}
+ out:
spin_unlock_irqrestore(&mpu->input_lock, flags);
}
EXPORT_SYMBOL(snd_msndmidi_input_read);
diff --git a/sound/isa/msnd/msnd_pinnacle.c b/sound/isa/msnd/msnd_pinnacle.c
index 4c07266..a31ea6c 100644
--- a/sound/isa/msnd/msnd_pinnacle.c
+++ b/sound/isa/msnd/msnd_pinnacle.c
@@ -170,23 +170,24 @@
{
struct snd_msnd *chip = dev_id;
void *pwDSPQData = chip->mappedbase + DSPQ_DATA_BUFF;
+ u16 head, tail, size;
/* Send ack to DSP */
/* inb(chip->io + HP_RXL); */
/* Evaluate queued DSP messages */
- while (readw(chip->DSPQ + JQS_wTail) != readw(chip->DSPQ + JQS_wHead)) {
- u16 wTmp;
-
- snd_msnd_eval_dsp_msg(chip,
- readw(pwDSPQData + 2 * readw(chip->DSPQ + JQS_wHead)));
-
- wTmp = readw(chip->DSPQ + JQS_wHead) + 1;
- if (wTmp > readw(chip->DSPQ + JQS_wSize))
- writew(0, chip->DSPQ + JQS_wHead);
- else
- writew(wTmp, chip->DSPQ + JQS_wHead);
+ head = readw(chip->DSPQ + JQS_wHead);
+ tail = readw(chip->DSPQ + JQS_wTail);
+ size = readw(chip->DSPQ + JQS_wSize);
+ if (head > size || tail > size)
+ goto out;
+ while (head != tail) {
+ snd_msnd_eval_dsp_msg(chip, readw(pwDSPQData + 2 * head));
+ if (++head > size)
+ head = 0;
+ writew(head, chip->DSPQ + JQS_wHead);
}
+ out:
/* Send ack to DSP */
inb(chip->io + HP_RXL);
return IRQ_HANDLED;
diff --git a/tools/testing/selftests/x86/fsgsbase.c b/tools/testing/selftests/x86/fsgsbase.c
index 5b2b4b3..9b4610c 100644
--- a/tools/testing/selftests/x86/fsgsbase.c
+++ b/tools/testing/selftests/x86/fsgsbase.c
@@ -285,9 +285,12 @@
}
}
-static void set_gs_and_switch_to(unsigned long local, unsigned long remote)
+static void set_gs_and_switch_to(unsigned long local,
+ unsigned short force_sel,
+ unsigned long remote)
{
unsigned long base;
+ unsigned short sel_pre_sched, sel_post_sched;
bool hard_zero = false;
if (local == HARD_ZERO) {
@@ -297,6 +300,8 @@
printf("[RUN]\tARCH_SET_GS(0x%lx)%s, then schedule to 0x%lx\n",
local, hard_zero ? " and clear gs" : "", remote);
+ if (force_sel)
+ printf("\tBefore schedule, set selector to 0x%hx\n", force_sel);
if (syscall(SYS_arch_prctl, ARCH_SET_GS, local) != 0)
err(1, "ARCH_SET_GS");
if (hard_zero)
@@ -307,18 +312,35 @@
printf("[FAIL]\tGSBASE wasn't set as expected\n");
}
+ if (force_sel) {
+ asm volatile ("mov %0, %%gs" : : "rm" (force_sel));
+ sel_pre_sched = force_sel;
+ local = read_base(GS);
+
+ /*
+ * Signal delivery seems to mess up weird selectors. Put it
+ * back.
+ */
+ asm volatile ("mov %0, %%gs" : : "rm" (force_sel));
+ } else {
+ asm volatile ("mov %%gs, %0" : "=rm" (sel_pre_sched));
+ }
+
remote_base = remote;
ftx = 1;
syscall(SYS_futex, &ftx, FUTEX_WAKE, 0, NULL, NULL, 0);
while (ftx != 0)
syscall(SYS_futex, &ftx, FUTEX_WAIT, 1, NULL, NULL, 0);
+ asm volatile ("mov %%gs, %0" : "=rm" (sel_post_sched));
base = read_base(GS);
- if (base == local) {
- printf("[OK]\tGSBASE remained 0x%lx\n", local);
+ if (base == local && sel_pre_sched == sel_post_sched) {
+ printf("[OK]\tGS/BASE remained 0x%hx/0x%lx\n",
+ sel_pre_sched, local);
} else {
nerrs++;
- printf("[FAIL]\tGSBASE changed to 0x%lx\n", base);
+ printf("[FAIL]\tGS/BASE changed from 0x%hx/0x%lx to 0x%hx/0x%lx\n",
+ sel_pre_sched, local, sel_post_sched, base);
}
}
@@ -381,8 +403,15 @@
for (int local = 0; local < 4; local++) {
for (int remote = 0; remote < 4; remote++) {
- set_gs_and_switch_to(bases_with_hard_zero[local],
- bases_with_hard_zero[remote]);
+ for (unsigned short s = 0; s < 5; s++) {
+ unsigned short sel = s;
+ if (s == 4)
+ asm ("mov %%ss, %0" : "=rm" (sel));
+ set_gs_and_switch_to(
+ bases_with_hard_zero[local],
+ sel,
+ bases_with_hard_zero[remote]);
+ }
}
}