Merge "msm: wlan: Fix regulatory rule of JO"
diff --git a/Documentation/devicetree/bindings/power/supply/qcom/qpnp-fg-gen3.txt b/Documentation/devicetree/bindings/power/supply/qcom/qpnp-fg-gen3.txt
index d205b0b..f50fd88 100644
--- a/Documentation/devicetree/bindings/power/supply/qcom/qpnp-fg-gen3.txt
+++ b/Documentation/devicetree/bindings/power/supply/qcom/qpnp-fg-gen3.txt
@@ -208,14 +208,14 @@
Value type: <u32>
Definition: Lower limit of battery temperature to start the capacity
learning. If this is not specified, then the default value
- used will be 150. Unit is in decidegC.
+ used will be 150 (15 C). Unit is in decidegC.
- qcom,cl-max-temp
Usage: optional
Value type: <u32>
Definition: Upper limit of battery temperature to start the capacity
learning. If this is not specified, then the default value
- used will be 450 (45C). Unit is in decidegC.
+ used will be 500 (50 C). Unit is in decidegC.
- qcom,cl-max-increment
Usage: optional
diff --git a/Documentation/devicetree/bindings/spi/qcom,spi-geni-qcom.txt b/Documentation/devicetree/bindings/spi/qcom,spi-geni-qcom.txt
index cd2d2ea..866d004 100644
--- a/Documentation/devicetree/bindings/spi/qcom,spi-geni-qcom.txt
+++ b/Documentation/devicetree/bindings/spi/qcom,spi-geni-qcom.txt
@@ -25,6 +25,10 @@
Documentation/devicetree/bindings/spi/spi-bus.txt
- qcom,wrapper-core: Wrapper QUPv3 core containing this SPI controller.
+Optional properties:
+- qcom,rt: Specifies if the framework worker thread for this
+ controller device should have "real-time" priority.
+
SPI slave nodes must be children of the SPI master node and can contain
properties described in Documentation/devicetree/bindings/spi/spi-bus.txt
diff --git a/arch/arm/boot/dts/qcom/pm8950.dtsi b/arch/arm/boot/dts/qcom/pm8950.dtsi
new file mode 100644
index 0000000..f47872a
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/pm8950.dtsi
@@ -0,0 +1,388 @@
+/* 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.
+ */
+
+&spmi_bus {
+ qcom,pm8950@0 {
+ compatible ="qcom,spmi-pmic";
+ reg = <0x0 SPMI_USID>;
+ #address-cells = <2>;
+ #size-cells = <0>;
+
+ pm8950_revid: qcom,revid@100 {
+ compatible = "qcom,qpnp-revid";
+ reg = <0x100 0x100>;
+ };
+
+ pm8950_temp_alarm: qcom,temp-alarm@2400 {
+ compatible = "qcom,qpnp-temp-alarm";
+ reg = <0x2400 0x100>;
+ interrupts = <0x0 0x24 0x0>;
+ label = "pm8950_tz";
+ qcom,channel-num = <8>;
+ qcom,threshold-set = <0>;
+ qcom,temp_alarm-vadc = <&pm8950_vadc>;
+ };
+
+ qcom,power-on@800 {
+ compatible = "qcom,qpnp-power-on";
+ reg = <0x800 0x100>;
+ interrupts = <0x0 0x8 0x0>,
+ <0x0 0x8 0x1>,
+ <0x0 0x8 0x4>,
+ <0x0 0x8 0x5>;
+ interrupt-names = "kpdpwr", "resin",
+ "resin-bark", "kpdpwr-resin-bark";
+ qcom,pon-dbc-delay = <15625>;
+ qcom,system-reset;
+
+ qcom,pon_1 {
+ qcom,pon-type = <0>;
+ qcom,pull-up = <1>;
+ linux,code = <116>;
+ };
+
+ qcom,pon_2 {
+ qcom,pon-type = <1>;
+ qcom,pull-up = <1>;
+ linux,code = <114>;
+ };
+ };
+
+ pm8950_coincell: qcom,coincell@2800 {
+ compatible = "qcom,qpnp-coincell";
+ reg = <0x2800 0x100>;
+ };
+
+ pm8950_mpps: mpps {
+ compatible = "qcom,qpnp-pin";
+ spmi-dev-container;
+ gpio-controller;
+ #gpio-cells = <2>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ label = "pm8950-mpp";
+
+ mpp@a000 {
+ reg = <0xa000 0x100>;
+ qcom,pin-num = <1>;
+ status = "disabled";
+ };
+
+ mpp@a100 {
+ /* MPP2 - PA_THERM config */
+ reg = <0xa100 0x100>;
+ qcom,pin-num = <2>;
+ qcom,mode = <4>; /* AIN input */
+ qcom,invert = <1>; /* Enable MPP */
+ qcom,ain-route = <1>; /* AMUX 6 */
+ qcom,master-en = <1>;
+ qcom,src-sel = <0>; /* Function constant */
+ };
+
+ mpp@a200 {
+ reg = <0xa200 0x100>;
+ qcom,pin-num = <3>;
+ status = "disabled";
+ };
+
+ mpp@a300 {
+ /* MPP4 - CASE_THERM config */
+ reg = <0xa300 0x100>;
+ qcom,pin-num = <4>;
+ qcom,mode = <4>; /* AIN input */
+ qcom,invert = <1>; /* Enable MPP */
+ qcom,ain-route = <3>; /* AMUX 8 */
+ qcom,master-en = <1>;
+ qcom,src-sel = <0>; /* Function constant */
+ };
+ };
+
+ pm8950_gpios: gpios {
+ spmi-dev-container;
+ compatible = "qcom,qpnp-pin";
+ gpio-controller;
+ #gpio-cells = <2>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ label = "pm8950-gpio";
+
+ gpio@c000 {
+ reg = <0xc000 0x100>;
+ qcom,pin-num = <1>;
+ status = "disabled";
+ };
+
+ gpio@c100 {
+ reg = <0xc100 0x100>;
+ qcom,pin-num = <2>;
+ status = "disabled";
+ };
+
+ gpio@c200 {
+ reg = <0xc200 0x100>;
+ qcom,pin-num = <3>;
+ status = "disabled";
+ };
+
+ gpio@c300 {
+ reg = <0xc300 0x100>;
+ qcom,pin-num = <4>;
+ status = "disabled";
+ };
+
+ gpio@c400 {
+ reg = <0xc400 0x100>;
+ qcom,pin-num = <5>;
+ status = "disabled";
+ };
+
+ gpio@c500 {
+ reg = <0xc500 0x100>;
+ qcom,pin-num = <6>;
+ status = "disabled";
+ };
+
+ gpio@c600 {
+ reg = <0xc600 0x100>;
+ qcom,pin-num = <7>;
+ status = "disabled";
+ };
+
+ gpio@c700 {
+ reg = <0xc700 0x100>;
+ qcom,pin-num = <8>;
+ status = "disabled";
+ };
+ };
+
+ pm8950_vadc: vadc@3100 {
+ compatible = "qcom,qpnp-vadc";
+ reg = <0x3100 0x100>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <0x0 0x31 0x0>;
+ interrupt-names = "eoc-int-en-set";
+ qcom,adc-bit-resolution = <15>;
+ qcom,adc-vdd-reference = <1800>;
+ qcom,vadc-poll-eoc;
+ qcom,pmic-revid = <&pm8950_revid>;
+
+ chan@5 {
+ label = "vcoin";
+ reg = <5>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <1>;
+ qcom,calibration-type = "absolute";
+ qcom,scale-function = <0>;
+ qcom,hw-settle-time = <0>;
+ qcom,fast-avg-setup = <0>;
+ };
+
+ chan@7 {
+ label = "vph_pwr";
+ reg = <7>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <1>;
+ qcom,calibration-type = "absolute";
+ qcom,scale-function = <0>;
+ qcom,hw-settle-time = <0>;
+ qcom,fast-avg-setup = <0>;
+ };
+
+ chan@8 {
+ label = "die_temp";
+ reg = <8>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "absolute";
+ qcom,scale-function = <3>;
+ qcom,hw-settle-time = <0>;
+ qcom,fast-avg-setup = <0>;
+ };
+
+ chan@9 {
+ label = "ref_625mv";
+ reg = <9>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "absolute";
+ qcom,scale-function = <0>;
+ qcom,hw-settle-time = <0>;
+ qcom,fast-avg-setup = <0>;
+ };
+
+ chan@a {
+ label = "ref_1250v";
+ reg = <0xa>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "absolute";
+ qcom,scale-function = <0>;
+ qcom,hw-settle-time = <0>;
+ qcom,fast-avg-setup = <0>;
+ };
+
+ chan@c {
+ label = "ref_buf_625mv";
+ reg = <0xc>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "absolute";
+ qcom,scale-function = <0>;
+ qcom,hw-settle-time = <0>;
+ qcom,fast-avg-setup = <0>;
+ };
+
+ chan@36 {
+ label = "pa_therm0";
+ reg = <0x36>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <2>;
+ qcom,hw-settle-time = <2>;
+ qcom,fast-avg-setup = <0>;
+ };
+
+ chan@11 {
+ label = "pa_therm1";
+ reg = <0x11>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <2>;
+ qcom,hw-settle-time = <2>;
+ qcom,fast-avg-setup = <0>;
+ qcom,vadc-thermal-node;
+ };
+
+ chan@32 {
+ label = "xo_therm";
+ reg = <0x32>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <4>;
+ qcom,hw-settle-time = <2>;
+ qcom,fast-avg-setup = <0>;
+ qcom,vadc-thermal-node;
+ };
+
+ chan@3c {
+ label = "xo_therm_buf";
+ reg = <0x3c>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <4>;
+ qcom,hw-settle-time = <2>;
+ qcom,fast-avg-setup = <0>;
+ qcom,vadc-thermal-node;
+ };
+
+ chan@13 {
+ label = "case_therm";
+ reg = <0x13>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <2>;
+ qcom,hw-settle-time = <2>;
+ qcom,fast-avg-setup = <0>;
+ qcom,vadc-thermal-node;
+ };
+ };
+
+ pm8950_adc_tm: vadc@3400 {
+ compatible = "qcom,qpnp-adc-tm";
+ reg = <0x3400 0x100>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <0x0 0x34 0x0>,
+ <0x0 0x34 0x3>,
+ <0x0 0x34 0x4>;
+ interrupt-names = "eoc-int-en-set",
+ "high-thr-en-set",
+ "low-thr-en-set";
+ qcom,adc-bit-resolution = <15>;
+ qcom,adc-vdd-reference = <1800>;
+ qcom,adc_tm-vadc = <&pm8950_vadc>;
+ qcom,pmic-revid = <&pm8950_revid>;
+
+ chan@36 {
+ label = "pa_therm0";
+ reg = <0x36>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <2>;
+ qcom,hw-settle-time = <2>;
+ qcom,fast-avg-setup = <0>;
+ qcom,btm-channel-number = <0x48>;
+ qcom,thermal-node;
+ };
+
+ chan@7 {
+ label = "vph_pwr";
+ reg = <0x7>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <1>;
+ qcom,calibration-type = "absolute";
+ qcom,scale-function = <0>;
+ qcom,hw-settle-time = <0>;
+ qcom,fast-avg-setup = <0>;
+ qcom,btm-channel-number = <0x68>;
+ };
+ };
+
+ pm8950_rtc: qcom,pm8950_rtc {
+ spmi-dev-container;
+ compatible = "qcom,qpnp-rtc";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ qcom,qpnp-rtc-write = <0>;
+ qcom,qpnp-rtc-alarm-pwrup = <0>;
+
+ qcom,pm8950_rtc_rw@6000 {
+ reg = <0x6000 0x100>;
+ };
+
+ qcom,pm8950_rtc_alarm@6100 {
+ reg = <0x6100 0x100>;
+ interrupts = <0x0 0x61 0x1>;
+ };
+ };
+
+ qcom,leds@a300 {
+ compatible = "qcom,leds-qpnp";
+ reg = <0xa300 0x100>;
+ label = "mpp";
+ };
+ };
+
+ pm8950_1: qcom,pm8950@1 {
+ compatible ="qcom,spmi-pmic";
+ reg = <0x1 SPMI_USID>;
+ #address-cells = <2>;
+ #size-cells = <0>;
+
+ pm8950_pwm: pwm@bc00 {
+ status = "disabled";
+ compatible = "qcom,qpnp-pwm";
+ reg = <0xbc00 0x100>;
+ reg-names = "qpnp-lpg-channel-base";
+ qcom,channel-id = <0>;
+ qcom,supported-sizes = <6>, <9>;
+ #pwm-cells = <2>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/qcom/pmi8950.dtsi b/arch/arm/boot/dts/qcom/pmi8950.dtsi
new file mode 100644
index 0000000..0ec1f0b
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/pmi8950.dtsi
@@ -0,0 +1,641 @@
+/* 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 <dt-bindings/msm/power-on.h>
+
+&spmi_bus {
+ qcom,pmi8950@2 {
+ compatible ="qcom,spmi-pmic";
+ reg = <0x2 SPMI_USID>;
+ #address-cells = <2>;
+ #size-cells = <0>;
+
+ pmi8950_revid: qcom,revid@100 {
+ compatible = "qcom,qpnp-revid";
+ reg = <0x100 0x100>;
+ };
+
+ qcom,power-on@800 {
+ compatible = "qcom,qpnp-power-on";
+ reg = <0x800 0x100>;
+ qcom,secondary-pon-reset;
+ qcom,hard-reset-poweroff-type =
+ <PON_POWER_OFF_SHUTDOWN>;
+
+ pon_perph_reg: qcom,pon_perph_reg {
+ regulator-name = "pon_spare_reg";
+ qcom,pon-spare-reg-addr = <0x8c>;
+ qcom,pon-spare-reg-bit = <1>;
+ };
+ };
+
+ pmi8950_vadc: vadc@3100 {
+ compatible = "qcom,qpnp-vadc";
+ reg = <0x3100 0x100>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <0x2 0x31 0x0>;
+ interrupt-names = "eoc-int-en-set";
+ qcom,adc-bit-resolution = <15>;
+ qcom,adc-vdd-reference = <1800>;
+ qcom,vadc-poll-eoc;
+
+ chan@0 {
+ label = "usbin";
+ reg = <0>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <4>;
+ qcom,calibration-type = "absolute";
+ qcom,scale-function = <0>;
+ qcom,hw-settle-time = <0>;
+ qcom,fast-avg-setup = <0>;
+ };
+
+ chan@1 {
+ label = "dcin";
+ reg = <1>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <4>;
+ qcom,calibration-type = "absolute";
+ qcom,scale-function = <0>;
+ qcom,hw-settle-time = <0>;
+ qcom,fast-avg-setup = <0>;
+ };
+
+ chan@3 {
+ label = "vchg_sns";
+ reg = <3>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <1>;
+ qcom,calibration-type = "absolute";
+ qcom,scale-function = <0>;
+ qcom,hw-settle-time = <0>;
+ qcom,fast-avg-setup = <0>;
+ };
+
+ chan@9 {
+ label = "ref_625mv";
+ reg = <9>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "absolute";
+ qcom,scale-function = <0>;
+ qcom,hw-settle-time = <0>;
+ qcom,fast-avg-setup = <0>;
+ };
+
+ chan@a {
+ label = "ref_1250v";
+ reg = <0xa>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "absolute";
+ qcom,scale-function = <0>;
+ qcom,hw-settle-time = <0>;
+ qcom,fast-avg-setup = <0>;
+ };
+
+ chan@d {
+ label = "chg_temp";
+ reg = <0xd>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "absolute";
+ qcom,scale-function = <16>;
+ qcom,hw-settle-time = <0>;
+ qcom,fast-avg-setup = <0>;
+ qcom,vadc-thermal-node;
+ };
+
+ chan@43 {
+ label = "usb_dp";
+ reg = <0x43>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <1>;
+ qcom,calibration-type = "absolute";
+ qcom,scale-function = <0>;
+ qcom,hw-settle-time = <0>;
+ qcom,fast-avg-setup = <0>;
+ };
+
+ chan@44 {
+ label = "usb_dm";
+ reg = <0x44>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <1>;
+ qcom,calibration-type = "absolute";
+ qcom,scale-function = <0>;
+ qcom,hw-settle-time = <0>;
+ qcom,fast-avg-setup = <0>;
+ };
+ };
+
+ pmi8950_gpios: gpios {
+ spmi-dev-container;
+ compatible = "qcom,qpnp-pin";
+ gpio-controller;
+ #gpio-cells = <2>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ label = "pmi8950-gpio";
+
+ gpio@c000 {
+ reg = <0xc000 0x100>;
+ qcom,pin-num = <1>;
+ status = "disabled";
+ };
+
+ gpio@c100 {
+ reg = <0xc100 0x100>;
+ qcom,pin-num = <2>;
+ status = "disabled";
+ };
+ };
+
+ pmi8950_mpps: mpps {
+ spmi-dev-container;
+ compatible = "qcom,qpnp-pin";
+ gpio-controller;
+ #gpio-cells = <2>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ label = "pmi8950-mpp";
+
+ mpp@a000 {
+ reg = <0xa000 0x100>;
+ qcom,pin-num = <1>;
+ status = "disabled";
+ };
+
+ mpp@a100 {
+ reg = <0xa100 0x100>;
+ qcom,pin-num = <2>;
+ status = "disabled";
+ };
+
+ mpp@a200 {
+ reg = <0xa200 0x100>;
+ qcom,pin-num = <3>;
+ status = "disabled";
+ };
+
+ mpp@a300 {
+ reg = <0xa300 0x100>;
+ qcom,pin-num = <4>;
+ status = "disabled";
+ };
+ };
+
+ pmi8950_charger: qcom,qpnp-smbcharger {
+ spmi-dev-container;
+ compatible = "qcom,qpnp-smbcharger";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ qcom,iterm-ma = <100>;
+ qcom,float-voltage-mv = <4200>;
+ qcom,resume-delta-mv = <200>;
+ qcom,chg-inhibit-fg;
+ qcom,rparasitic-uohm = <100000>;
+ qcom,bms-psy-name = "bms";
+ qcom,thermal-mitigation = <1500 700 600 0>;
+ qcom,parallel-usb-min-current-ma = <1400>;
+ qcom,parallel-usb-9v-min-current-ma = <900>;
+ qcom,parallel-allowed-lowering-ma = <500>;
+ qcom,pmic-revid = <&pmi8950_revid>;
+ qcom,force-aicl-rerun;
+ qcom,aicl-rerun-period-s = <180>;
+ qcom,autoadjust-vfloat;
+
+ qcom,chgr@1000 {
+ reg = <0x1000 0x100>;
+ interrupts = <0x2 0x10 0x0>,
+ <0x2 0x10 0x1>,
+ <0x2 0x10 0x2>,
+ <0x2 0x10 0x3>,
+ <0x2 0x10 0x4>,
+ <0x2 0x10 0x5>,
+ <0x2 0x10 0x6>,
+ <0x2 0x10 0x7>;
+
+ interrupt-names = "chg-error",
+ "chg-inhibit",
+ "chg-prechg-sft",
+ "chg-complete-chg-sft",
+ "chg-p2f-thr",
+ "chg-rechg-thr",
+ "chg-taper-thr",
+ "chg-tcc-thr";
+ };
+
+ qcom,otg@1100 {
+ reg = <0x1100 0x100>;
+ interrupts = <0x2 0x11 0x0>,
+ <0x2 0x11 0x1>,
+ <0x2 0x11 0x3>;
+ interrupt-names = "otg-fail",
+ "otg-oc",
+ "usbid-change";
+ };
+
+ qcom,bat-if@1200 {
+ reg = <0x1200 0x100>;
+ interrupts = <0x2 0x12 0x0>,
+ <0x2 0x12 0x1>,
+ <0x2 0x12 0x2>,
+ <0x2 0x12 0x3>,
+ <0x2 0x12 0x4>,
+ <0x2 0x12 0x5>,
+ <0x2 0x12 0x6>,
+ <0x2 0x12 0x7>;
+
+ interrupt-names = "batt-hot",
+ "batt-warm",
+ "batt-cold",
+ "batt-cool",
+ "batt-ov",
+ "batt-low",
+ "batt-missing",
+ "batt-term-missing";
+ };
+
+ qcom,usb-chgpth@1300 {
+ reg = <0x1300 0x100>;
+ interrupts = <0x2 0x13 0x0>,
+ <0x2 0x13 0x1>,
+ <0x2 0x13 0x2>,
+ <0x2 0x13 0x5>;
+
+ interrupt-names = "usbin-uv",
+ "usbin-ov",
+ "usbin-src-det",
+ "aicl-done";
+ };
+
+ qcom,dc-chgpth@1400 {
+ reg = <0x1400 0x100>;
+ interrupts = <0x2 0x14 0x0>,
+ <0x2 0x14 0x1>;
+ interrupt-names = "dcin-uv",
+ "dcin-ov";
+ };
+
+ qcom,chgr-misc@1600 {
+ reg = <0x1600 0x100>;
+ interrupts = <0x2 0x16 0x0>,
+ <0x2 0x16 0x1>,
+ <0x2 0x16 0x2>,
+ <0x2 0x16 0x3>,
+ <0x2 0x16 0x4>,
+ <0x2 0x16 0x5>;
+
+ interrupt-names = "power-ok",
+ "temp-shutdown",
+ "wdog-timeout",
+ "flash-fail",
+ "otst2",
+ "otst3";
+ };
+
+ smbcharger_charger_otg: qcom,smbcharger-boost-otg {
+ regulator-name = "smbcharger_charger_otg";
+ };
+ };
+
+ pmi8950_fg: qcom,fg {
+ spmi-dev-container;
+ compatible = "qcom,qpnp-fg";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ qcom,resume-soc = <95>;
+ status = "okay";
+ qcom,bcl-lm-threshold-ma = <127>;
+ qcom,bcl-mh-threshold-ma = <405>;
+ qcom,fg-iterm-ma = <150>;
+ qcom,fg-chg-iterm-ma = <100>;
+ qcom,pmic-revid = <&pmi8950_revid>;
+ qcom,fg-cutoff-voltage-mv = <3500>;
+ qcom,cycle-counter-en;
+ qcom,capacity-learning-on;
+
+ qcom,fg-soc@4000 {
+ status = "okay";
+ reg = <0x4000 0x100>;
+ interrupts = <0x2 0x40 0x0>,
+ <0x2 0x40 0x1>,
+ <0x2 0x40 0x2>,
+ <0x2 0x40 0x3>,
+ <0x2 0x40 0x4>,
+ <0x2 0x40 0x5>,
+ <0x2 0x40 0x6>;
+
+ interrupt-names = "high-soc",
+ "low-soc",
+ "full-soc",
+ "empty-soc",
+ "delta-soc",
+ "first-est-done",
+ "update-soc";
+ };
+
+ qcom,fg-batt@4100 {
+ reg = <0x4100 0x100>;
+ interrupts = <0x2 0x41 0x0>,
+ <0x2 0x41 0x1>,
+ <0x2 0x41 0x2>,
+ <0x2 0x41 0x3>,
+ <0x2 0x41 0x4>,
+ <0x2 0x41 0x5>,
+ <0x2 0x41 0x6>,
+ <0x2 0x41 0x7>;
+
+ interrupt-names = "soft-cold",
+ "soft-hot",
+ "vbatt-low",
+ "batt-ided",
+ "batt-id-req",
+ "batt-unknown",
+ "batt-missing",
+ "batt-match";
+ };
+
+ qcom,revid-tp-rev@1f1 {
+ reg = <0x1f1 0x1>;
+ };
+
+ qcom,fg-memif@4400 {
+ status = "okay";
+ reg = <0x4400 0x100>;
+ interrupts = <0x2 0x44 0x0>,
+ <0x2 0x44 0x2>;
+
+ interrupt-names = "mem-avail",
+ "data-rcvry-sug";
+ };
+ };
+
+ bcl@4200 {
+ compatible = "qcom,msm-bcl";
+ reg = <0x4200 0xFF 0x88E 0x2>;
+ reg-names = "fg_user_adc", "pon_spare";
+ interrupts = <0x2 0x42 0x0>,
+ <0x2 0x42 0x1>;
+ interrupt-names = "bcl-high-ibat-int",
+ "bcl-low-vbat-int";
+ qcom,vbat-scaling-factor = <39000>;
+ qcom,vbat-gain-numerator = <1>;
+ qcom,vbat-gain-denominator = <128>;
+ qcom,vbat-polling-delay-ms = <100>;
+ qcom,ibat-scaling-factor = <39000>;
+ qcom,ibat-gain-numerator = <1>;
+ qcom,ibat-gain-denominator = <128>;
+ qcom,ibat-offset-numerator = <1200>;
+ qcom,ibat-offset-denominator = <1>;
+ qcom,ibat-polling-delay-ms = <100>;
+ qcom,inhibit-derating-ua = <550000>;
+ };
+
+ qcom,leds@a100 {
+ compatible = "qcom,leds-qpnp";
+ reg = <0xa100 0x100>;
+ label = "mpp";
+ };
+ };
+
+ qcom,pmi8950@3 {
+ compatible ="qcom,spmi-pmic";
+ reg = <0x3 SPMI_USID>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ pmi8950_pwm: pwm@b000 {
+ status = "disabled";
+ compatible = "qcom,qpnp-pwm";
+ reg = <0xb000 0x100>;
+ reg-names = "qpnp-lpg-channel-base";
+ qcom,channel-id = <0>;
+ qcom,supported-sizes = <6>, <9>;
+ #pwm-cells = <2>;
+ };
+
+ labibb: qpnp-labibb-regulator {
+ status = "disabled";
+ spmi-dev-container;
+ compatible = "qcom,qpnp-labibb-regulator";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ qcom,pmic-revid = <&pmi8950_revid>;
+
+ ibb_regulator: qcom,ibb@dc00 {
+ reg = <0xdc00 0x100>;
+ reg-names = "ibb_reg";
+ regulator-name = "ibb_reg";
+
+ regulator-min-microvolt = <4600000>;
+ regulator-max-microvolt = <6000000>;
+
+ qcom,qpnp-ibb-min-voltage = <1400000>;
+ qcom,qpnp-ibb-step-size = <100000>;
+ qcom,qpnp-ibb-slew-rate = <2000000>;
+ qcom,qpnp-ibb-use-default-voltage;
+ qcom,qpnp-ibb-init-voltage = <5500000>;
+ qcom,qpnp-ibb-init-amoled-voltage = <4000000>;
+ qcom,qpnp-ibb-init-lcd-voltage = <5500000>;
+
+ qcom,qpnp-ibb-soft-start = <1000>;
+
+ qcom,qpnp-ibb-discharge-resistor = <32>;
+ qcom,qpnp-ibb-lab-pwrup-delay = <8000>;
+ qcom,qpnp-ibb-lab-pwrdn-delay = <8000>;
+ qcom,qpnp-ibb-en-discharge;
+
+ qcom,qpnp-ibb-full-pull-down;
+ qcom,qpnp-ibb-pull-down-enable;
+ qcom,qpnp-ibb-switching-clock-frequency =
+ <1480>;
+ qcom,qpnp-ibb-limit-maximum-current = <1550>;
+ qcom,qpnp-ibb-debounce-cycle = <16>;
+ qcom,qpnp-ibb-limit-max-current-enable;
+ qcom,qpnp-ibb-ps-enable;
+ };
+
+ lab_regulator: qcom,lab@de00 {
+ reg = <0xde00 0x100>;
+ reg-names = "lab";
+ regulator-name = "lab_reg";
+
+ regulator-min-microvolt = <4600000>;
+ regulator-max-microvolt = <6000000>;
+
+ qcom,qpnp-lab-min-voltage = <4600000>;
+ qcom,qpnp-lab-step-size = <100000>;
+ qcom,qpnp-lab-slew-rate = <5000>;
+ qcom,qpnp-lab-use-default-voltage;
+ qcom,qpnp-lab-init-voltage = <5500000>;
+ qcom,qpnp-lab-init-amoled-voltage = <4600000>;
+ qcom,qpnp-lab-init-lcd-voltage = <5500000>;
+
+ qcom,qpnp-lab-soft-start = <800>;
+
+ qcom,qpnp-lab-full-pull-down;
+ qcom,qpnp-lab-pull-down-enable;
+ qcom,qpnp-lab-switching-clock-frequency =
+ <1600>;
+ qcom,qpnp-lab-limit-maximum-current = <800>;
+ qcom,qpnp-lab-limit-max-current-enable;
+ qcom,qpnp-lab-ps-threshold = <40>;
+ qcom,qpnp-lab-ps-enable;
+ qcom,qpnp-lab-nfet-size = <100>;
+ qcom,qpnp-lab-pfet-size = <100>;
+ qcom,qpnp-lab-max-precharge-time = <500>;
+ };
+
+ };
+
+ wled: qcom,leds@d800 {
+ compatible = "qcom,qpnp-wled";
+ reg = <0xd800 0x100>,
+ <0xd900 0x100>,
+ <0xdc00 0x100>,
+ <0xde00 0x100>;
+ reg-names = "qpnp-wled-ctrl-base",
+ "qpnp-wled-sink-base",
+ "qpnp-wled-ibb-base",
+ "qpnp-wled-lab-base";
+ interrupts = <0x3 0xd8 0x2>;
+ interrupt-names = "sc-irq";
+ status = "okay";
+ linux,name = "wled";
+ linux,default-trigger = "bkl-trigger";
+ qcom,fdbk-output = "auto";
+ qcom,vref-mv = <350>;
+ qcom,switch-freq-khz = <800>;
+ qcom,ovp-mv = <29500>;
+ qcom,ilim-ma = <980>;
+ qcom,boost-duty-ns = <26>;
+ qcom,mod-freq-khz = <9600>;
+ qcom,dim-mode = "hybrid";
+ qcom,dim-method = "linear";
+ qcom,hyb-thres = <625>;
+ qcom,sync-dly-us = <800>;
+ qcom,fs-curr-ua = <20000>;
+ qcom,led-strings-list = [00 01];
+ qcom,en-ext-pfet-sc-pro;
+ qcom,cons-sync-write-delay-us = <1000>;
+ };
+
+ flash_led: qcom,leds@d300 {
+ compatible = "qcom,qpnp-flash-led";
+ status = "okay";
+ reg = <0xd300 0x100>;
+ label = "flash";
+ qcom,headroom = <500>;
+ qcom,startup-dly = <128>;
+ qcom,clamp-curr = <200>;
+ qcom,pmic-charger-support;
+ qcom,self-check-enabled;
+ qcom,thermal-derate-enabled;
+ qcom,thermal-derate-threshold = <100>;
+ qcom,thermal-derate-rate = "5_PERCENT";
+ qcom,current-ramp-enabled;
+ qcom,ramp_up_step = "6P7_US";
+ qcom,ramp_dn_step = "6P7_US";
+ qcom,vph-pwr-droop-enabled;
+ qcom,vph-pwr-droop-threshold = <3000>;
+ qcom,vph-pwr-droop-debounce-time = <10>;
+ qcom,headroom-sense-ch0-enabled;
+ qcom,headroom-sense-ch1-enabled;
+ qcom,pmic-revid = <&pmi8950_revid>;
+
+ pmi8950_flash0: qcom,flash_0 {
+ label = "flash";
+ qcom,led-name = "led:flash_0";
+ qcom,default-led-trigger =
+ "flash0_trigger";
+ qcom,max-current = <1000>;
+ qcom,duration = <1280>;
+ qcom,id = <0>;
+ qcom,current = <625>;
+ };
+
+ pmi8950_flash1: qcom,flash_1 {
+ label = "flash";
+ qcom,led-name = "led:flash_1";
+ qcom,default-led-trigger =
+ "flash1_trigger";
+ qcom,max-current = <1000>;
+ qcom,duration = <1280>;
+ qcom,id = <1>;
+ qcom,current = <625>;
+ };
+
+ pmi8950_torch0: qcom,torch_0 {
+ label = "torch";
+ qcom,led-name = "led:torch_0";
+ qcom,default-led-trigger =
+ "torch0_trigger";
+ qcom,max-current = <200>;
+ qcom,id = <0>;
+ qcom,current = <120>;
+ };
+
+ pmi8950_torch1: qcom,torch_1 {
+ label = "torch";
+ qcom,led-name = "led:torch_1";
+ qcom,default-led-trigger =
+ "torch1_trigger";
+ qcom,max-current = <200>;
+ qcom,id = <1>;
+ qcom,current = <120>;
+ };
+
+ pmi8950_switch: qcom,switch {
+ label = "switch";
+ qcom,led-name = "led:switch";
+ qcom,default-led-trigger =
+ "switch_trigger";
+ qcom,max-current = <1000>;
+ qcom,duration = <1280>;
+ qcom,id = <2>;
+ qcom,current = <625>;
+ reg0 {
+ regulator-name = "pon_spare_reg";
+ };
+ };
+ };
+
+ pmi_haptic: qcom,haptic@c000 {
+ compatible = "qcom,qpnp-haptic";
+ reg = <0xc000 0x100>;
+ interrupts = <0x3 0xc0 0x0>,
+ <0x3 0xc0 0x1>;
+ interrupt-names = "sc-irq", "play-irq";
+ qcom,pmic-revid = <&pmi8950_revid>;
+ vcc_pon-supply = <&pon_perph_reg>;
+ qcom,play-mode = "direct";
+ qcom,wave-play-rate-us = <5263>;
+ qcom,actuator-type = "erm";
+ qcom,wave-shape = "square";
+ qcom,vmax-mv = <2000>;
+ qcom,ilim-ma = <800>;
+ qcom,sc-deb-cycles = <8>;
+ qcom,int-pwm-freq-khz = <505>;
+ qcom,en-brake;
+ qcom,brake-pattern = [03 03 00 00];
+ qcom,use-play-irq;
+ qcom,use-sc-irq;
+ qcom,wave-samples = [3e 3e 3e 3e 3e 3e 3e 3e];
+ qcom,wave-rep-cnt = <1>;
+ qcom,wave-samp-rep-cnt = <1>;
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/msm-arm-smmu-sdm670.dtsi b/arch/arm64/boot/dts/qcom/msm-arm-smmu-sdm670.dtsi
index 8e5d854..25a332b 100644
--- a/arch/arm64/boot/dts/qcom/msm-arm-smmu-sdm670.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm-arm-smmu-sdm670.dtsi
@@ -36,11 +36,9 @@
<GIC_SPI 371 IRQ_TYPE_EDGE_RISING>;
clock-names = "gcc_ddrss_gpu_axi_clk",
"gcc_gpu_memnoc_gfx_clk",
- "gpu_cc_ahb_clk",
"gpu_cc_cx_gmu_clk";
clocks = <&clock_gcc GCC_DDRSS_GPU_AXI_CLK>,
<&clock_gcc GCC_GPU_MEMNOC_GFX_CLK>,
- <&clock_gpucc GPU_CC_AHB_CLK>,
<&clock_gpucc GPU_CC_CX_GMU_CLK>;
attach-impl-defs =
<0x6000 0x2378>,
diff --git a/arch/arm64/boot/dts/qcom/msm-arm-smmu-sdm845.dtsi b/arch/arm64/boot/dts/qcom/msm-arm-smmu-sdm845.dtsi
index faeaa9e..0a8fb4a 100644
--- a/arch/arm64/boot/dts/qcom/msm-arm-smmu-sdm845.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm-arm-smmu-sdm845.dtsi
@@ -35,10 +35,8 @@
<GIC_SPI 369 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 370 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 371 IRQ_TYPE_EDGE_RISING>;
- clock-names = "gcc_gpu_memnoc_gfx_clk",
- "gpu_cc_ahb_clk";
- clocks = <&clock_gcc GCC_GPU_MEMNOC_GFX_CLK>,
- <&clock_gpucc GPU_CC_AHB_CLK>;
+ clock-names = "gcc_gpu_memnoc_gfx_clk";
+ clocks = <&clock_gcc GCC_GPU_MEMNOC_GFX_CLK>;
attach-impl-defs =
<0x6000 0x2378>,
<0x6060 0x1055>,
diff --git a/arch/arm64/boot/dts/qcom/msm-gdsc-sdm845.dtsi b/arch/arm64/boot/dts/qcom/msm-gdsc-sdm845.dtsi
index dcc646c93b..b43c876 100644
--- a/arch/arm64/boot/dts/qcom/msm-gdsc-sdm845.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm-gdsc-sdm845.dtsi
@@ -181,6 +181,8 @@
qcom,poll-cfg-gdscr;
qcom,support-hw-trigger;
status = "disabled";
+ proxy-supply = <&mdss_core_gdsc>;
+ qcom,proxy-consumer-enable;
};
/* GDSCs in Graphics CC */
diff --git a/arch/arm64/boot/dts/qcom/pm660.dtsi b/arch/arm64/boot/dts/qcom/pm660.dtsi
index 1fdb3f6..df5a970 100644
--- a/arch/arm64/boot/dts/qcom/pm660.dtsi
+++ b/arch/arm64/boot/dts/qcom/pm660.dtsi
@@ -371,6 +371,16 @@
"bcl-crit-low-vbat";
#thermal-sensor-cells = <1>;
};
+
+ pm660_div_clk: qcom,clkdiv@5b00 {
+ compatible = "qcom,qpnp-clkdiv";
+ reg = <0x5b00 0x100>;
+ #clock-cells = <1>;
+ qcom,cxo-freq = <19200000>;
+ qcom,clkdiv-id = <1>;
+ qcom,clkdiv-init-freq = <19200000>;
+ status = "disabled";
+ };
};
pm660_1: qcom,pm660@1 {
diff --git a/arch/arm64/boot/dts/qcom/pm8950.dtsi b/arch/arm64/boot/dts/qcom/pm8950.dtsi
new file mode 100644
index 0000000..f47872a
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/pm8950.dtsi
@@ -0,0 +1,388 @@
+/* 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.
+ */
+
+&spmi_bus {
+ qcom,pm8950@0 {
+ compatible ="qcom,spmi-pmic";
+ reg = <0x0 SPMI_USID>;
+ #address-cells = <2>;
+ #size-cells = <0>;
+
+ pm8950_revid: qcom,revid@100 {
+ compatible = "qcom,qpnp-revid";
+ reg = <0x100 0x100>;
+ };
+
+ pm8950_temp_alarm: qcom,temp-alarm@2400 {
+ compatible = "qcom,qpnp-temp-alarm";
+ reg = <0x2400 0x100>;
+ interrupts = <0x0 0x24 0x0>;
+ label = "pm8950_tz";
+ qcom,channel-num = <8>;
+ qcom,threshold-set = <0>;
+ qcom,temp_alarm-vadc = <&pm8950_vadc>;
+ };
+
+ qcom,power-on@800 {
+ compatible = "qcom,qpnp-power-on";
+ reg = <0x800 0x100>;
+ interrupts = <0x0 0x8 0x0>,
+ <0x0 0x8 0x1>,
+ <0x0 0x8 0x4>,
+ <0x0 0x8 0x5>;
+ interrupt-names = "kpdpwr", "resin",
+ "resin-bark", "kpdpwr-resin-bark";
+ qcom,pon-dbc-delay = <15625>;
+ qcom,system-reset;
+
+ qcom,pon_1 {
+ qcom,pon-type = <0>;
+ qcom,pull-up = <1>;
+ linux,code = <116>;
+ };
+
+ qcom,pon_2 {
+ qcom,pon-type = <1>;
+ qcom,pull-up = <1>;
+ linux,code = <114>;
+ };
+ };
+
+ pm8950_coincell: qcom,coincell@2800 {
+ compatible = "qcom,qpnp-coincell";
+ reg = <0x2800 0x100>;
+ };
+
+ pm8950_mpps: mpps {
+ compatible = "qcom,qpnp-pin";
+ spmi-dev-container;
+ gpio-controller;
+ #gpio-cells = <2>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ label = "pm8950-mpp";
+
+ mpp@a000 {
+ reg = <0xa000 0x100>;
+ qcom,pin-num = <1>;
+ status = "disabled";
+ };
+
+ mpp@a100 {
+ /* MPP2 - PA_THERM config */
+ reg = <0xa100 0x100>;
+ qcom,pin-num = <2>;
+ qcom,mode = <4>; /* AIN input */
+ qcom,invert = <1>; /* Enable MPP */
+ qcom,ain-route = <1>; /* AMUX 6 */
+ qcom,master-en = <1>;
+ qcom,src-sel = <0>; /* Function constant */
+ };
+
+ mpp@a200 {
+ reg = <0xa200 0x100>;
+ qcom,pin-num = <3>;
+ status = "disabled";
+ };
+
+ mpp@a300 {
+ /* MPP4 - CASE_THERM config */
+ reg = <0xa300 0x100>;
+ qcom,pin-num = <4>;
+ qcom,mode = <4>; /* AIN input */
+ qcom,invert = <1>; /* Enable MPP */
+ qcom,ain-route = <3>; /* AMUX 8 */
+ qcom,master-en = <1>;
+ qcom,src-sel = <0>; /* Function constant */
+ };
+ };
+
+ pm8950_gpios: gpios {
+ spmi-dev-container;
+ compatible = "qcom,qpnp-pin";
+ gpio-controller;
+ #gpio-cells = <2>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ label = "pm8950-gpio";
+
+ gpio@c000 {
+ reg = <0xc000 0x100>;
+ qcom,pin-num = <1>;
+ status = "disabled";
+ };
+
+ gpio@c100 {
+ reg = <0xc100 0x100>;
+ qcom,pin-num = <2>;
+ status = "disabled";
+ };
+
+ gpio@c200 {
+ reg = <0xc200 0x100>;
+ qcom,pin-num = <3>;
+ status = "disabled";
+ };
+
+ gpio@c300 {
+ reg = <0xc300 0x100>;
+ qcom,pin-num = <4>;
+ status = "disabled";
+ };
+
+ gpio@c400 {
+ reg = <0xc400 0x100>;
+ qcom,pin-num = <5>;
+ status = "disabled";
+ };
+
+ gpio@c500 {
+ reg = <0xc500 0x100>;
+ qcom,pin-num = <6>;
+ status = "disabled";
+ };
+
+ gpio@c600 {
+ reg = <0xc600 0x100>;
+ qcom,pin-num = <7>;
+ status = "disabled";
+ };
+
+ gpio@c700 {
+ reg = <0xc700 0x100>;
+ qcom,pin-num = <8>;
+ status = "disabled";
+ };
+ };
+
+ pm8950_vadc: vadc@3100 {
+ compatible = "qcom,qpnp-vadc";
+ reg = <0x3100 0x100>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <0x0 0x31 0x0>;
+ interrupt-names = "eoc-int-en-set";
+ qcom,adc-bit-resolution = <15>;
+ qcom,adc-vdd-reference = <1800>;
+ qcom,vadc-poll-eoc;
+ qcom,pmic-revid = <&pm8950_revid>;
+
+ chan@5 {
+ label = "vcoin";
+ reg = <5>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <1>;
+ qcom,calibration-type = "absolute";
+ qcom,scale-function = <0>;
+ qcom,hw-settle-time = <0>;
+ qcom,fast-avg-setup = <0>;
+ };
+
+ chan@7 {
+ label = "vph_pwr";
+ reg = <7>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <1>;
+ qcom,calibration-type = "absolute";
+ qcom,scale-function = <0>;
+ qcom,hw-settle-time = <0>;
+ qcom,fast-avg-setup = <0>;
+ };
+
+ chan@8 {
+ label = "die_temp";
+ reg = <8>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "absolute";
+ qcom,scale-function = <3>;
+ qcom,hw-settle-time = <0>;
+ qcom,fast-avg-setup = <0>;
+ };
+
+ chan@9 {
+ label = "ref_625mv";
+ reg = <9>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "absolute";
+ qcom,scale-function = <0>;
+ qcom,hw-settle-time = <0>;
+ qcom,fast-avg-setup = <0>;
+ };
+
+ chan@a {
+ label = "ref_1250v";
+ reg = <0xa>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "absolute";
+ qcom,scale-function = <0>;
+ qcom,hw-settle-time = <0>;
+ qcom,fast-avg-setup = <0>;
+ };
+
+ chan@c {
+ label = "ref_buf_625mv";
+ reg = <0xc>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "absolute";
+ qcom,scale-function = <0>;
+ qcom,hw-settle-time = <0>;
+ qcom,fast-avg-setup = <0>;
+ };
+
+ chan@36 {
+ label = "pa_therm0";
+ reg = <0x36>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <2>;
+ qcom,hw-settle-time = <2>;
+ qcom,fast-avg-setup = <0>;
+ };
+
+ chan@11 {
+ label = "pa_therm1";
+ reg = <0x11>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <2>;
+ qcom,hw-settle-time = <2>;
+ qcom,fast-avg-setup = <0>;
+ qcom,vadc-thermal-node;
+ };
+
+ chan@32 {
+ label = "xo_therm";
+ reg = <0x32>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <4>;
+ qcom,hw-settle-time = <2>;
+ qcom,fast-avg-setup = <0>;
+ qcom,vadc-thermal-node;
+ };
+
+ chan@3c {
+ label = "xo_therm_buf";
+ reg = <0x3c>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <4>;
+ qcom,hw-settle-time = <2>;
+ qcom,fast-avg-setup = <0>;
+ qcom,vadc-thermal-node;
+ };
+
+ chan@13 {
+ label = "case_therm";
+ reg = <0x13>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <2>;
+ qcom,hw-settle-time = <2>;
+ qcom,fast-avg-setup = <0>;
+ qcom,vadc-thermal-node;
+ };
+ };
+
+ pm8950_adc_tm: vadc@3400 {
+ compatible = "qcom,qpnp-adc-tm";
+ reg = <0x3400 0x100>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <0x0 0x34 0x0>,
+ <0x0 0x34 0x3>,
+ <0x0 0x34 0x4>;
+ interrupt-names = "eoc-int-en-set",
+ "high-thr-en-set",
+ "low-thr-en-set";
+ qcom,adc-bit-resolution = <15>;
+ qcom,adc-vdd-reference = <1800>;
+ qcom,adc_tm-vadc = <&pm8950_vadc>;
+ qcom,pmic-revid = <&pm8950_revid>;
+
+ chan@36 {
+ label = "pa_therm0";
+ reg = <0x36>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <2>;
+ qcom,hw-settle-time = <2>;
+ qcom,fast-avg-setup = <0>;
+ qcom,btm-channel-number = <0x48>;
+ qcom,thermal-node;
+ };
+
+ chan@7 {
+ label = "vph_pwr";
+ reg = <0x7>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <1>;
+ qcom,calibration-type = "absolute";
+ qcom,scale-function = <0>;
+ qcom,hw-settle-time = <0>;
+ qcom,fast-avg-setup = <0>;
+ qcom,btm-channel-number = <0x68>;
+ };
+ };
+
+ pm8950_rtc: qcom,pm8950_rtc {
+ spmi-dev-container;
+ compatible = "qcom,qpnp-rtc";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ qcom,qpnp-rtc-write = <0>;
+ qcom,qpnp-rtc-alarm-pwrup = <0>;
+
+ qcom,pm8950_rtc_rw@6000 {
+ reg = <0x6000 0x100>;
+ };
+
+ qcom,pm8950_rtc_alarm@6100 {
+ reg = <0x6100 0x100>;
+ interrupts = <0x0 0x61 0x1>;
+ };
+ };
+
+ qcom,leds@a300 {
+ compatible = "qcom,leds-qpnp";
+ reg = <0xa300 0x100>;
+ label = "mpp";
+ };
+ };
+
+ pm8950_1: qcom,pm8950@1 {
+ compatible ="qcom,spmi-pmic";
+ reg = <0x1 SPMI_USID>;
+ #address-cells = <2>;
+ #size-cells = <0>;
+
+ pm8950_pwm: pwm@bc00 {
+ status = "disabled";
+ compatible = "qcom,qpnp-pwm";
+ reg = <0xbc00 0x100>;
+ reg-names = "qpnp-lpg-channel-base";
+ qcom,channel-id = <0>;
+ qcom,supported-sizes = <6>, <9>;
+ #pwm-cells = <2>;
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/pmi8950.dtsi b/arch/arm64/boot/dts/qcom/pmi8950.dtsi
new file mode 100644
index 0000000..0ec1f0b
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/pmi8950.dtsi
@@ -0,0 +1,641 @@
+/* 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 <dt-bindings/msm/power-on.h>
+
+&spmi_bus {
+ qcom,pmi8950@2 {
+ compatible ="qcom,spmi-pmic";
+ reg = <0x2 SPMI_USID>;
+ #address-cells = <2>;
+ #size-cells = <0>;
+
+ pmi8950_revid: qcom,revid@100 {
+ compatible = "qcom,qpnp-revid";
+ reg = <0x100 0x100>;
+ };
+
+ qcom,power-on@800 {
+ compatible = "qcom,qpnp-power-on";
+ reg = <0x800 0x100>;
+ qcom,secondary-pon-reset;
+ qcom,hard-reset-poweroff-type =
+ <PON_POWER_OFF_SHUTDOWN>;
+
+ pon_perph_reg: qcom,pon_perph_reg {
+ regulator-name = "pon_spare_reg";
+ qcom,pon-spare-reg-addr = <0x8c>;
+ qcom,pon-spare-reg-bit = <1>;
+ };
+ };
+
+ pmi8950_vadc: vadc@3100 {
+ compatible = "qcom,qpnp-vadc";
+ reg = <0x3100 0x100>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ interrupts = <0x2 0x31 0x0>;
+ interrupt-names = "eoc-int-en-set";
+ qcom,adc-bit-resolution = <15>;
+ qcom,adc-vdd-reference = <1800>;
+ qcom,vadc-poll-eoc;
+
+ chan@0 {
+ label = "usbin";
+ reg = <0>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <4>;
+ qcom,calibration-type = "absolute";
+ qcom,scale-function = <0>;
+ qcom,hw-settle-time = <0>;
+ qcom,fast-avg-setup = <0>;
+ };
+
+ chan@1 {
+ label = "dcin";
+ reg = <1>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <4>;
+ qcom,calibration-type = "absolute";
+ qcom,scale-function = <0>;
+ qcom,hw-settle-time = <0>;
+ qcom,fast-avg-setup = <0>;
+ };
+
+ chan@3 {
+ label = "vchg_sns";
+ reg = <3>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <1>;
+ qcom,calibration-type = "absolute";
+ qcom,scale-function = <0>;
+ qcom,hw-settle-time = <0>;
+ qcom,fast-avg-setup = <0>;
+ };
+
+ chan@9 {
+ label = "ref_625mv";
+ reg = <9>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "absolute";
+ qcom,scale-function = <0>;
+ qcom,hw-settle-time = <0>;
+ qcom,fast-avg-setup = <0>;
+ };
+
+ chan@a {
+ label = "ref_1250v";
+ reg = <0xa>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "absolute";
+ qcom,scale-function = <0>;
+ qcom,hw-settle-time = <0>;
+ qcom,fast-avg-setup = <0>;
+ };
+
+ chan@d {
+ label = "chg_temp";
+ reg = <0xd>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "absolute";
+ qcom,scale-function = <16>;
+ qcom,hw-settle-time = <0>;
+ qcom,fast-avg-setup = <0>;
+ qcom,vadc-thermal-node;
+ };
+
+ chan@43 {
+ label = "usb_dp";
+ reg = <0x43>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <1>;
+ qcom,calibration-type = "absolute";
+ qcom,scale-function = <0>;
+ qcom,hw-settle-time = <0>;
+ qcom,fast-avg-setup = <0>;
+ };
+
+ chan@44 {
+ label = "usb_dm";
+ reg = <0x44>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <1>;
+ qcom,calibration-type = "absolute";
+ qcom,scale-function = <0>;
+ qcom,hw-settle-time = <0>;
+ qcom,fast-avg-setup = <0>;
+ };
+ };
+
+ pmi8950_gpios: gpios {
+ spmi-dev-container;
+ compatible = "qcom,qpnp-pin";
+ gpio-controller;
+ #gpio-cells = <2>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ label = "pmi8950-gpio";
+
+ gpio@c000 {
+ reg = <0xc000 0x100>;
+ qcom,pin-num = <1>;
+ status = "disabled";
+ };
+
+ gpio@c100 {
+ reg = <0xc100 0x100>;
+ qcom,pin-num = <2>;
+ status = "disabled";
+ };
+ };
+
+ pmi8950_mpps: mpps {
+ spmi-dev-container;
+ compatible = "qcom,qpnp-pin";
+ gpio-controller;
+ #gpio-cells = <2>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ label = "pmi8950-mpp";
+
+ mpp@a000 {
+ reg = <0xa000 0x100>;
+ qcom,pin-num = <1>;
+ status = "disabled";
+ };
+
+ mpp@a100 {
+ reg = <0xa100 0x100>;
+ qcom,pin-num = <2>;
+ status = "disabled";
+ };
+
+ mpp@a200 {
+ reg = <0xa200 0x100>;
+ qcom,pin-num = <3>;
+ status = "disabled";
+ };
+
+ mpp@a300 {
+ reg = <0xa300 0x100>;
+ qcom,pin-num = <4>;
+ status = "disabled";
+ };
+ };
+
+ pmi8950_charger: qcom,qpnp-smbcharger {
+ spmi-dev-container;
+ compatible = "qcom,qpnp-smbcharger";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ qcom,iterm-ma = <100>;
+ qcom,float-voltage-mv = <4200>;
+ qcom,resume-delta-mv = <200>;
+ qcom,chg-inhibit-fg;
+ qcom,rparasitic-uohm = <100000>;
+ qcom,bms-psy-name = "bms";
+ qcom,thermal-mitigation = <1500 700 600 0>;
+ qcom,parallel-usb-min-current-ma = <1400>;
+ qcom,parallel-usb-9v-min-current-ma = <900>;
+ qcom,parallel-allowed-lowering-ma = <500>;
+ qcom,pmic-revid = <&pmi8950_revid>;
+ qcom,force-aicl-rerun;
+ qcom,aicl-rerun-period-s = <180>;
+ qcom,autoadjust-vfloat;
+
+ qcom,chgr@1000 {
+ reg = <0x1000 0x100>;
+ interrupts = <0x2 0x10 0x0>,
+ <0x2 0x10 0x1>,
+ <0x2 0x10 0x2>,
+ <0x2 0x10 0x3>,
+ <0x2 0x10 0x4>,
+ <0x2 0x10 0x5>,
+ <0x2 0x10 0x6>,
+ <0x2 0x10 0x7>;
+
+ interrupt-names = "chg-error",
+ "chg-inhibit",
+ "chg-prechg-sft",
+ "chg-complete-chg-sft",
+ "chg-p2f-thr",
+ "chg-rechg-thr",
+ "chg-taper-thr",
+ "chg-tcc-thr";
+ };
+
+ qcom,otg@1100 {
+ reg = <0x1100 0x100>;
+ interrupts = <0x2 0x11 0x0>,
+ <0x2 0x11 0x1>,
+ <0x2 0x11 0x3>;
+ interrupt-names = "otg-fail",
+ "otg-oc",
+ "usbid-change";
+ };
+
+ qcom,bat-if@1200 {
+ reg = <0x1200 0x100>;
+ interrupts = <0x2 0x12 0x0>,
+ <0x2 0x12 0x1>,
+ <0x2 0x12 0x2>,
+ <0x2 0x12 0x3>,
+ <0x2 0x12 0x4>,
+ <0x2 0x12 0x5>,
+ <0x2 0x12 0x6>,
+ <0x2 0x12 0x7>;
+
+ interrupt-names = "batt-hot",
+ "batt-warm",
+ "batt-cold",
+ "batt-cool",
+ "batt-ov",
+ "batt-low",
+ "batt-missing",
+ "batt-term-missing";
+ };
+
+ qcom,usb-chgpth@1300 {
+ reg = <0x1300 0x100>;
+ interrupts = <0x2 0x13 0x0>,
+ <0x2 0x13 0x1>,
+ <0x2 0x13 0x2>,
+ <0x2 0x13 0x5>;
+
+ interrupt-names = "usbin-uv",
+ "usbin-ov",
+ "usbin-src-det",
+ "aicl-done";
+ };
+
+ qcom,dc-chgpth@1400 {
+ reg = <0x1400 0x100>;
+ interrupts = <0x2 0x14 0x0>,
+ <0x2 0x14 0x1>;
+ interrupt-names = "dcin-uv",
+ "dcin-ov";
+ };
+
+ qcom,chgr-misc@1600 {
+ reg = <0x1600 0x100>;
+ interrupts = <0x2 0x16 0x0>,
+ <0x2 0x16 0x1>,
+ <0x2 0x16 0x2>,
+ <0x2 0x16 0x3>,
+ <0x2 0x16 0x4>,
+ <0x2 0x16 0x5>;
+
+ interrupt-names = "power-ok",
+ "temp-shutdown",
+ "wdog-timeout",
+ "flash-fail",
+ "otst2",
+ "otst3";
+ };
+
+ smbcharger_charger_otg: qcom,smbcharger-boost-otg {
+ regulator-name = "smbcharger_charger_otg";
+ };
+ };
+
+ pmi8950_fg: qcom,fg {
+ spmi-dev-container;
+ compatible = "qcom,qpnp-fg";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ qcom,resume-soc = <95>;
+ status = "okay";
+ qcom,bcl-lm-threshold-ma = <127>;
+ qcom,bcl-mh-threshold-ma = <405>;
+ qcom,fg-iterm-ma = <150>;
+ qcom,fg-chg-iterm-ma = <100>;
+ qcom,pmic-revid = <&pmi8950_revid>;
+ qcom,fg-cutoff-voltage-mv = <3500>;
+ qcom,cycle-counter-en;
+ qcom,capacity-learning-on;
+
+ qcom,fg-soc@4000 {
+ status = "okay";
+ reg = <0x4000 0x100>;
+ interrupts = <0x2 0x40 0x0>,
+ <0x2 0x40 0x1>,
+ <0x2 0x40 0x2>,
+ <0x2 0x40 0x3>,
+ <0x2 0x40 0x4>,
+ <0x2 0x40 0x5>,
+ <0x2 0x40 0x6>;
+
+ interrupt-names = "high-soc",
+ "low-soc",
+ "full-soc",
+ "empty-soc",
+ "delta-soc",
+ "first-est-done",
+ "update-soc";
+ };
+
+ qcom,fg-batt@4100 {
+ reg = <0x4100 0x100>;
+ interrupts = <0x2 0x41 0x0>,
+ <0x2 0x41 0x1>,
+ <0x2 0x41 0x2>,
+ <0x2 0x41 0x3>,
+ <0x2 0x41 0x4>,
+ <0x2 0x41 0x5>,
+ <0x2 0x41 0x6>,
+ <0x2 0x41 0x7>;
+
+ interrupt-names = "soft-cold",
+ "soft-hot",
+ "vbatt-low",
+ "batt-ided",
+ "batt-id-req",
+ "batt-unknown",
+ "batt-missing",
+ "batt-match";
+ };
+
+ qcom,revid-tp-rev@1f1 {
+ reg = <0x1f1 0x1>;
+ };
+
+ qcom,fg-memif@4400 {
+ status = "okay";
+ reg = <0x4400 0x100>;
+ interrupts = <0x2 0x44 0x0>,
+ <0x2 0x44 0x2>;
+
+ interrupt-names = "mem-avail",
+ "data-rcvry-sug";
+ };
+ };
+
+ bcl@4200 {
+ compatible = "qcom,msm-bcl";
+ reg = <0x4200 0xFF 0x88E 0x2>;
+ reg-names = "fg_user_adc", "pon_spare";
+ interrupts = <0x2 0x42 0x0>,
+ <0x2 0x42 0x1>;
+ interrupt-names = "bcl-high-ibat-int",
+ "bcl-low-vbat-int";
+ qcom,vbat-scaling-factor = <39000>;
+ qcom,vbat-gain-numerator = <1>;
+ qcom,vbat-gain-denominator = <128>;
+ qcom,vbat-polling-delay-ms = <100>;
+ qcom,ibat-scaling-factor = <39000>;
+ qcom,ibat-gain-numerator = <1>;
+ qcom,ibat-gain-denominator = <128>;
+ qcom,ibat-offset-numerator = <1200>;
+ qcom,ibat-offset-denominator = <1>;
+ qcom,ibat-polling-delay-ms = <100>;
+ qcom,inhibit-derating-ua = <550000>;
+ };
+
+ qcom,leds@a100 {
+ compatible = "qcom,leds-qpnp";
+ reg = <0xa100 0x100>;
+ label = "mpp";
+ };
+ };
+
+ qcom,pmi8950@3 {
+ compatible ="qcom,spmi-pmic";
+ reg = <0x3 SPMI_USID>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ pmi8950_pwm: pwm@b000 {
+ status = "disabled";
+ compatible = "qcom,qpnp-pwm";
+ reg = <0xb000 0x100>;
+ reg-names = "qpnp-lpg-channel-base";
+ qcom,channel-id = <0>;
+ qcom,supported-sizes = <6>, <9>;
+ #pwm-cells = <2>;
+ };
+
+ labibb: qpnp-labibb-regulator {
+ status = "disabled";
+ spmi-dev-container;
+ compatible = "qcom,qpnp-labibb-regulator";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ qcom,pmic-revid = <&pmi8950_revid>;
+
+ ibb_regulator: qcom,ibb@dc00 {
+ reg = <0xdc00 0x100>;
+ reg-names = "ibb_reg";
+ regulator-name = "ibb_reg";
+
+ regulator-min-microvolt = <4600000>;
+ regulator-max-microvolt = <6000000>;
+
+ qcom,qpnp-ibb-min-voltage = <1400000>;
+ qcom,qpnp-ibb-step-size = <100000>;
+ qcom,qpnp-ibb-slew-rate = <2000000>;
+ qcom,qpnp-ibb-use-default-voltage;
+ qcom,qpnp-ibb-init-voltage = <5500000>;
+ qcom,qpnp-ibb-init-amoled-voltage = <4000000>;
+ qcom,qpnp-ibb-init-lcd-voltage = <5500000>;
+
+ qcom,qpnp-ibb-soft-start = <1000>;
+
+ qcom,qpnp-ibb-discharge-resistor = <32>;
+ qcom,qpnp-ibb-lab-pwrup-delay = <8000>;
+ qcom,qpnp-ibb-lab-pwrdn-delay = <8000>;
+ qcom,qpnp-ibb-en-discharge;
+
+ qcom,qpnp-ibb-full-pull-down;
+ qcom,qpnp-ibb-pull-down-enable;
+ qcom,qpnp-ibb-switching-clock-frequency =
+ <1480>;
+ qcom,qpnp-ibb-limit-maximum-current = <1550>;
+ qcom,qpnp-ibb-debounce-cycle = <16>;
+ qcom,qpnp-ibb-limit-max-current-enable;
+ qcom,qpnp-ibb-ps-enable;
+ };
+
+ lab_regulator: qcom,lab@de00 {
+ reg = <0xde00 0x100>;
+ reg-names = "lab";
+ regulator-name = "lab_reg";
+
+ regulator-min-microvolt = <4600000>;
+ regulator-max-microvolt = <6000000>;
+
+ qcom,qpnp-lab-min-voltage = <4600000>;
+ qcom,qpnp-lab-step-size = <100000>;
+ qcom,qpnp-lab-slew-rate = <5000>;
+ qcom,qpnp-lab-use-default-voltage;
+ qcom,qpnp-lab-init-voltage = <5500000>;
+ qcom,qpnp-lab-init-amoled-voltage = <4600000>;
+ qcom,qpnp-lab-init-lcd-voltage = <5500000>;
+
+ qcom,qpnp-lab-soft-start = <800>;
+
+ qcom,qpnp-lab-full-pull-down;
+ qcom,qpnp-lab-pull-down-enable;
+ qcom,qpnp-lab-switching-clock-frequency =
+ <1600>;
+ qcom,qpnp-lab-limit-maximum-current = <800>;
+ qcom,qpnp-lab-limit-max-current-enable;
+ qcom,qpnp-lab-ps-threshold = <40>;
+ qcom,qpnp-lab-ps-enable;
+ qcom,qpnp-lab-nfet-size = <100>;
+ qcom,qpnp-lab-pfet-size = <100>;
+ qcom,qpnp-lab-max-precharge-time = <500>;
+ };
+
+ };
+
+ wled: qcom,leds@d800 {
+ compatible = "qcom,qpnp-wled";
+ reg = <0xd800 0x100>,
+ <0xd900 0x100>,
+ <0xdc00 0x100>,
+ <0xde00 0x100>;
+ reg-names = "qpnp-wled-ctrl-base",
+ "qpnp-wled-sink-base",
+ "qpnp-wled-ibb-base",
+ "qpnp-wled-lab-base";
+ interrupts = <0x3 0xd8 0x2>;
+ interrupt-names = "sc-irq";
+ status = "okay";
+ linux,name = "wled";
+ linux,default-trigger = "bkl-trigger";
+ qcom,fdbk-output = "auto";
+ qcom,vref-mv = <350>;
+ qcom,switch-freq-khz = <800>;
+ qcom,ovp-mv = <29500>;
+ qcom,ilim-ma = <980>;
+ qcom,boost-duty-ns = <26>;
+ qcom,mod-freq-khz = <9600>;
+ qcom,dim-mode = "hybrid";
+ qcom,dim-method = "linear";
+ qcom,hyb-thres = <625>;
+ qcom,sync-dly-us = <800>;
+ qcom,fs-curr-ua = <20000>;
+ qcom,led-strings-list = [00 01];
+ qcom,en-ext-pfet-sc-pro;
+ qcom,cons-sync-write-delay-us = <1000>;
+ };
+
+ flash_led: qcom,leds@d300 {
+ compatible = "qcom,qpnp-flash-led";
+ status = "okay";
+ reg = <0xd300 0x100>;
+ label = "flash";
+ qcom,headroom = <500>;
+ qcom,startup-dly = <128>;
+ qcom,clamp-curr = <200>;
+ qcom,pmic-charger-support;
+ qcom,self-check-enabled;
+ qcom,thermal-derate-enabled;
+ qcom,thermal-derate-threshold = <100>;
+ qcom,thermal-derate-rate = "5_PERCENT";
+ qcom,current-ramp-enabled;
+ qcom,ramp_up_step = "6P7_US";
+ qcom,ramp_dn_step = "6P7_US";
+ qcom,vph-pwr-droop-enabled;
+ qcom,vph-pwr-droop-threshold = <3000>;
+ qcom,vph-pwr-droop-debounce-time = <10>;
+ qcom,headroom-sense-ch0-enabled;
+ qcom,headroom-sense-ch1-enabled;
+ qcom,pmic-revid = <&pmi8950_revid>;
+
+ pmi8950_flash0: qcom,flash_0 {
+ label = "flash";
+ qcom,led-name = "led:flash_0";
+ qcom,default-led-trigger =
+ "flash0_trigger";
+ qcom,max-current = <1000>;
+ qcom,duration = <1280>;
+ qcom,id = <0>;
+ qcom,current = <625>;
+ };
+
+ pmi8950_flash1: qcom,flash_1 {
+ label = "flash";
+ qcom,led-name = "led:flash_1";
+ qcom,default-led-trigger =
+ "flash1_trigger";
+ qcom,max-current = <1000>;
+ qcom,duration = <1280>;
+ qcom,id = <1>;
+ qcom,current = <625>;
+ };
+
+ pmi8950_torch0: qcom,torch_0 {
+ label = "torch";
+ qcom,led-name = "led:torch_0";
+ qcom,default-led-trigger =
+ "torch0_trigger";
+ qcom,max-current = <200>;
+ qcom,id = <0>;
+ qcom,current = <120>;
+ };
+
+ pmi8950_torch1: qcom,torch_1 {
+ label = "torch";
+ qcom,led-name = "led:torch_1";
+ qcom,default-led-trigger =
+ "torch1_trigger";
+ qcom,max-current = <200>;
+ qcom,id = <1>;
+ qcom,current = <120>;
+ };
+
+ pmi8950_switch: qcom,switch {
+ label = "switch";
+ qcom,led-name = "led:switch";
+ qcom,default-led-trigger =
+ "switch_trigger";
+ qcom,max-current = <1000>;
+ qcom,duration = <1280>;
+ qcom,id = <2>;
+ qcom,current = <625>;
+ reg0 {
+ regulator-name = "pon_spare_reg";
+ };
+ };
+ };
+
+ pmi_haptic: qcom,haptic@c000 {
+ compatible = "qcom,qpnp-haptic";
+ reg = <0xc000 0x100>;
+ interrupts = <0x3 0xc0 0x0>,
+ <0x3 0xc0 0x1>;
+ interrupt-names = "sc-irq", "play-irq";
+ qcom,pmic-revid = <&pmi8950_revid>;
+ vcc_pon-supply = <&pon_perph_reg>;
+ qcom,play-mode = "direct";
+ qcom,wave-play-rate-us = <5263>;
+ qcom,actuator-type = "erm";
+ qcom,wave-shape = "square";
+ qcom,vmax-mv = <2000>;
+ qcom,ilim-ma = <800>;
+ qcom,sc-deb-cycles = <8>;
+ qcom,int-pwm-freq-khz = <505>;
+ qcom,en-brake;
+ qcom,brake-pattern = [03 03 00 00];
+ qcom,use-play-irq;
+ qcom,use-sc-irq;
+ qcom,wave-samples = [3e 3e 3e 3e 3e 3e 3e 3e];
+ qcom,wave-rep-cnt = <1>;
+ qcom,wave-samp-rep-cnt = <1>;
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm670-cdp.dtsi b/arch/arm64/boot/dts/qcom/sdm670-cdp.dtsi
index 60a81ff..8e152b0 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-cdp.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-cdp.dtsi
@@ -95,15 +95,6 @@
pinctrl-0 = <&sdc2_clk_on &sdc2_cmd_on &sdc2_data_on &sdc2_cd_on>;
pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off &sdc2_cd_off>;
- #address-cells = <0>;
- interrupt-parent = <&sdhc_2>;
- interrupts = <0 1 2>;
- #interrupt-cells = <1>;
- interrupt-map-mask = <0xffffffff>;
- interrupt-map = <0 &intc 0 0 204 0
- 1 &intc 0 0 222 0
- 2 &tlmm 96 0>;
- interrupt-names = "hc_irq", "pwr_irq", "status_irq";
cd-gpios = <&tlmm 96 0x1>;
status = "ok";
diff --git a/arch/arm64/boot/dts/qcom/sdm670-mtp.dtsi b/arch/arm64/boot/dts/qcom/sdm670-mtp.dtsi
index 5e88b0a..c5eefea 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-mtp.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-mtp.dtsi
@@ -95,15 +95,6 @@
pinctrl-0 = <&sdc2_clk_on &sdc2_cmd_on &sdc2_data_on &sdc2_cd_on>;
pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off &sdc2_cd_off>;
- #address-cells = <0>;
- interrupt-parent = <&sdhc_2>;
- interrupts = <0 1 2>;
- #interrupt-cells = <1>;
- interrupt-map-mask = <0xffffffff>;
- interrupt-map = <0 &intc 0 0 204 0
- 1 &intc 0 0 222 0
- 2 &tlmm 96 0>;
- interrupt-names = "hc_irq", "pwr_irq", "status_irq";
cd-gpios = <&tlmm 96 0x1>;
status = "ok";
diff --git a/arch/arm64/boot/dts/qcom/sdm670-pinctrl.dtsi b/arch/arm64/boot/dts/qcom/sdm670-pinctrl.dtsi
index 177813f..2bf00fb 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-pinctrl.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-pinctrl.dtsi
@@ -1625,6 +1625,20 @@
};
&pm660l_gpios {
+ camera0_dvdd_en_default: camera0_dvdd_en_default {
+ pins = "gpio3";
+ function = "normal";
+ power-source = <0>;
+ output-low;
+ };
+
+ camera1_dvdd_en_default: camera1_dvdd_en_default {
+ pins = "gpio4";
+ function = "normal";
+ power-source = <0>;
+ output-low;
+ };
+
key_vol_up {
key_vol_up_default: key_vol_up_default {
pins = "gpio7";
@@ -1635,3 +1649,13 @@
};
};
};
+
+&pm660_gpios {
+ smb_shutdown_default: smb_shutdown_default {
+ pins = "gpio11";
+ function = "normal";
+ power-source = <0>;
+ qcom,drive-strength = <3>;
+ output-high;
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm670-qrd.dtsi b/arch/arm64/boot/dts/qcom/sdm670-qrd.dtsi
index 29113ee..55f3b93 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-qrd.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-qrd.dtsi
@@ -10,8 +10,10 @@
* GNU General Public License for more details.
*/
+#include <dt-bindings/gpio/gpio.h>
#include "sdm670-pmic-overlay.dtsi"
#include "sdm670-audio-overlay.dtsi"
+#include "smb1355.dtsi"
&qupv3_se9_2uart {
status = "disabled";
@@ -30,13 +32,96 @@
};
&qupv3_se10_i2c {
- status = "disabled";
+ status = "ok";
};
&qupv3_se6_4uart {
status = "disabled";
};
+&vendor {
+ qrd_batterydata: qcom,battery-data {
+ qcom,batt-id-range-pct = <15>;
+ #include "fg-gen3-batterydata-mlp356477-2800mah.dtsi"
+ };
+};
+
+&pm660_fg {
+ qcom,battery-data = <&qrd_batterydata>;
+ qcom,fg-bmd-en-delay-ms = <300>;
+};
+
+&tlmm {
+ smb_int_default: smb_int_default {
+ mux {
+ pins = "gpio54";
+ function = "gpio";
+ };
+ config {
+ pins = "gpio54";
+ drive-strength = <2>;
+ bias-pull-up;
+ input-enable;
+ };
+ };
+};
+
+&smb1355_0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&smb_int_default
+ &smb_shutdown_default>;
+ interrupt-parent = <&tlmm>;
+ interrupts = <54 IRQ_TYPE_LEVEL_LOW>;
+ smb1355_charger_0: qcom,smb1355-charger@1000 {
+ io-channels = <&pm660_rradc 2>,
+ <&pm660_rradc 12>;
+ io-channel-names = "charger_temp",
+ "charger_temp_max";
+ status = "ok";
+ };
+};
+
+&smb1355_1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&smb_int_default
+ &smb_shutdown_default>;
+ interrupt-parent = <&tlmm>;
+ interrupts = <54 IRQ_TYPE_LEVEL_LOW>;
+ smb1355_charger_1: qcom,smb1355-charger@1000 {
+ io-channels = <&pm660_rradc 2>,
+ <&pm660_rradc 12>;
+ io-channel-names = "charger_temp",
+ "charger_temp_max";
+ status = "ok";
+ };
+};
+
+&soc {
+ gpio_keys {
+ compatible = "gpio-keys";
+ label = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&key_vol_up_default>;
+
+ 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;
+ };
+ };
+};
+
+&pm660_haptics {
+ qcom,vmax-mv = <1800>;
+ qcom,wave-play-rate-us = <4255>;
+ qcom,lra-auto-mode;
+ status = "okay";
+};
+
&int_codec {
qcom,model = "sdm660-skuw-snd-card";
qcom,audio-routing =
diff --git a/arch/arm64/boot/dts/qcom/sdm670-sde.dtsi b/arch/arm64/boot/dts/qcom/sdm670-sde.dtsi
index bb30a20..948a7be 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-sde.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-sde.dtsi
@@ -190,6 +190,9 @@
qcom,sde-dspp-blocks {
qcom,sde-dspp-igc = <0x0 0x00030001>;
+ qcom,sde-dspp-hsic = <0x800 0x00010007>;
+ qcom,sde-dspp-memcolor = <0x880 0x00010007>;
+ qcom,sde-dspp-sixzone= <0x900 0x00010007>;
qcom,sde-dspp-vlut = <0xa00 0x00010008>;
qcom,sde-dspp-gamut = <0x1000 0x00040000>;
qcom,sde-dspp-pcc = <0x1700 0x00040000>;
diff --git a/arch/arm64/boot/dts/qcom/sdm670.dtsi b/arch/arm64/boot/dts/qcom/sdm670.dtsi
index 2ab77e5..e52fb62 100644
--- a/arch/arm64/boot/dts/qcom/sdm670.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670.dtsi
@@ -56,7 +56,7 @@
reg = <0x0 0x0>;
enable-method = "psci";
efficiency = <1024>;
- cache-size = <0x8000>;
+ cache-size = <0x10000>;
cpu-release-addr = <0x0 0x90000000>;
next-level-cache = <&L2_0>;
sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_0>;
@@ -75,11 +75,11 @@
};
L1_I_0: l1-icache {
compatible = "arm,arch-cache";
- qcom,dump-size = <0x9000>;
+ qcom,dump-size = <0x12000>;
};
L1_D_0: l1-dcache {
compatible = "arm,arch-cache";
- qcom,dump-size = <0x9000>;
+ qcom,dump-size = <0xa000>;
};
L1_TLB_0: l1-tlb {
qcom,dump-size = <0x3000>;
@@ -92,7 +92,7 @@
reg = <0x0 0x100>;
enable-method = "psci";
efficiency = <1024>;
- cache-size = <0x8000>;
+ cache-size = <0x10000>;
cpu-release-addr = <0x0 0x90000000>;
next-level-cache = <&L2_100>;
sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_0>;
@@ -106,11 +106,11 @@
};
L1_I_100: l1-icache {
compatible = "arm,arch-cache";
- qcom,dump-size = <0x9000>;
+ qcom,dump-size = <0x12000>;
};
L1_D_100: l1-dcache {
compatible = "arm,arch-cache";
- qcom,dump-size = <0x9000>;
+ qcom,dump-size = <0xa000>;
};
L1_TLB_100: l1-tlb {
qcom,dump-size = <0x3000>;
@@ -123,7 +123,7 @@
reg = <0x0 0x200>;
enable-method = "psci";
efficiency = <1024>;
- cache-size = <0x8000>;
+ cache-size = <0x10000>;
cpu-release-addr = <0x0 0x90000000>;
next-level-cache = <&L2_200>;
sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_0>;
@@ -137,11 +137,11 @@
};
L1_I_200: l1-icache {
compatible = "arm,arch-cache";
- qcom,dump-size = <0x9000>;
+ qcom,dump-size = <0x12000>;
};
L1_D_200: l1-dcache {
compatible = "arm,arch-cache";
- qcom,dump-size = <0x9000>;
+ qcom,dump-size = <0xa000>;
};
L1_TLB_200: l1-tlb {
qcom,dump-size = <0x3000>;
@@ -154,7 +154,7 @@
reg = <0x0 0x300>;
enable-method = "psci";
efficiency = <1024>;
- cache-size = <0x8000>;
+ cache-size = <0x10000>;
cpu-release-addr = <0x0 0x90000000>;
next-level-cache = <&L2_300>;
sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_0>;
@@ -168,11 +168,11 @@
};
L1_I_300: l1-icache {
compatible = "arm,arch-cache";
- qcom,dump-size = <0x9000>;
+ qcom,dump-size = <0x12000>;
};
L1_D_300: l1-dcache {
compatible = "arm,arch-cache";
- qcom,dump-size = <0x9000>;
+ qcom,dump-size = <0xa000>;
};
L1_TLB_300: l1-tlb {
qcom,dump-size = <0x3000>;
@@ -185,7 +185,7 @@
reg = <0x0 0x400>;
enable-method = "psci";
efficiency = <1024>;
- cache-size = <0x8000>;
+ cache-size = <0x10000>;
cpu-release-addr = <0x0 0x90000000>;
next-level-cache = <&L2_400>;
sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_0>;
@@ -199,11 +199,11 @@
};
L1_I_400: l1-icache {
compatible = "arm,arch-cache";
- qcom,dump-size = <0x9000>;
+ qcom,dump-size = <0x12000>;
};
L1_D_400: l1-dcache {
compatible = "arm,arch-cache";
- qcom,dump-size = <0x9000>;
+ qcom,dump-size = <0xa000>;
};
L1_TLB_400: l1-tlb {
qcom,dump-size = <0x3000>;
@@ -216,7 +216,7 @@
reg = <0x0 0x500>;
enable-method = "psci";
efficiency = <1024>;
- cache-size = <0x8000>;
+ cache-size = <0x10000>;
cpu-release-addr = <0x0 0x90000000>;
next-level-cache = <&L2_500>;
sched-energy-costs = <&CPU_COST_0 &CLUSTER_COST_0>;
@@ -230,11 +230,11 @@
};
L1_I_500: l1-icache {
compatible = "arm,arch-cache";
- qcom,dump-size = <0x9000>;
+ qcom,dump-size = <0x12000>;
};
L1_D_500: l1-dcache {
compatible = "arm,arch-cache";
- qcom,dump-size = <0x9000>;
+ qcom,dump-size = <0xa000>;
};
L1_TLB_500: l1-tlb {
qcom,dump-size = <0x3000>;
@@ -247,7 +247,7 @@
reg = <0x0 0x600>;
enable-method = "psci";
efficiency = <1740>;
- cache-size = <0x10000>;
+ cache-size = <0x20000>;
cpu-release-addr = <0x0 0x90000000>;
next-level-cache = <&L2_600>;
sched-energy-costs = <&CPU_COST_1 &CLUSTER_COST_1>;
@@ -261,11 +261,11 @@
};
L1_I_600: l1-icache {
compatible = "arm,arch-cache";
- qcom,dump-size = <0x12000>;
+ qcom,dump-size = <0x24000>;
};
L1_D_600: l1-dcache {
compatible = "arm,arch-cache";
- qcom,dump-size = <0x12000>;
+ qcom,dump-size = <0x14000>;
};
L1_TLB_600: l1-tlb {
qcom,dump-size = <0x3c000>;
@@ -278,7 +278,7 @@
reg = <0x0 0x700>;
enable-method = "psci";
efficiency = <1740>;
- cache-size = <0x10000>;
+ cache-size = <0x20000>;
cpu-release-addr = <0x0 0x90000000>;
next-level-cache = <&L2_700>;
sched-energy-costs = <&CPU_COST_1 &CLUSTER_COST_1>;
@@ -292,11 +292,11 @@
};
L1_I_700: l1-icache {
compatible = "arm,arch-cache";
- qcom,dump-size = <0x12000>;
+ qcom,dump-size = <0x24000>;
};
L1_D_700: l1-dcache {
compatible = "arm,arch-cache";
- qcom,dump-size = <0x12000>;
+ qcom,dump-size = <0x14000>;
};
L1_TLB_700: l1-tlb {
qcom,dump-size = <0x3c000>;
@@ -2061,7 +2061,7 @@
qcom,ssctl-instance-id = <0x12>;
qcom,override-acc;
qcom,qdsp6v65-1-0;
- qcom,mss_pdc_offset = <8>;
+ qcom,mss_pdc_offset = <9>;
status = "ok";
memory-region = <&pil_modem_mem>;
qcom,mem-protect-id = <0xF>;
@@ -2161,30 +2161,30 @@
qcom,msm-bus,num-paths = <2>;
qcom,msm-bus,vectors-KBps =
/* No vote */
- <78 512 0 0>, <1 606 0 0>,
+ <150 512 0 0>, <1 606 0 0>,
/* 400 KB/s*/
- <78 512 1046 1600>,
+ <150 512 1046 1600>,
<1 606 1600 1600>,
/* 20 MB/s */
- <78 512 52286 80000>,
+ <150 512 52286 80000>,
<1 606 80000 80000>,
/* 25 MB/s */
- <78 512 65360 100000>,
+ <150 512 65360 100000>,
<1 606 100000 100000>,
/* 50 MB/s */
- <78 512 130718 200000>,
+ <150 512 130718 200000>,
<1 606 133320 133320>,
/* 100 MB/s */
- <78 512 130718 200000>,
+ <150 512 130718 200000>,
<1 606 150000 150000>,
/* 200 MB/s */
- <78 512 261438 400000>,
+ <150 512 261438 400000>,
<1 606 300000 300000>,
/* 400 MB/s */
- <78 512 261438 400000>,
+ <150 512 261438 400000>,
<1 606 300000 300000>,
/* Max. bandwidth */
- <78 512 1338562 4096000>,
+ <150 512 1338562 4096000>,
<1 606 1338562 4096000>;
qcom,bus-bw-vectors-bps = <0 400000 20000000 25000000 50000000
100000000 200000000 400000000 4294967295>;
@@ -2198,8 +2198,10 @@
clocks = <&clock_gcc GCC_SDCC1_AHB_CLK>,
<&clock_gcc GCC_SDCC1_APPS_CLK>,
- <&clock_gcc GCC_SDCC1_ICE_CORE_CLK>;
- clock-names = "iface_clk", "core_clk", "ice_core_clk";
+ <&clock_gcc GCC_SDCC1_ICE_CORE_CLK>,
+ <&clock_gcc GCC_AGGRE_UFS_PHY_AXI_CLK>;
+ clock-names = "iface_clk", "core_clk", "ice_core_clk",
+ "bus_aggr_clk";
qcom,ice-clk-rates = <300000000 75000000>;
@@ -2351,6 +2353,12 @@
iommus = <&apps_smmu 0x1805 0x0>;
dma-coherent;
};
+ qcom,msm_fastrpc_compute_cb12 {
+ compatible = "qcom,msm-fastrpc-compute-cb";
+ label = "adsprpc-smd";
+ iommus = <&apps_smmu 0x1806 0x0>;
+ dma-coherent;
+ };
};
bluetooth: bt_wcn3990 {
@@ -2369,9 +2377,12 @@
};
qcom,icnss@18800000 {
- status = "disabled";
compatible = "qcom,icnss";
- reg = <0x18800000 0x800000>;
+ reg = <0x18800000 0x800000>,
+ <0xa0000000 0x10000000>,
+ <0xb0000000 0x10000>;
+ reg-names = "membase", "smmu_iova_base", "smmu_iova_ipa";
+ iommus = <&apps_smmu 0x0040 0x1>;
interrupts = <0 414 0 /* CE0 */ >,
<0 415 0 /* CE1 */ >,
<0 416 0 /* CE2 */ >,
@@ -2384,6 +2395,10 @@
<0 423 0 /* CE9 */ >,
<0 424 0 /* CE10 */ >,
<0 425 0 /* CE11 */ >;
+ vdd-0.8-cx-mx-supply = <&pm660_l5>;
+ vdd-1.8-xo-supply = <&pm660_l9>;
+ vdd-1.3-rfa-supply = <&pm660_l6>;
+ vdd-3.3-ch0-supply = <&pm660_l19>;
qcom,wlan-msa-memory = <0x100000>;
qcom,smmu-s1-bypass;
};
@@ -2414,6 +2429,7 @@
reg-names = "base", "global_base";
interrupts = <0 581 4>;
qcom,mport = <0>;
+ qcom,count-unit = <0x10000>;
qcom,hw-timer-hz = <19200000>;
qcom,target-dev = <&cpubw>;
};
@@ -2705,3 +2721,7 @@
#include "sdm670-gpu.dtsi"
#include "sdm670-thermal.dtsi"
#include "sdm670-bus.dtsi"
+
+&pm660_div_clk {
+ status = "ok";
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm845-cdp.dtsi b/arch/arm64/boot/dts/qcom/sdm845-cdp.dtsi
index 81ce1e5..dffb5e0 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-cdp.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-cdp.dtsi
@@ -269,6 +269,27 @@
qcom,platform-reset-gpio = <&tlmm 6 0>;
};
+&dsi_dual_nt35597_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 52 0>;
+ qcom,platform-reset-gpio = <&tlmm 6 0>;
+};
+
+&dsi_dual_nt35597_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 52 0>;
+ qcom,platform-reset-gpio = <&tlmm 6 0>;
+ qcom,platform-te-gpio = <&tlmm 10 0>;
+};
+
&dsi_nt35597_truly_dsc_cmd_display {
qcom,dsi-display-active;
};
diff --git a/arch/arm64/boot/dts/qcom/sdm845-gpu.dtsi b/arch/arm64/boot/dts/qcom/sdm845-gpu.dtsi
index 4fd1a67..0eee34a 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-gpu.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-gpu.dtsi
@@ -268,7 +268,8 @@
compatible = "qcom,kgsl-smmu-v2";
reg = <0x05040000 0x10000>;
- qcom,protect = <0x40000 0x10000>;
+ /* CB5(ATOS) & CB5/6/7 are protected by HYP */
+ qcom,protect = <0x40000 0xc000>;
qcom,micro-mmu-control = <0x6000>;
clocks =<&clock_gcc GCC_GPU_CFG_AHB_CLK>,
@@ -289,7 +290,7 @@
gfx3d_secure: gfx3d_secure {
compatible = "qcom,smmu-kgsl-cb";
- iommus = <&kgsl_smmu 2>;
+ iommus = <&kgsl_smmu 2>, <&kgsl_smmu 1>;
};
};
diff --git a/arch/arm64/boot/dts/qcom/sdm845-interposer-pm660.dtsi b/arch/arm64/boot/dts/qcom/sdm845-interposer-pm660.dtsi
index fbda72c..1a8de22 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-interposer-pm660.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-interposer-pm660.dtsi
@@ -54,6 +54,18 @@
ibb-supply = <&lcdb_ncp_vreg>;
};
+&dsi_dual_nt35597_video_display {
+ vddio-supply = <&pm660_l11>;
+ lab-supply = <&lcdb_ldo_vreg>;
+ ibb-supply = <&lcdb_ncp_vreg>;
+};
+
+&dsi_dual_nt35597_cmd_display {
+ vddio-supply = <&pm660_l11>;
+ lab-supply = <&lcdb_ldo_vreg>;
+ ibb-supply = <&lcdb_ncp_vreg>;
+};
+
&sde_dp {
status = "disabled";
/delete-property/ vdda-1p2-supply;
@@ -240,6 +252,7 @@
qcom,ssc@5c00000 {
/delete-property/ vdd_cx-supply;
+ /delete-property/ vdd_mx-supply;
};
qcom,spss@1880000 {
diff --git a/arch/arm64/boot/dts/qcom/sdm845-mtp.dtsi b/arch/arm64/boot/dts/qcom/sdm845-mtp.dtsi
index f0d16ec..48a4a8b 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-mtp.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-mtp.dtsi
@@ -164,6 +164,27 @@
qcom,platform-reset-gpio = <&tlmm 6 0>;
};
+&dsi_dual_nt35597_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 52 0>;
+ qcom,platform-reset-gpio = <&tlmm 6 0>;
+};
+
+&dsi_dual_nt35597_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 52 0>;
+ qcom,platform-reset-gpio = <&tlmm 6 0>;
+ qcom,platform-te-gpio = <&tlmm 10 0>;
+};
+
&dsi_nt35597_truly_dsc_cmd_display {
qcom,dsi-display-active;
};
diff --git a/arch/arm64/boot/dts/qcom/sdm845-pcie.dtsi b/arch/arm64/boot/dts/qcom/sdm845-pcie.dtsi
index 322c5f5..daf5687 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-pcie.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-pcie.dtsi
@@ -214,7 +214,8 @@
qcom,smmu-sid-base = <0x1c10>;
- iommu-map = <0x100 &apps_smmu 0x1c11 0x1>,
+ iommu-map = <0x0 &apps_smmu 0x1c10 0x1>,
+ <0x100 &apps_smmu 0x1c11 0x1>,
<0x200 &apps_smmu 0x1c12 0x1>,
<0x300 &apps_smmu 0x1c13 0x1>,
<0x400 &apps_smmu 0x1c14 0x1>,
@@ -547,7 +548,8 @@
qcom,smmu-sid-base = <0x1c00>;
- iommu-map = <0x100 &apps_smmu 0x1c01 0x1>,
+ iommu-map = <0x0 &apps_smmu 0x1c00 0x1>,
+ <0x100 &apps_smmu 0x1c01 0x1>,
<0x200 &apps_smmu 0x1c02 0x1>,
<0x300 &apps_smmu 0x1c03 0x1>,
<0x400 &apps_smmu 0x1c04 0x1>,
diff --git a/arch/arm64/boot/dts/qcom/sdm845-qupv3.dtsi b/arch/arm64/boot/dts/qcom/sdm845-qupv3.dtsi
index 77495bf..810afde 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-qupv3.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-qupv3.dtsi
@@ -629,7 +629,7 @@
<&clock_gcc GCC_QUPV3_WRAP_1_S_AHB_CLK>;
pinctrl-names = "default", "sleep";
pinctrl-0 = <&qupv3_se8_spi_active>;
- pinctrl-1 = <&qupv3_se8_spi_sleep>;
+ pinctrl-1 = <&qupv3_se8_spi_active>;
interrupts = <GIC_SPI 353 0>;
spi-max-frequency = <50000000>;
qcom,wrapper-core = <&qupv3_1>;
diff --git a/arch/arm64/boot/dts/qcom/sdm845-regulator.dtsi b/arch/arm64/boot/dts/qcom/sdm845-regulator.dtsi
index f09efd4..da4d41c 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-regulator.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-regulator.dtsi
@@ -171,11 +171,14 @@
<RPMH_REGULATOR_MODE_LDO_LPM
RPMH_REGULATOR_MODE_LDO_HPM>;
qcom,mode-threshold-currents = <0 1>;
+ proxy-supply = <&pm8998_l1>;
pm8998_l1: regulator-l1 {
regulator-name = "pm8998_l1";
qcom,set = <RPMH_REGULATOR_SET_ALL>;
regulator-min-microvolt = <880000>;
regulator-max-microvolt = <880000>;
+ qcom,proxy-consumer-enable;
+ qcom,proxy-consumer-current = <72000>;
qcom,init-voltage = <880000>;
qcom,init-mode = <RPMH_REGULATOR_MODE_LDO_LPM>;
};
@@ -420,9 +423,12 @@
<RPMH_REGULATOR_MODE_LDO_LPM
RPMH_REGULATOR_MODE_LDO_HPM>;
qcom,mode-threshold-currents = <0 10000>;
+ proxy-supply = <&pm8998_l14>;
pm8998_l14: regulator-l14 {
regulator-name = "pm8998_l14";
qcom,set = <RPMH_REGULATOR_SET_ALL>;
+ qcom,proxy-consumer-enable;
+ qcom,proxy-consumer-current = <115000>;
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1880000>;
qcom,init-voltage = <1800000>;
@@ -637,11 +643,14 @@
<RPMH_REGULATOR_MODE_LDO_LPM
RPMH_REGULATOR_MODE_LDO_HPM>;
qcom,mode-threshold-currents = <0 1>;
+ proxy-supply = <&pm8998_l26>;
pm8998_l26: regulator-l26 {
regulator-name = "pm8998_l26";
qcom,set = <RPMH_REGULATOR_SET_ALL>;
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <1200000>;
+ qcom,proxy-consumer-enable;
+ qcom,proxy-consumer-current = <43600>;
qcom,init-voltage = <1200000>;
qcom,init-mode = <RPMH_REGULATOR_MODE_LDO_LPM>;
};
diff --git a/arch/arm64/boot/dts/qcom/sdm845-sde-display.dtsi b/arch/arm64/boot/dts/qcom/sdm845-sde-display.dtsi
index 4337da7..8c8d5d4 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-sde-display.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-sde-display.dtsi
@@ -25,6 +25,8 @@
#include "dsi-panel-sharp-1080p-cmd.dtsi"
#include "dsi-panel-sharp-dualmipi-1080p-120hz.dtsi"
#include "dsi-panel-s6e3ha3-amoled-dualmipi-wqhd-cmd.dtsi"
+#include "dsi-panel-nt35597-dualmipi-wqxga-video.dtsi"
+#include "dsi-panel-nt35597-dualmipi-wqxga-cmd.dtsi"
#include <dt-bindings/clock/mdss-10nm-pll-clk.h>
&soc {
@@ -401,6 +403,54 @@
qcom,dsi-panel = <&dsi_dual_sim_dsc_375_cmd>;
};
+ dsi_dual_nt35597_video_display: qcom,dsi-display@14 {
+ compatible = "qcom,dsi-display";
+ label = "dsi_dual_nt35597_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 6 0>;
+ qcom,panel-mode-gpio = <&tlmm 52 0>;
+
+ qcom,dsi-panel = <&dsi_dual_nt35597_video>;
+ vddio-supply = <&pm8998_l14>;
+ lab-supply = <&lab_regulator>;
+ ibb-supply = <&ibb_regulator>;
+ };
+
+
+ dsi_dual_nt35597_cmd_display: qcom,dsi-display@15 {
+ compatible = "qcom,dsi-display";
+ label = "dsi_dual_nt35597_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 6 0>;
+ qcom,panel-mode-gpio = <&tlmm 52 0>;
+
+ qcom,dsi-panel = <&dsi_dual_nt35597_cmd>;
+ vddio-supply = <&pm8998_l14>;
+ lab-supply = <&lab_regulator>;
+ ibb-supply = <&ibb_regulator>;
+ };
+
sde_wb: qcom,wb-display@0 {
compatible = "qcom,wb-display";
cell-index = <0>;
@@ -660,3 +710,31 @@
};
};
};
+
+&dsi_dual_nt35597_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-timings = [00 1c 08 07 23 22 07 07
+ 05 03 04 00];
+ qcom,display-topology = <2 0 2>,
+ <1 0 2>;
+ qcom,default-topology-index = <0>;
+ };
+ };
+};
+
+&dsi_dual_nt35597_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-timings = [00 1c 08 07 23 22 07 07
+ 05 03 04 00];
+ qcom,display-topology = <2 0 2>,
+ <1 0 2>;
+ qcom,default-topology-index = <0>;
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi
index 007f231..7437931 100644
--- a/arch/arm64/boot/dts/qcom/sdm845.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi
@@ -610,6 +610,11 @@
size = <0 0x800000>;
};
+ cont_splash_memory: cont_splash_region@9d400000 {
+ reg = <0x0 0x9d400000 0x0 0x02400000>;
+ label = "cont_splash_region";
+ };
+
secure_display_memory: secure_display_region {
compatible = "shared-dma-pool";
alloc-ranges = <0 0x00000000 0 0xffffffff>;
@@ -1551,7 +1556,9 @@
vdd_cx-supply = <&pm8998_l27_level>;
qcom,vdd_cx-uV-uA = <RPMH_REGULATOR_LEVEL_TURBO 0>;
- qcom,proxy-reg-names = "vdd_cx";
+ vdd_mx-supply = <&pm8998_l4_level>;
+ qcom,vdd_mx-uV-uA = <RPMH_REGULATOR_LEVEL_TURBO 0>;
+ qcom,proxy-reg-names = "vdd_cx", "vdd_mx";
qcom,keep-proxy-regs-on;
clocks = <&clock_rpmh RPMH_CXO_CLK>;
diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c
index b325f74..c1e932d 100644
--- a/arch/arm64/kernel/perf_event.c
+++ b/arch/arm64/kernel/perf_event.c
@@ -1161,8 +1161,8 @@
{
int ret;
- ret = cpuhp_setup_state_nocalls(CPUHP_AP_NOTIFY_ONLINE,
- "PERF_EVENT/CPUHP_AP_NOTIFY_ONLINE",
+ ret = cpuhp_setup_state_nocalls(CPUHP_AP_NOTIFY_PERF_ONLINE,
+ "PERF_EVENT/CPUHP_AP_NOTIFY_PERF_ONLINE",
perf_event_hotplug_coming_up,
perf_event_hotplug_going_down);
if (ret)
diff --git a/drivers/clk/qcom/gcc-sdm845.c b/drivers/clk/qcom/gcc-sdm845.c
index 4142dd5..53f0778 100644
--- a/drivers/clk/qcom/gcc-sdm845.c
+++ b/drivers/clk/qcom/gcc-sdm845.c
@@ -36,9 +36,6 @@
#include "clk-alpha-pll.h"
#include "vdd-level-sdm845.h"
-#define GCC_APCS_CLOCK_SLEEP_ENA_VOTE_OFFSET 0x52008
-#define CPUSS_AHB_CLK_SLEEP_ENA BIT(21)
-#define SYS_NOC_CPUSS_AHB_CLK_SLEEP_ENA BIT(0)
#define GCC_MMSS_MISC 0x09FFC
#define GCC_GPU_MISC 0x71028
@@ -4288,14 +4285,6 @@
if (IS_ERR(regmap))
return PTR_ERR(regmap);
- /*
- * Set the *_SLEEP_ENA bits to allow certain cpuss* clocks to be
- * turned off by hardware during certain apps low power modes.
- */
- regmap_update_bits(regmap, GCC_APCS_CLOCK_SLEEP_ENA_VOTE_OFFSET,
- CPUSS_AHB_CLK_SLEEP_ENA | SYS_NOC_CPUSS_AHB_CLK_SLEEP_ENA,
- CPUSS_AHB_CLK_SLEEP_ENA | SYS_NOC_CPUSS_AHB_CLK_SLEEP_ENA);
-
vdd_cx.regulator[0] = devm_regulator_get(&pdev->dev, "vdd_cx");
if (IS_ERR(vdd_cx.regulator[0])) {
if (!(PTR_ERR(vdd_cx.regulator[0]) == -EPROBE_DEFER))
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index f55ce04..3c2d214 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -1274,6 +1274,10 @@
struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev);
int ret;
+ if (!adreno_is_a3xx(adreno_dev))
+ kgsl_sharedmem_set(device, &device->scratch, 0, 0,
+ device->scratch.size);
+
ret = kgsl_pwrctrl_change_state(device, KGSL_STATE_INIT);
if (ret)
return ret;
diff --git a/drivers/gpu/msm/adreno_ringbuffer.c b/drivers/gpu/msm/adreno_ringbuffer.c
index d248479..0965923 100644
--- a/drivers/gpu/msm/adreno_ringbuffer.c
+++ b/drivers/gpu/msm/adreno_ringbuffer.c
@@ -225,8 +225,9 @@
FOR_EACH_RINGBUFFER(adreno_dev, rb, i) {
kgsl_sharedmem_set(device, &(rb->buffer_desc),
0, 0xAA, KGSL_RB_SIZE);
- kgsl_sharedmem_writel(device, &device->scratch,
- SCRATCH_RPTR_OFFSET(rb->id), 0);
+ if (!adreno_is_a3xx(adreno_dev))
+ kgsl_sharedmem_writel(device, &device->scratch,
+ SCRATCH_RPTR_OFFSET(rb->id), 0);
rb->wptr = 0;
rb->_wptr = 0;
rb->wptr_preempt_end = 0xFFFFFFFF;
@@ -287,9 +288,16 @@
int adreno_ringbuffer_probe(struct adreno_device *adreno_dev, bool nopreempt)
{
- int status = 0;
+ struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev);
- int i;
+ int i, status;
+
+ if (!adreno_is_a3xx(adreno_dev)) {
+ status = kgsl_allocate_global(device, &device->scratch,
+ PAGE_SIZE, 0, 0, "scratch");
+ if (status != 0)
+ return status;
+ }
if (nopreempt == false)
adreno_dev->num_ringbuffers = gpudev->num_prio_levels;
@@ -325,9 +333,13 @@
void adreno_ringbuffer_close(struct adreno_device *adreno_dev)
{
+ struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
struct adreno_ringbuffer *rb;
int i;
+ if (!adreno_is_a3xx(adreno_dev))
+ kgsl_free_global(device, &device->scratch);
+
FOR_EACH_RINGBUFFER(adreno_dev, rb, i)
_adreno_ringbuffer_close(adreno_dev, rb);
}
diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c
index 7da90c6..31868a0 100644
--- a/drivers/gpu/msm/kgsl.c
+++ b/drivers/gpu/msm/kgsl.c
@@ -1131,8 +1131,6 @@
atomic_inc(&device->active_cnt);
kgsl_sharedmem_set(device, &device->memstore, 0, 0,
device->memstore.size);
- kgsl_sharedmem_set(device, &device->scratch, 0, 0,
- device->scratch.size);
result = device->ftbl->init(device);
if (result)
@@ -4382,13 +4380,13 @@
if (!kgsl_memdesc_use_cpu_map(&entry->memdesc)) {
val = get_unmapped_area(NULL, addr, len, 0, flags);
if (IS_ERR_VALUE(val))
- KGSL_MEM_ERR(device,
+ KGSL_DRV_ERR_RATELIMIT(device,
"get_unmapped_area: pid %d addr %lx pgoff %lx len %ld failed error %d\n",
private->pid, addr, pgoff, len, (int) val);
} else {
val = _get_svm_area(private, entry, addr, len, flags);
if (IS_ERR_VALUE(val))
- KGSL_MEM_ERR(device,
+ KGSL_DRV_ERR_RATELIMIT(device,
"_get_svm_area: pid %d mmap_base %lx addr %lx pgoff %lx len %ld failed error %d\n",
private->pid, current->mm->mmap_base, addr,
pgoff, len, (int) val);
@@ -4689,11 +4687,6 @@
if (status != 0)
goto error_close_mmu;
- status = kgsl_allocate_global(device, &device->scratch,
- PAGE_SIZE, 0, 0, "scratch");
- if (status != 0)
- goto error_free_memstore;
-
/*
* The default request type PM_QOS_REQ_ALL_CORES is
* applicable to all CPU cores that are online and
@@ -4739,8 +4732,6 @@
return 0;
-error_free_memstore:
- kgsl_free_global(device, &device->memstore);
error_close_mmu:
kgsl_mmu_close(device);
error_pwrctrl_close:
@@ -4768,8 +4759,6 @@
idr_destroy(&device->context_idr);
- kgsl_free_global(device, &device->scratch);
-
kgsl_free_global(device, &device->memstore);
kgsl_mmu_close(device);
diff --git a/drivers/gpu/msm/kgsl_gmu.c b/drivers/gpu/msm/kgsl_gmu.c
index 9446f70..57148e0 100644
--- a/drivers/gpu/msm/kgsl_gmu.c
+++ b/drivers/gpu/msm/kgsl_gmu.c
@@ -1283,7 +1283,7 @@
return ret;
}
-#define CX_GDSC_TIMEOUT 500 /* ms */
+#define CX_GDSC_TIMEOUT 5000 /* ms */
static int gmu_disable_gdsc(struct gmu_device *gmu)
{
int ret;
@@ -1302,7 +1302,7 @@
/*
* After GX GDSC is off, CX GDSC must be off
* Voting off alone from GPU driver cannot
- * Guarantee CX GDSC off. Polling with 10ms
+ * Guarantee CX GDSC off. Polling with 5s
* timeout to ensure
*/
t = jiffies + msecs_to_jiffies(CX_GDSC_TIMEOUT);
diff --git a/drivers/gpu/msm/kgsl_log.h b/drivers/gpu/msm/kgsl_log.h
index d79a410..4f1241b 100644
--- a/drivers/gpu/msm/kgsl_log.h
+++ b/drivers/gpu/msm/kgsl_log.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002,2008-2011,2013-2014,2016 The Linux Foundation.
+/* Copyright (c) 2002,2008-2011,2013-2014,2016-2017 The Linux Foundation.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -67,6 +67,13 @@
__func__, ##args);\
} while (0)
+#define KGSL_LOG_ERR_RATELIMITED(dev, lvl, fmt, args...) \
+ do { \
+ if ((lvl) >= 3) \
+ dev_err_ratelimited(dev, "|%s| " fmt, \
+ __func__, ##args);\
+ } while (0)
+
#define KGSL_DRV_INFO(_dev, fmt, args...) \
KGSL_LOG_INFO(_dev->dev, _dev->drv_log, fmt, ##args)
#define KGSL_DRV_WARN(_dev, fmt, args...) \
@@ -77,6 +84,8 @@
KGSL_LOG_CRIT(_dev->dev, _dev->drv_log, fmt, ##args)
#define KGSL_DRV_CRIT_RATELIMIT(_dev, fmt, args...) \
KGSL_LOG_CRIT_RATELIMITED(_dev->dev, _dev->drv_log, fmt, ##args)
+#define KGSL_DRV_ERR_RATELIMIT(_dev, fmt, args...) \
+KGSL_LOG_ERR_RATELIMITED(_dev->dev, _dev->drv_log, fmt, ##args)
#define KGSL_DRV_FATAL(_dev, fmt, args...) \
KGSL_LOG_FATAL((_dev)->dev, (_dev)->drv_log, fmt, ##args)
diff --git a/drivers/i2c/busses/i2c-qcom-geni.c b/drivers/i2c/busses/i2c-qcom-geni.c
index 2460ba7..793cbb5 100644
--- a/drivers/i2c/busses/i2c-qcom-geni.c
+++ b/drivers/i2c/busses/i2c-qcom-geni.c
@@ -881,9 +881,17 @@
return ret;
if (gi2c->se_mode == UNINITIALIZED) {
- u32 se_mode = readl_relaxed(gi2c->base +
- GENI_IF_FIFO_DISABLE_RO);
+ int proto = get_se_proto(gi2c->base);
+ u32 se_mode;
+ if (unlikely(proto != I2C)) {
+ dev_err(gi2c->dev, "Invalid proto %d\n", proto);
+ se_geni_resources_off(&gi2c->i2c_rsc);
+ return -ENXIO;
+ }
+
+ se_mode = readl_relaxed(gi2c->base +
+ GENI_IF_FIFO_DISABLE_RO);
if (se_mode) {
gi2c->se_mode = GSI_ONLY;
geni_se_select_mode(gi2c->base, GSI_DMA);
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 58d5030..1bd8e89 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -1190,6 +1190,7 @@
list_for_each_entry_safe(it, i, &smmu_domain->secure_pool_list, list) {
arm_smmu_unprepare_pgtable(smmu_domain, it->addr, it->size);
/* pages will be freed later (after being unassigned) */
+ list_del(&it->list);
kfree(it);
}
}
diff --git a/drivers/leds/leds-qpnp-wled.c b/drivers/leds/leds-qpnp-wled.c
index 7068212..579705d 100644
--- a/drivers/leds/leds-qpnp-wled.c
+++ b/drivers/leds/leds-qpnp-wled.c
@@ -106,10 +106,8 @@
#define QPNP_WLED_BOOST_DUTY_MIN_NS 26
#define QPNP_WLED_BOOST_DUTY_MAX_NS 156
#define QPNP_WLED_DEF_BOOST_DUTY_NS 104
-#define QPNP_WLED_SWITCH_FREQ_MASK 0x70
-#define QPNP_WLED_SWITCH_FREQ_800_KHZ 800
-#define QPNP_WLED_SWITCH_FREQ_1600_KHZ 1600
-#define QPNP_WLED_SWITCH_FREQ_OVERWRITE 0x80
+#define QPNP_WLED_SWITCH_FREQ_MASK GENMASK(3, 0)
+#define QPNP_WLED_SWITCH_FREQ_OVERWRITE BIT(7)
#define QPNP_WLED_OVP_MASK GENMASK(1, 0)
#define QPNP_WLED_TEST4_EN_DEB_BYPASS_ILIM_BIT BIT(6)
#define QPNP_WLED_TEST4_EN_SH_FOR_SS_BIT BIT(5)
@@ -404,6 +402,7 @@
bool ovp_irq_disabled;
bool auto_calib_enabled;
bool auto_calib_done;
+ bool module_dis_perm;
ktime_t start_ovp_fault_time;
};
@@ -600,6 +599,9 @@
{
int rc;
+ if (wled->module_dis_perm)
+ return 0;
+
rc = qpnp_wled_masked_write_reg(wled,
QPNP_WLED_MODULE_EN_REG(base_addr),
QPNP_WLED_MODULE_EN_MASK,
@@ -1098,7 +1100,7 @@
return 0;
}
-#define AUTO_CALIB_BRIGHTNESS 16
+#define AUTO_CALIB_BRIGHTNESS 200
static int wled_auto_calibrate(struct qpnp_wled *wled)
{
int rc = 0, i;
@@ -1128,6 +1130,17 @@
goto failed_calib;
}
+ if (wled->en_cabc) {
+ for (i = 0; i < wled->max_strings; i++) {
+ reg = 0;
+ rc = qpnp_wled_masked_write_reg(wled,
+ QPNP_WLED_CABC_REG(wled->sink_base, i),
+ QPNP_WLED_CABC_MASK, reg);
+ if (rc < 0)
+ goto failed_calib;
+ }
+ }
+
/* disable all sinks */
rc = qpnp_wled_write_reg(wled,
QPNP_WLED_CURR_SINK_REG(wled->sink_base), 0);
@@ -1136,21 +1149,6 @@
goto failed_calib;
}
- rc = qpnp_wled_masked_write_reg(wled,
- QPNP_WLED_MODULE_EN_REG(wled->ctrl_base),
- QPNP_WLED_MODULE_EN_MASK,
- QPNP_WLED_MODULE_EN_MASK);
- if (rc < 0) {
- pr_err("Failed to enable WLED module rc=%d\n", rc);
- goto failed_calib;
- }
- /*
- * Delay for the WLED soft-start, check the OVP status
- * only after soft-start is complete
- */
- usleep_range(QPNP_WLED_SOFT_START_DLY_US,
- QPNP_WLED_SOFT_START_DLY_US + 1000);
-
/* iterate through the strings one by one */
for (i = 0; i < wled->max_strings; i++) {
sink_test = 1 << (QPNP_WLED_CURR_SINK_SHIFT + i);
@@ -1174,6 +1172,15 @@
goto failed_calib;
}
+ /* Enable the module */
+ rc = qpnp_wled_masked_write_reg(wled,
+ QPNP_WLED_MODULE_EN_REG(wled->ctrl_base),
+ QPNP_WLED_MODULE_EN_MASK, QPNP_WLED_MODULE_EN_MASK);
+ if (rc < 0) {
+ pr_err("Failed to enable WLED module rc=%d\n", rc);
+ goto failed_calib;
+ }
+
/* delay for WLED soft-start */
usleep_range(QPNP_WLED_SOFT_START_DLY_US,
QPNP_WLED_SOFT_START_DLY_US + 1000);
@@ -1190,6 +1197,15 @@
i + 1);
else
sink_valid |= sink_test;
+
+ /* Disable the module */
+ rc = qpnp_wled_masked_write_reg(wled,
+ QPNP_WLED_MODULE_EN_REG(wled->ctrl_base),
+ QPNP_WLED_MODULE_EN_MASK, 0);
+ if (rc < 0) {
+ pr_err("Failed to disable WLED module rc=%d\n", rc);
+ goto failed_calib;
+ }
}
if (sink_valid == sink_config) {
@@ -1203,14 +1219,7 @@
if (!sink_config) {
pr_warn("No valid WLED sinks found\n");
- goto failed_calib;
- }
-
- rc = qpnp_wled_masked_write_reg(wled,
- QPNP_WLED_MODULE_EN_REG(wled->ctrl_base),
- QPNP_WLED_MODULE_EN_MASK, 0);
- if (rc < 0) {
- pr_err("Failed to disable WLED module rc=%d\n", rc);
+ wled->module_dis_perm = true;
goto failed_calib;
}
@@ -1224,6 +1233,15 @@
/* MODULATOR_EN setting for valid sinks */
for (i = 0; i < wled->max_strings; i++) {
+ if (wled->en_cabc) {
+ reg = 1 << QPNP_WLED_CABC_SHIFT;
+ rc = qpnp_wled_masked_write_reg(wled,
+ QPNP_WLED_CABC_REG(wled->sink_base, i),
+ QPNP_WLED_CABC_MASK, reg);
+ if (rc < 0)
+ goto failed_calib;
+ }
+
if (sink_config & (1 << (QPNP_WLED_CURR_SINK_SHIFT + i)))
reg = (QPNP_WLED_MOD_EN << QPNP_WLED_MOD_EN_SHFT);
else
@@ -1785,21 +1803,24 @@
return rc;
/* Configure the SWITCHING FREQ register */
- if (wled->switch_freq_khz == QPNP_WLED_SWITCH_FREQ_1600_KHZ)
- temp = QPNP_WLED_SWITCH_FREQ_1600_KHZ_CODE;
+ if (wled->switch_freq_khz == 1600)
+ reg = QPNP_WLED_SWITCH_FREQ_1600_KHZ_CODE;
else
- temp = QPNP_WLED_SWITCH_FREQ_800_KHZ_CODE;
+ reg = QPNP_WLED_SWITCH_FREQ_800_KHZ_CODE;
- rc = qpnp_wled_read_reg(wled,
- QPNP_WLED_SWITCH_FREQ_REG(wled->ctrl_base), ®);
+ /*
+ * Do not set the overwrite bit when switching frequency is selected
+ * for AMOLED. This register is in logic reset block which can cause
+ * the value to be overwritten during module enable/disable.
+ */
+ mask = QPNP_WLED_SWITCH_FREQ_MASK | QPNP_WLED_SWITCH_FREQ_OVERWRITE;
+ if (!wled->disp_type_amoled)
+ reg |= QPNP_WLED_SWITCH_FREQ_OVERWRITE;
+
+ rc = qpnp_wled_masked_write_reg(wled,
+ QPNP_WLED_SWITCH_FREQ_REG(wled->ctrl_base), mask, reg);
if (rc < 0)
return rc;
- reg &= QPNP_WLED_SWITCH_FREQ_MASK;
- reg |= (temp | QPNP_WLED_SWITCH_FREQ_OVERWRITE);
- rc = qpnp_wled_write_reg(wled,
- QPNP_WLED_SWITCH_FREQ_REG(wled->ctrl_base), reg);
- if (rc)
- return rc;
rc = qpnp_wled_ovp_config(wled);
if (rc < 0) {
@@ -2237,7 +2258,7 @@
return rc;
}
- wled->switch_freq_khz = QPNP_WLED_SWITCH_FREQ_800_KHZ;
+ wled->switch_freq_khz = wled->disp_type_amoled ? 1600 : 800;
rc = of_property_read_u32(pdev->dev.of_node,
"qcom,switch-freq-khz", &temp_val);
if (!rc) {
diff --git a/drivers/md/dm-req-crypt.c b/drivers/md/dm-req-crypt.c
index 3ffe7e5..b4bdbc0 100644
--- a/drivers/md/dm-req-crypt.c
+++ b/drivers/md/dm-req-crypt.c
@@ -217,6 +217,7 @@
* this should never happen
*/
WARN_ON(1);
+ return;
}
} else {
DMERR("%s io is NULL\n", __func__);
@@ -225,6 +226,7 @@
* this should never happen
*/
WARN_ON(1);
+ return;
}
atomic_dec(&io->pending);
@@ -253,6 +255,7 @@
* this should never happen
*/
WARN_ON(1);
+ return;
}
} else {
DMERR("%s io is NULL\n",
@@ -262,6 +265,7 @@
* this should never happen
*/
WARN_ON(1);
+ return;
}
/* Should never get here if io or Clone is NULL */
@@ -445,6 +449,7 @@
if (!io || !io->cloned_request) {
DMERR("%s io is invalid\n", __func__);
WARN_ON(1); /* should not happen */
+ return;
}
clone = io->cloned_request;
@@ -696,6 +701,7 @@
if (!io || !io->cloned_request) {
DMERR("%s io is invalid\n", __func__);
WARN_ON(1); /* should not happen */
+ return;
}
clone = io->cloned_request;
@@ -740,6 +746,7 @@
err = DM_REQ_CRYPT_ERROR;
/* If io is not populated this should not be called */
WARN_ON(1);
+ return;
}
req = skcipher_request_alloc(tfm, GFP_KERNEL);
if (!req) {
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index bc89472..df78c3df2 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -1604,12 +1604,19 @@
/* For Enhance Strobe HS400 flow */
if (card->ext_csd.strobe_support &&
card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400 &&
- card->host->caps & MMC_CAP_8_BIT_DATA)
- err = mmc_select_hs400es(card);
- else if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS200)
+ card->host->caps & MMC_CAP_8_BIT_DATA) {
+ err = mmc_select_hs400(card);
+ if (err) {
+ pr_err("%s: %s: mmc_select_hs400 failed : %d\n",
+ mmc_hostname(card->host), __func__,
+ err);
+ err = mmc_select_hs400es(card);
+ }
+ } else if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS200) {
err = mmc_select_hs200(card);
- else if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS)
+ } else if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS) {
err = mmc_select_hs(card);
+ }
if (err && err != -EBADMSG)
return err;
diff --git a/drivers/pci/host/pci-msm.c b/drivers/pci/host/pci-msm.c
index c857150..bcd7869 100644
--- a/drivers/pci/host/pci-msm.c
+++ b/drivers/pci/host/pci-msm.c
@@ -19,6 +19,7 @@
#include <linux/clk.h>
#include <linux/debugfs.h>
#include <linux/delay.h>
+#include <linux/jiffies.h>
#include <linux/gpio.h>
#include <linux/iopoll.h>
#include <linux/kernel.h>
@@ -146,6 +147,9 @@
#define LINK_UP_TIMEOUT_US_MIN 5000
#define LINK_UP_TIMEOUT_US_MAX 5100
#define LINK_UP_CHECK_MAX_COUNT 20
+#define EP_UP_TIMEOUT_US_MIN 1000
+#define EP_UP_TIMEOUT_US_MAX 1005
+#define EP_UP_TIMEOUT_US 1000000
#define PHY_STABILIZATION_DELAY_US_MIN 995
#define PHY_STABILIZATION_DELAY_US_MAX 1005
#define POWER_DOWN_DELAY_US_MIN 10
@@ -554,6 +558,32 @@
module_param_named(debug_mask, msm_pcie_debug_mask,
int, 0644);
+/*
+ * For each bit set, invert the default capability
+ * option for the corresponding root complex
+ * and its devices.
+ */
+static int msm_pcie_invert_l0s_support;
+module_param_named(invert_l0s_support, msm_pcie_invert_l0s_support,
+ int, 0644);
+static int msm_pcie_invert_l1_support;
+module_param_named(invert_l1_support, msm_pcie_invert_l1_support,
+ int, 0644);
+static int msm_pcie_invert_l1ss_support;
+module_param_named(invert_l1ss_support, msm_pcie_invert_l1ss_support,
+ int, 0644);
+static int msm_pcie_invert_aer_support;
+module_param_named(invert_aer_support, msm_pcie_invert_aer_support,
+ int, 0644);
+
+/*
+ * For each bit set, keep the resources on when link training fails
+ * or linkdown occurs for the corresponding root complex
+ */
+static int msm_pcie_keep_resources_on;
+module_param_named(keep_resources_on, msm_pcie_keep_resources_on,
+ int, 0644);
+
/* debugfs values */
static u32 rc_sel;
static u32 base_sel;
@@ -3626,6 +3656,7 @@
uint32_t val;
long int retries = 0;
int link_check_count = 0;
+ unsigned long ep_up_timeout = 0;
PCIE_DBG(dev, "RC%d: entry\n", dev->rc_idx);
@@ -3786,6 +3817,8 @@
1 - dev->gpio[MSM_PCIE_GPIO_PERST].on);
usleep_range(dev->perst_delay_us_min, dev->perst_delay_us_max);
+ ep_up_timeout = jiffies + usecs_to_jiffies(EP_UP_TIMEOUT_US);
+
/* setup Gen3 specific configurations */
if (dev->max_link_speed == GEN3_SPEED)
msm_pcie_setup_gen3(dev);
@@ -3825,6 +3858,11 @@
goto link_fail;
}
+ dev->link_status = MSM_PCIE_LINK_ENABLED;
+ dev->power_on = true;
+ dev->suspending = false;
+ dev->link_turned_on_counter++;
+
if (dev->switch_latency) {
PCIE_DBG(dev, "switch_latency: %dms\n",
dev->switch_latency);
@@ -3837,6 +3875,28 @@
msm_pcie_config_controller(dev);
+ /* check endpoint configuration space is accessible */
+ while (time_before(jiffies, ep_up_timeout)) {
+ if (readl_relaxed(dev->conf) != PCIE_LINK_DOWN)
+ break;
+ usleep_range(EP_UP_TIMEOUT_US_MIN, EP_UP_TIMEOUT_US_MAX);
+ }
+
+ if (readl_relaxed(dev->conf) != PCIE_LINK_DOWN) {
+ PCIE_DBG(dev,
+ "PCIe: RC%d: endpoint config space is accessible\n",
+ dev->rc_idx);
+ } else {
+ PCIE_ERR(dev,
+ "PCIe: RC%d: endpoint config space is not accessible\n",
+ dev->rc_idx);
+ dev->link_status = MSM_PCIE_LINK_DISABLED;
+ dev->power_on = false;
+ dev->link_turned_off_counter++;
+ ret = -ENODEV;
+ goto link_fail;
+ }
+
if (!dev->msi_gicm_addr)
msm_pcie_config_msi_controller(dev);
@@ -3845,14 +3905,12 @@
if (dev->enumerated)
pci_walk_bus(dev->dev->bus, &msm_pcie_config_device, dev);
- dev->link_status = MSM_PCIE_LINK_ENABLED;
- dev->power_on = true;
- dev->suspending = false;
- dev->link_turned_on_counter++;
-
goto out;
link_fail:
+ if (msm_pcie_keep_resources_on & BIT(dev->rc_idx))
+ goto out;
+
if (dev->gpio[MSM_PCIE_GPIO_EP].num)
gpio_set_value(dev->gpio[MSM_PCIE_GPIO_EP].num,
1 - dev->gpio[MSM_PCIE_GPIO_EP].on);
@@ -4046,8 +4104,9 @@
if (pcie_dev->num_ep > 1)
pcie_dev->pending_ep_reg = true;
- msm_pcie_config_ep_aer(pcie_dev,
- &dev_table_t[index]);
+ if (pcie_dev->aer_enable)
+ msm_pcie_config_ep_aer(pcie_dev,
+ &dev_table_t[index]);
break;
}
@@ -4561,8 +4620,10 @@
panic("User has chosen to panic on linkdown\n");
/* assert PERST */
- gpio_set_value(dev->gpio[MSM_PCIE_GPIO_PERST].num,
- dev->gpio[MSM_PCIE_GPIO_PERST].on);
+ if (!(msm_pcie_keep_resources_on & BIT(dev->rc_idx)))
+ gpio_set_value(dev->gpio[MSM_PCIE_GPIO_PERST].num,
+ dev->gpio[MSM_PCIE_GPIO_PERST].on);
+
PCIE_ERR(dev, "PCIe link is down for RC%d\n", dev->rc_idx);
if (dev->num_ep > 1) {
@@ -5265,16 +5326,25 @@
msm_pcie_dev[rc_idx].l0s_supported =
of_property_read_bool((&pdev->dev)->of_node,
"qcom,l0s-supported");
+ if (msm_pcie_invert_l0s_support & BIT(rc_idx))
+ msm_pcie_dev[rc_idx].l0s_supported =
+ !msm_pcie_dev[rc_idx].l0s_supported;
PCIE_DBG(&msm_pcie_dev[rc_idx], "L0s is %s supported.\n",
msm_pcie_dev[rc_idx].l0s_supported ? "" : "not");
msm_pcie_dev[rc_idx].l1_supported =
of_property_read_bool((&pdev->dev)->of_node,
"qcom,l1-supported");
+ if (msm_pcie_invert_l1_support & BIT(rc_idx))
+ msm_pcie_dev[rc_idx].l1_supported =
+ !msm_pcie_dev[rc_idx].l1_supported;
PCIE_DBG(&msm_pcie_dev[rc_idx], "L1 is %s supported.\n",
msm_pcie_dev[rc_idx].l1_supported ? "" : "not");
msm_pcie_dev[rc_idx].l1ss_supported =
of_property_read_bool((&pdev->dev)->of_node,
"qcom,l1ss-supported");
+ if (msm_pcie_invert_l1ss_support & BIT(rc_idx))
+ msm_pcie_dev[rc_idx].l1ss_supported =
+ !msm_pcie_dev[rc_idx].l1ss_supported;
PCIE_DBG(&msm_pcie_dev[rc_idx], "L1ss is %s supported.\n",
msm_pcie_dev[rc_idx].l1ss_supported ? "" : "not");
msm_pcie_dev[rc_idx].common_clk_en =
@@ -5528,6 +5598,8 @@
msm_pcie_dev[rc_idx].suspending = false;
msm_pcie_dev[rc_idx].wake_counter = 0;
msm_pcie_dev[rc_idx].aer_enable = true;
+ if (msm_pcie_invert_aer_support)
+ msm_pcie_dev[rc_idx].aer_enable = false;
msm_pcie_dev[rc_idx].power_on = false;
msm_pcie_dev[rc_idx].use_msi = false;
msm_pcie_dev[rc_idx].use_pinctrl = false;
diff --git a/drivers/platform/msm/ipa/ipa_clients/rndis_ipa.c b/drivers/platform/msm/ipa/ipa_clients/rndis_ipa.c
index 1c47e69..2e87bd2 100644
--- a/drivers/platform/msm/ipa/ipa_clients/rndis_ipa.c
+++ b/drivers/platform/msm/ipa/ipa_clients/rndis_ipa.c
@@ -2490,9 +2490,13 @@
(struct file *file,
const char __user *buf, size_t count, loff_t *ppos)
{
- struct rndis_ipa_dev *rndis_ipa_ctx = file->private_data;
+ struct rndis_ipa_dev *rndis_ipa_ctx = NULL;
int result;
+ if (file == NULL)
+ return -EFAULT;
+ rndis_ipa_ctx = file->private_data;
+
result = ipa_cfg_ep(rndis_ipa_ctx->usb_to_ipa_hdl, &ipa_to_usb_ep_cfg);
if (result) {
pr_err("failed to re-configure USB to IPA point\n");
diff --git a/drivers/platform/msm/ipa/ipa_v2/Makefile b/drivers/platform/msm/ipa/ipa_v2/Makefile
index 69b8a4c..fb03970 100644
--- a/drivers/platform/msm/ipa/ipa_v2/Makefile
+++ b/drivers/platform/msm/ipa/ipa_v2/Makefile
@@ -1,6 +1,7 @@
obj-$(CONFIG_IPA) += ipat.o
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_uc.o ipa_uc_wdi.o ipa_dma.o ipa_uc_mhi.o ipa_mhi.o ipa_uc_ntn.o \
+ ipa_wdi3_i.o
obj-$(CONFIG_RMNET_IPA) += 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_v2/ipa_flt.c b/drivers/platform/msm/ipa/ipa_v2/ipa_flt.c
index f7b0864..918630f 100644
--- a/drivers/platform/msm/ipa/ipa_v2/ipa_flt.c
+++ b/drivers/platform/msm/ipa/ipa_v2/ipa_flt.c
@@ -23,10 +23,10 @@
static int ipa_generate_hw_rule_from_eq(
const struct ipa_ipfltri_rule_eq *attrib, u8 **buf)
{
- int num_offset_meq_32 = attrib->num_offset_meq_32;
- int num_ihl_offset_range_16 = attrib->num_ihl_offset_range_16;
- int num_ihl_offset_meq_32 = attrib->num_ihl_offset_meq_32;
- int num_offset_meq_128 = attrib->num_offset_meq_128;
+ uint8_t num_offset_meq_32 = attrib->num_offset_meq_32;
+ uint8_t num_ihl_offset_range_16 = attrib->num_ihl_offset_range_16;
+ uint8_t num_ihl_offset_meq_32 = attrib->num_ihl_offset_meq_32;
+ uint8_t num_offset_meq_128 = attrib->num_offset_meq_128;
int i;
if (attrib->tos_eq_present) {
diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_i.h b/drivers/platform/msm/ipa/ipa_v2/ipa_i.h
index 9bfdcdc..67b0be6 100644
--- a/drivers/platform/msm/ipa/ipa_v2/ipa_i.h
+++ b/drivers/platform/msm/ipa/ipa_v2/ipa_i.h
@@ -1546,6 +1546,12 @@
int ipa2_ntn_uc_reg_rdyCB(void (*ipauc_ready_cb)(void *), void *priv);
void ipa2_ntn_uc_dereg_rdyCB(void);
+int ipa2_conn_wdi3_pipes(struct ipa_wdi3_conn_in_params *in,
+ struct ipa_wdi3_conn_out_params *out);
+int ipa2_disconn_wdi3_pipes(int ipa_ep_idx_tx, int ipa_ep_idx_rx);
+int ipa2_enable_wdi3_pipes(int ipa_ep_idx_tx, int ipa_ep_idx_rx);
+int ipa2_disable_wdi3_pipes(int ipa_ep_idx_tx, int ipa_ep_idx_rx);
+
/*
* To retrieve doorbell physical address of
* wlan pipes
diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_qmi_service.c b/drivers/platform/msm/ipa/ipa_v2/ipa_qmi_service.c
index 2608e1d..825c538 100644
--- a/drivers/platform/msm/ipa/ipa_v2/ipa_qmi_service.c
+++ b/drivers/platform/msm/ipa/ipa_v2/ipa_qmi_service.c
@@ -512,6 +512,7 @@
struct ipa_install_fltr_rule_resp_msg_v01 resp;
struct msg_desc req_desc, resp_desc;
int rc;
+ int i;
/* check if the filter rules from IPACM is valid */
if (req->filter_spec_list_len == 0) {
@@ -521,6 +522,38 @@
req->filter_spec_list_len);
}
+ if (req->filter_spec_list_len >= QMI_IPA_MAX_FILTERS_V01) {
+ IPAWANDBG(
+ "IPACM passes the number of filtering rules exceed limit\n");
+ return -EINVAL;
+ } else if (req->source_pipe_index_valid != 0) {
+ IPAWANDBG(
+ "IPACM passes source_pipe_index_valid not zero 0 != %d\n",
+ req->source_pipe_index_valid);
+ return -EINVAL;
+ } else if (req->source_pipe_index >= ipa_ctx->ipa_num_pipes) {
+ IPAWANDBG(
+ "IPACM passes source pipe index not valid ID = %d\n",
+ req->source_pipe_index);
+ return -EINVAL;
+ }
+ for (i = 0; i < req->filter_spec_list_len; i++) {
+ if ((req->filter_spec_list[i].ip_type !=
+ QMI_IPA_IP_TYPE_V4_V01) &&
+ (req->filter_spec_list[i].ip_type !=
+ QMI_IPA_IP_TYPE_V6_V01))
+ return -EINVAL;
+ if (req->filter_spec_list[i].is_mux_id_valid == false)
+ return -EINVAL;
+ if (req->filter_spec_list[i].is_routing_table_index_valid
+ == false)
+ return -EINVAL;
+ if ((req->filter_spec_list[i].filter_action <=
+ QMI_IPA_FILTER_ACTION_INVALID_V01) &&
+ (req->filter_spec_list[i].filter_action >
+ QMI_IPA_FILTER_ACTION_EXCEPTION_V01))
+ return -EINVAL;
+ }
mutex_lock(&ipa_qmi_lock);
if (ipa_qmi_ctx != NULL) {
/* cache the qmi_filter_request */
@@ -673,6 +706,25 @@
req->filter_index_list[i].filter_handle,
req->filter_index_list[i].filter_index);
return -EINVAL;
+ } else if (req->install_status != IPA_QMI_RESULT_SUCCESS_V01) {
+ IPAWANERR(" UL filter rule for pipe %d install_status = %d\n",
+ req->source_pipe_index, req->install_status);
+ return -EINVAL;
+ } else if (req->source_pipe_index >= ipa_ctx->ipa_num_pipes) {
+ IPAWANERR("IPACM passes source pipe index not valid ID = %d\n",
+ req->source_pipe_index);
+ return -EINVAL;
+ } else if (((req->embedded_pipe_index_valid != true) ||
+ (req->embedded_call_mux_id_valid != true)) &&
+ ((req->embedded_pipe_index_valid != false) ||
+ (req->embedded_call_mux_id_valid != false))) {
+ IPAWANERR(
+ "IPACM passes embedded pipe and mux valid not valid\n");
+ return -EINVAL;
+ } else if (req->embedded_pipe_index >= ipa_ctx->ipa_num_pipes) {
+ IPAWANERR("IPACM passes source pipe index not valid ID = %d\n",
+ req->source_pipe_index);
+ return -EINVAL;
}
mutex_lock(&ipa_qmi_lock);
diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_uc_offload_i.h b/drivers/platform/msm/ipa/ipa_v2/ipa_uc_offload_i.h
index a98d602..afe6368 100644
--- a/drivers/platform/msm/ipa/ipa_v2/ipa_uc_offload_i.h
+++ b/drivers/platform/msm/ipa/ipa_v2/ipa_uc_offload_i.h
@@ -26,6 +26,9 @@
#define IPA_NTN_TX_DIR 1
#define IPA_NTN_RX_DIR 2
+#define IPA_WDI3_TX_DIR 1
+#define IPA_WDI3_RX_DIR 2
+
/**
* @brief Enum value determined based on the feature it
* corresponds to
@@ -45,16 +48,20 @@
* enum ipa_hw_features - Values that represent the features supported in IPA HW
* @IPA_HW_FEATURE_COMMON : Feature related to common operation of IPA HW
* @IPA_HW_FEATURE_MHI : Feature related to MHI operation in IPA HW
+ * @IPA_HW_FEATURE_POWER_COLLAPSE: Feature related to IPA Power collapse
* @IPA_HW_FEATURE_WDI : Feature related to WDI operation in IPA HW
* @IPA_HW_FEATURE_NTN : Feature related to NTN operation in IPA HW
* @IPA_HW_FEATURE_OFFLOAD : Feature related to NTN operation in IPA HW
+ * @IPA_HW_FEATURE_WDI3 : Feature related to WDI operation in IPA HW
*/
enum ipa_hw_features {
IPA_HW_FEATURE_COMMON = 0x0,
IPA_HW_FEATURE_MHI = 0x1,
+ IPA_HW_FEATURE_POWER_COLLAPSE = 0x2,
IPA_HW_FEATURE_WDI = 0x3,
IPA_HW_FEATURE_NTN = 0x4,
IPA_HW_FEATURE_OFFLOAD = 0x5,
+ IPA_HW_FEATURE_WDI3 = 0x6,
IPA_HW_FEATURE_MAX = IPA_HW_NUM_FEATURES
};
@@ -277,6 +284,33 @@
} __packed;
+struct IpaHwWdi3SetUpCmdData_t {
+ u32 transfer_ring_base_pa;
+ u32 transfer_ring_base_pa_hi;
+
+ u32 transfer_ring_size;
+
+ u32 transfer_ring_doorbell_pa;
+ u32 transfer_ring_doorbell_pa_hi;
+
+ u32 event_ring_base_pa;
+ u32 event_ring_base_pa_hi;
+
+ u32 event_ring_size;
+
+ u32 event_ring_doorbell_pa;
+ u32 event_ring_doorbell_pa_hi;
+
+ u16 num_pkt_buffers;
+ u8 ipa_pipe_number;
+ u8 dir;
+
+ u16 pkt_offset;
+ u16 reserved0;
+
+ u32 desc_format_template[IPA_HW_WDI3_MAX_ER_DESC_SIZE];
+} __packed;
+
/**
* struct IpaHwNtnCommonChCmdData_t - Structure holding the
* parameters for Ntn Tear down command data params
@@ -291,6 +325,13 @@
uint32_t raw32b;
} __packed;
+union IpaHwWdi3CommonChCmdData_t {
+ struct IpaHwWdi3CommonChCmdParams_t {
+ u32 ipa_pipe_number :8;
+ u32 reserved :24;
+ } __packed params;
+ u32 raw32b;
+} __packed;
/**
* struct IpaHwNTNErrorEventData_t - Structure holding the
@@ -408,13 +449,30 @@
* the offload commands from CPU
* @IPA_CPU_2_HW_CMD_OFFLOAD_CHANNEL_SET_UP : Command to set up
* Offload protocol's Tx/Rx Path
- * @IPA_CPU_2_HW_CMD_OFFLOAD_RX_SET_UP : Command to tear down
+ * @IPA_CPU_2_HW_CMD_OFFLOAD_TEAR_DOWN : Command to tear down
+ * Offload protocol's Tx/ Rx Path
+ * @IPA_CPU_2_HW_CMD_OFFLOAD_ENABLE : Command to enable
+ * Offload protocol's Tx/Rx Path
+ * @IPA_CPU_2_HW_CMD_OFFLOAD_DISABLE : Command to disable
+ * Offload protocol's Tx/ Rx Path
+ * @IPA_CPU_2_HW_CMD_OFFLOAD_SUSPEND : Command to suspend
+ * Offload protocol's Tx/Rx Path
+ * @IPA_CPU_2_HW_CMD_OFFLOAD_RESUME : Command to resume
* Offload protocol's Tx/ Rx Path
*/
enum ipa_cpu_2_hw_offload_commands {
IPA_CPU_2_HW_CMD_OFFLOAD_CHANNEL_SET_UP =
FEATURE_ENUM_VAL(IPA_HW_FEATURE_OFFLOAD, 1),
- IPA_CPU_2_HW_CMD_OFFLOAD_TEAR_DOWN,
+ IPA_CPU_2_HW_CMD_OFFLOAD_TEAR_DOWN =
+ FEATURE_ENUM_VAL(IPA_HW_FEATURE_OFFLOAD, 2),
+ IPA_CPU_2_HW_CMD_OFFLOAD_ENABLE =
+ FEATURE_ENUM_VAL(IPA_HW_FEATURE_OFFLOAD, 3),
+ IPA_CPU_2_HW_CMD_OFFLOAD_DISABLE =
+ FEATURE_ENUM_VAL(IPA_HW_FEATURE_OFFLOAD, 4),
+ IPA_CPU_2_HW_CMD_OFFLOAD_SUSPEND =
+ FEATURE_ENUM_VAL(IPA_HW_FEATURE_OFFLOAD, 5),
+ IPA_CPU_2_HW_CMD_OFFLOAD_RESUME =
+ FEATURE_ENUM_VAL(IPA_HW_FEATURE_OFFLOAD, 6),
};
@@ -525,6 +583,7 @@
*/
union IpaHwSetUpCmd {
struct IpaHwNtnSetUpCmdData_t NtnSetupCh_params;
+ struct IpaHwWdi3SetUpCmdData_t Wdi3SetupCh_params;
} __packed;
/**
@@ -545,6 +604,7 @@
*/
union IpaHwCommonChCmd {
union IpaHwNtnCommonChCmdData_t NtnCommonCh_params;
+ union IpaHwWdi3CommonChCmdData_t Wdi3CommonCh_params;
} __packed;
struct IpaHwOffloadCommonChCmdData_t {
diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_utils.c b/drivers/platform/msm/ipa/ipa_v2/ipa_utils.c
index 2c88244..210ddfe 100644
--- a/drivers/platform/msm/ipa/ipa_v2/ipa_utils.c
+++ b/drivers/platform/msm/ipa/ipa_v2/ipa_utils.c
@@ -5088,6 +5088,10 @@
api_ctrl->ipa_get_pdev = ipa2_get_pdev;
api_ctrl->ipa_ntn_uc_reg_rdyCB = ipa2_ntn_uc_reg_rdyCB;
api_ctrl->ipa_ntn_uc_dereg_rdyCB = ipa2_ntn_uc_dereg_rdyCB;
+ api_ctrl->ipa_conn_wdi3_pipes = ipa2_conn_wdi3_pipes;
+ api_ctrl->ipa_disconn_wdi3_pipes = ipa2_disconn_wdi3_pipes;
+ api_ctrl->ipa_enable_wdi3_pipes = ipa2_enable_wdi3_pipes;
+ api_ctrl->ipa_disable_wdi3_pipes = ipa2_disable_wdi3_pipes;
return 0;
}
diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_wdi3_i.c b/drivers/platform/msm/ipa/ipa_v2/ipa_wdi3_i.c
new file mode 100644
index 0000000..a2c33a1
--- /dev/null
+++ b/drivers/platform/msm/ipa/ipa_v2/ipa_wdi3_i.c
@@ -0,0 +1,406 @@
+/* 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 "ipa_i.h"
+#include "ipa_uc_offload_i.h"
+#include <linux/ipa_wdi3.h>
+
+#define IPA_HW_WDI3_RX_MBOX_START_INDEX 48
+#define IPA_HW_WDI3_TX_MBOX_START_INDEX 50
+
+static int ipa_send_wdi3_setup_pipe_cmd(
+ struct ipa_wdi3_setup_info *info, u8 dir)
+{
+ int ipa_ep_idx;
+ int result = 0;
+ struct ipa_mem_buffer cmd;
+ struct IpaHwWdi3SetUpCmdData_t *wdi3_params;
+ struct IpaHwOffloadSetUpCmdData_t *cmd_data;
+
+ if (info == NULL) {
+ IPAERR("invalid input\n");
+ return -EINVAL;
+ }
+
+ ipa_ep_idx = ipa_get_ep_mapping(info->client);
+ IPAERR("ep number: %d\n", ipa_ep_idx);
+ if (ipa_ep_idx == -1) {
+ IPAERR("fail to get ep idx.\n");
+ return -EFAULT;
+ }
+
+ IPAERR("client=%d ep=%d\n", info->client, ipa_ep_idx);
+ IPAERR("ring_base_pa = 0x%pad\n", &info->transfer_ring_base_pa);
+ IPAERR("ring_size = %hu\n", info->transfer_ring_size);
+ IPAERR("ring_db_pa = 0x%pad\n", &info->transfer_ring_doorbell_pa);
+ IPAERR("evt_ring_base_pa = 0x%pad\n", &info->event_ring_base_pa);
+ IPAERR("evt_ring_size = %hu\n", info->event_ring_size);
+ IPAERR("evt_ring_db_pa = 0x%pad\n", &info->event_ring_doorbell_pa);
+ IPAERR("num_pkt_buffers = %hu\n", info->num_pkt_buffers);
+ IPAERR("pkt_offset = %d.\n", info->pkt_offset);
+
+ cmd.size = sizeof(*cmd_data);
+ cmd.base = dma_alloc_coherent(ipa_ctx->uc_pdev, cmd.size,
+ &cmd.phys_base, GFP_KERNEL);
+ if (cmd.base == NULL) {
+ IPAERR("fail to get DMA memory.\n");
+ return -ENOMEM;
+ }
+ IPAERR("suceeded in allocating memory.\n");
+
+ cmd_data = (struct IpaHwOffloadSetUpCmdData_t *)cmd.base;
+ cmd_data->protocol = IPA_HW_FEATURE_WDI3;
+
+ wdi3_params = &cmd_data->SetupCh_params.Wdi3SetupCh_params;
+ wdi3_params->transfer_ring_base_pa = (u32)info->transfer_ring_base_pa;
+ wdi3_params->transfer_ring_base_pa_hi =
+ (u32)((u64)info->transfer_ring_base_pa >> 32);
+ wdi3_params->transfer_ring_size = info->transfer_ring_size;
+ wdi3_params->transfer_ring_doorbell_pa =
+ (u32)info->transfer_ring_doorbell_pa;
+ wdi3_params->transfer_ring_doorbell_pa_hi =
+ (u32)((u64)info->transfer_ring_doorbell_pa >> 32);
+ wdi3_params->event_ring_base_pa = (u32)info->event_ring_base_pa;
+ wdi3_params->event_ring_base_pa_hi =
+ (u32)((u64)info->event_ring_base_pa >> 32);
+ wdi3_params->event_ring_size = info->event_ring_size;
+ wdi3_params->event_ring_doorbell_pa =
+ (u32)info->event_ring_doorbell_pa;
+ wdi3_params->event_ring_doorbell_pa_hi =
+ (u32)((u64)info->event_ring_doorbell_pa >> 32);
+ wdi3_params->num_pkt_buffers = info->num_pkt_buffers;
+ wdi3_params->ipa_pipe_number = ipa_ep_idx;
+ wdi3_params->dir = dir;
+ wdi3_params->pkt_offset = info->pkt_offset;
+ memcpy(wdi3_params->desc_format_template, info->desc_format_template,
+ sizeof(wdi3_params->desc_format_template));
+ IPAERR("suceeded in populating the command memory.\n");
+
+ result = ipa_uc_send_cmd((u32)(cmd.phys_base),
+ IPA_CPU_2_HW_CMD_OFFLOAD_CHANNEL_SET_UP,
+ IPA_HW_2_CPU_OFFLOAD_CMD_STATUS_SUCCESS,
+ false, 10*HZ);
+ if (result) {
+ IPAERR("uc setup channel cmd failed: %d\n", result);
+ result = -EFAULT;
+ }
+
+ dma_free_coherent(ipa_ctx->uc_pdev, cmd.size, cmd.base, cmd.phys_base);
+ IPAERR("suceeded in freeing memory.\n");
+ return result;
+}
+
+int ipa2_conn_wdi3_pipes(struct ipa_wdi3_conn_in_params *in,
+ struct ipa_wdi3_conn_out_params *out)
+{
+ struct ipa_ep_context *ep_rx;
+ struct ipa_ep_context *ep_tx;
+ int ipa_ep_idx_rx;
+ int ipa_ep_idx_tx;
+ int result = 0;
+
+ if (in == NULL || out == NULL) {
+ IPAERR("invalid input\n");
+ return -EINVAL;
+ }
+
+ ipa_ep_idx_rx = ipa_get_ep_mapping(in->rx.client);
+ ipa_ep_idx_tx = ipa_get_ep_mapping(in->tx.client);
+ if (ipa_ep_idx_rx == -1 || ipa_ep_idx_tx == -1) {
+ IPAERR("fail to alloc EP.\n");
+ return -EFAULT;
+ }
+
+ ep_rx = &ipa_ctx->ep[ipa_ep_idx_rx];
+ ep_tx = &ipa_ctx->ep[ipa_ep_idx_tx];
+
+ if (ep_rx->valid || ep_tx->valid) {
+ IPAERR("EP already allocated.\n");
+ return -EFAULT;
+ }
+
+ memset(ep_rx, 0, offsetof(struct ipa_ep_context, sys));
+ memset(ep_tx, 0, offsetof(struct ipa_ep_context, sys));
+
+ IPA_ACTIVE_CLIENTS_INC_SIMPLE();
+
+ /* setup rx ep cfg */
+ ep_rx->valid = 1;
+ ep_rx->client = in->rx.client;
+ result = ipa_disable_data_path(ipa_ep_idx_rx);
+ if (result) {
+ IPAERR("disable data path failed res=%d clnt=%d.\n", result,
+ ipa_ep_idx_rx);
+ IPA_ACTIVE_CLIENTS_DEC_SIMPLE();
+ return -EFAULT;
+ }
+ ep_rx->client_notify = in->notify;
+ ep_rx->priv = in->priv;
+
+ memcpy(&ep_rx->cfg, &in->rx.ipa_ep_cfg, sizeof(ep_rx->cfg));
+
+ if (ipa_cfg_ep(ipa_ep_idx_rx, &ep_rx->cfg)) {
+ IPAERR("fail to setup rx pipe cfg\n");
+ result = -EFAULT;
+ goto fail;
+ }
+ IPAERR("configured RX EP.\n");
+
+ if (ipa_send_wdi3_setup_pipe_cmd(&in->rx, IPA_WDI3_RX_DIR)) {
+ IPAERR("fail to send cmd to uc for rx pipe\n");
+ result = -EFAULT;
+ goto fail;
+ }
+ IPAERR("rx pipe was setup.\n");
+
+ ipa_install_dflt_flt_rules(ipa_ep_idx_rx);
+ out->rx_uc_db_pa = ipa_ctx->ipa_wrapper_base +
+ IPA_REG_BASE_OFST_v2_5 +
+ IPA_UC_MAILBOX_m_n_OFFS_v2_5(
+ IPA_HW_WDI3_RX_MBOX_START_INDEX/32,
+ IPA_HW_WDI3_RX_MBOX_START_INDEX % 32);
+ IPADBG("client %d (ep: %d) connected\n", in->rx.client,
+ ipa_ep_idx_rx);
+
+ /* setup dl ep cfg */
+ ep_tx->valid = 1;
+ ep_tx->client = in->tx.client;
+ result = ipa_disable_data_path(ipa_ep_idx_tx);
+ if (result) {
+ IPAERR("disable data path failed res=%d clnt=%d.\n", result,
+ ipa_ep_idx_tx);
+ result = -EFAULT;
+ goto fail;
+ }
+
+ memcpy(&ep_tx->cfg, &in->tx.ipa_ep_cfg, sizeof(ep_tx->cfg));
+
+ if (ipa_cfg_ep(ipa_ep_idx_tx, &ep_tx->cfg)) {
+ IPAERR("fail to setup tx pipe cfg\n");
+ result = -EFAULT;
+ goto fail;
+ }
+ IPAERR("configured TX EP in DMA mode.\n");
+
+ if (ipa_send_wdi3_setup_pipe_cmd(&in->tx, IPA_WDI3_TX_DIR)) {
+ IPAERR("fail to send cmd to uc for tx pipe\n");
+ result = -EFAULT;
+ goto fail;
+ }
+ IPAERR("tx pipe was setup.\n");
+
+ out->tx_uc_db_pa = ipa_ctx->ipa_wrapper_base +
+ IPA_REG_BASE_OFST_v2_5 +
+ IPA_UC_MAILBOX_m_n_OFFS_v2_5(
+ IPA_HW_WDI3_TX_MBOX_START_INDEX/32,
+ IPA_HW_WDI3_TX_MBOX_START_INDEX % 32);
+ out->tx_uc_db_va = ioremap(out->tx_uc_db_pa, 4);
+ IPADBG("client %d (ep: %d) connected\n", in->tx.client,
+ ipa_ep_idx_tx);
+
+fail:
+ IPA_ACTIVE_CLIENTS_DEC_SIMPLE();
+ return result;
+}
+
+static int ipa_send_wdi3_common_ch_cmd(int ipa_ep_idx, int command)
+{
+ struct ipa_mem_buffer cmd;
+ struct IpaHwOffloadCommonChCmdData_t *cmd_data;
+ union IpaHwWdi3CommonChCmdData_t *wdi3;
+ int result = 0;
+
+ cmd.size = sizeof(*cmd_data);
+ cmd.base = dma_alloc_coherent(ipa_ctx->uc_pdev, cmd.size,
+ &cmd.phys_base, GFP_KERNEL);
+ if (cmd.base == NULL) {
+ IPAERR("fail to get DMA memory.\n");
+ return -ENOMEM;
+ }
+
+ IPA_ACTIVE_CLIENTS_INC_SIMPLE();
+ /* enable the TX pipe */
+ cmd_data = (struct IpaHwOffloadCommonChCmdData_t *)cmd.base;
+ cmd_data->protocol = IPA_HW_FEATURE_WDI3;
+
+ wdi3 = &cmd_data->CommonCh_params.Wdi3CommonCh_params;
+ wdi3->params.ipa_pipe_number = ipa_ep_idx;
+ IPAERR("cmd: %d ep_idx: %d\n", command, ipa_ep_idx);
+ result = ipa_uc_send_cmd((u32)(cmd.phys_base), command,
+ IPA_HW_2_CPU_OFFLOAD_CMD_STATUS_SUCCESS,
+ false, 10*HZ);
+ if (result) {
+ result = -EFAULT;
+ goto fail;
+ }
+
+fail:
+ dma_free_coherent(ipa_ctx->uc_pdev, cmd.size, cmd.base, cmd.phys_base);
+ IPA_ACTIVE_CLIENTS_DEC_SIMPLE();
+ return result;
+}
+
+int ipa2_disconn_wdi3_pipes(int ipa_ep_idx_tx, int ipa_ep_idx_rx)
+{
+ struct ipa_ep_context *ep_tx, *ep_rx;
+ int result = 0;
+
+ IPADBG("ep_tx = %d\n", ipa_ep_idx_tx);
+ IPADBG("ep_rx = %d\n", ipa_ep_idx_rx);
+
+ ep_tx = &ipa_ctx->ep[ipa_ep_idx_tx];
+ ep_rx = &ipa_ctx->ep[ipa_ep_idx_rx];
+
+ /* tear down tx pipe */
+ if (ipa_send_wdi3_common_ch_cmd(ipa_ep_idx_tx,
+ IPA_CPU_2_HW_CMD_OFFLOAD_TEAR_DOWN)) {
+ IPAERR("fail to tear down tx pipe\n");
+ result = -EFAULT;
+ goto fail;
+ }
+ ipa_disable_data_path(ipa_ep_idx_tx);
+ memset(ep_tx, 0, sizeof(struct ipa_ep_context));
+ IPADBG("tx client (ep: %d) disconnected\n", ipa_ep_idx_tx);
+
+ /* tear down rx pipe */
+ if (ipa_send_wdi3_common_ch_cmd(ipa_ep_idx_rx,
+ IPA_CPU_2_HW_CMD_OFFLOAD_TEAR_DOWN)) {
+ IPAERR("fail to tear down rx pipe\n");
+ result = -EFAULT;
+ goto fail;
+ }
+ ipa_disable_data_path(ipa_ep_idx_rx);
+ ipa_delete_dflt_flt_rules(ipa_ep_idx_rx);
+ memset(ep_rx, 0, sizeof(struct ipa_ep_context));
+ IPADBG("rx client (ep: %d) disconnected\n", ipa_ep_idx_rx);
+
+fail:
+ return result;
+}
+
+int ipa2_enable_wdi3_pipes(int ipa_ep_idx_tx, int ipa_ep_idx_rx)
+{
+ struct ipa_ep_context *ep_tx, *ep_rx;
+ int result = 0;
+
+ IPAERR("ep_tx = %d\n", ipa_ep_idx_tx);
+ IPAERR("ep_rx = %d\n", ipa_ep_idx_rx);
+
+ ep_tx = &ipa_ctx->ep[ipa_ep_idx_tx];
+ ep_rx = &ipa_ctx->ep[ipa_ep_idx_rx];
+
+ /* enable tx pipe */
+ if (ipa_send_wdi3_common_ch_cmd(ipa_ep_idx_tx,
+ IPA_CPU_2_HW_CMD_OFFLOAD_ENABLE)) {
+ IPAERR("fail to enable tx pipe\n");
+ WARN_ON(1);
+ result = -EFAULT;
+ goto fail;
+ }
+
+ /* resume tx pipe */
+ if (ipa_send_wdi3_common_ch_cmd(ipa_ep_idx_tx,
+ IPA_CPU_2_HW_CMD_OFFLOAD_RESUME)) {
+ IPAERR("fail to resume tx pipe\n");
+ WARN_ON(1);
+ result = -EFAULT;
+ goto fail;
+ }
+
+ /* enable rx pipe */
+ if (ipa_send_wdi3_common_ch_cmd(ipa_ep_idx_rx,
+ IPA_CPU_2_HW_CMD_OFFLOAD_ENABLE)) {
+ IPAERR("fail to enable rx pipe\n");
+ WARN_ON(1);
+ result = -EFAULT;
+ goto fail;
+ }
+
+ /* resume rx pipe */
+ if (ipa_send_wdi3_common_ch_cmd(ipa_ep_idx_rx,
+ IPA_CPU_2_HW_CMD_OFFLOAD_RESUME)) {
+ IPAERR("fail to resume rx pipe\n");
+ WARN_ON(1);
+ result = -EFAULT;
+ goto fail;
+ }
+
+ IPA_ACTIVE_CLIENTS_INC_SIMPLE();
+
+ /* enable data path */
+ result = ipa_enable_data_path(ipa_ep_idx_rx);
+ if (result) {
+ IPAERR("enable data path failed res=%d clnt=%d.\n", result,
+ ipa_ep_idx_rx);
+ IPA_ACTIVE_CLIENTS_DEC_SIMPLE();
+ return -EFAULT;
+ }
+
+ result = ipa_enable_data_path(ipa_ep_idx_tx);
+ if (result) {
+ IPAERR("enable data path failed res=%d clnt=%d.\n", result,
+ ipa_ep_idx_tx);
+ IPA_ACTIVE_CLIENTS_DEC_SIMPLE();
+ return -EFAULT;
+ }
+
+ IPA_ACTIVE_CLIENTS_DEC_SIMPLE();
+
+fail:
+ return result;
+}
+
+int ipa2_disable_wdi3_pipes(int ipa_ep_idx_tx, int ipa_ep_idx_rx)
+{
+ struct ipa_ep_context *ep_tx, *ep_rx;
+ int result = 0;
+
+ IPADBG("ep_tx = %d\n", ipa_ep_idx_tx);
+ IPADBG("ep_rx = %d\n", ipa_ep_idx_rx);
+
+ ep_tx = &ipa_ctx->ep[ipa_ep_idx_tx];
+ ep_rx = &ipa_ctx->ep[ipa_ep_idx_rx];
+
+ /* suspend tx pipe */
+ if (ipa_send_wdi3_common_ch_cmd(ipa_ep_idx_tx,
+ IPA_CPU_2_HW_CMD_OFFLOAD_SUSPEND)) {
+ IPAERR("fail to suspend tx pipe\n");
+ result = -EFAULT;
+ goto fail;
+ }
+
+ /* disable tx pipe */
+ if (ipa_send_wdi3_common_ch_cmd(ipa_ep_idx_tx,
+ IPA_CPU_2_HW_CMD_OFFLOAD_DISABLE)) {
+ IPAERR("fail to disable tx pipe\n");
+ result = -EFAULT;
+ goto fail;
+ }
+
+ /* suspend rx pipe */
+ if (ipa_send_wdi3_common_ch_cmd(ipa_ep_idx_rx,
+ IPA_CPU_2_HW_CMD_OFFLOAD_SUSPEND)) {
+ IPAERR("fail to suspend rx pipe\n");
+ result = -EFAULT;
+ goto fail;
+ }
+
+ /* disable rx pipe */
+ if (ipa_send_wdi3_common_ch_cmd(ipa_ep_idx_rx,
+ IPA_CPU_2_HW_CMD_OFFLOAD_DISABLE)) {
+ IPAERR("fail to disable rx pipe\n");
+ result = -EFAULT;
+ goto fail;
+ }
+
+fail:
+ return result;
+}
diff --git a/drivers/platform/msm/ipa/ipa_v2/rmnet_ipa.c b/drivers/platform/msm/ipa/ipa_v2/rmnet_ipa.c
index 39a1cc2..8ea1d99 100644
--- a/drivers/platform/msm/ipa/ipa_v2/rmnet_ipa.c
+++ b/drivers/platform/msm/ipa/ipa_v2/rmnet_ipa.c
@@ -649,6 +649,8 @@
return -ENOMEM;
}
+ memset(req, 0, sizeof(struct ipa_fltr_installed_notif_req_msg_v01));
+
param->commit = 1;
param->ep = IPA_CLIENT_APPS_LAN_WAN_PROD;
param->global = false;
@@ -1516,8 +1518,8 @@
/* Get driver name */
case RMNET_IOCTL_GET_DRIVER_NAME:
memcpy(&extend_ioctl_data.u.if_name,
- ipa_netdevs[0]->name,
- sizeof(IFNAMSIZ));
+ ipa_netdevs[0]->name, IFNAMSIZ);
+ extend_ioctl_data.u.if_name[IFNAMSIZ - 1] = '\0';
if (copy_to_user((u8 *)ifr->ifr_ifru.ifru_data,
&extend_ioctl_data,
sizeof(struct rmnet_ioctl_extended_s)))
@@ -1540,6 +1542,8 @@
mutex_unlock(&add_mux_channel_lock);
return -EFAULT;
}
+ extend_ioctl_data.u.rmnet_mux_val.vchannel_name
+ [IFNAMSIZ-1] = '\0';
IPAWANDBG("ADD_MUX_CHANNEL(%d, name: %s)\n",
extend_ioctl_data.u.rmnet_mux_val.mux_id,
extend_ioctl_data.u.rmnet_mux_val.vchannel_name);
@@ -1661,6 +1665,7 @@
sizeof(wan_msg->upstream_ifname);
strlcpy(wan_msg->upstream_ifname,
extend_ioctl_data.u.if_name, len);
+ wan_msg->upstream_ifname[len - 1] = '\0';
memset(&msg_meta, 0, sizeof(struct ipa_msg_meta));
msg_meta.msg_type = WAN_XLAT_CONNECT;
msg_meta.msg_len = sizeof(struct ipa_wan_msg);
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa.c b/drivers/platform/msm/ipa/ipa_v3/ipa.c
index 180d03eb..a40d038 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa.c
@@ -4446,6 +4446,9 @@
return -EFAULT;
}
+ if (count > 0)
+ dbg_buff[count - 1] = '\0';
+
/* Prevent consequent calls from trying to load the FW again. */
if (ipa3_is_ready())
return count;
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c b/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c
index cd19a91..ee312c7 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c
@@ -3816,7 +3816,7 @@
cnt += IPA_WAN_AGGR_PKT_CNT;
total_cnt++;
- if (ep->sys->len == 0 || total_cnt >= ep->sys->rx_pool_sz) {
+ if (ep->sys->len == 0) {
total_cnt = 0;
cnt = cnt-1;
break;
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 fbaa4ae..e3a3821 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c
@@ -603,15 +603,49 @@
struct ipa_install_fltr_rule_resp_msg_v01 resp;
struct msg_desc req_desc, resp_desc;
int rc;
+ int i;
/* check if the filter rules from IPACM is valid */
- if (req->filter_spec_ex_list_len == 0) {
+ if (req->filter_spec_list_len == 0) {
IPAWANDBG("IPACM pass zero rules to Q6\n");
} else {
IPAWANDBG("IPACM pass %u rules to Q6\n",
req->filter_spec_ex_list_len);
}
+ if (req->filter_spec_list_len >= QMI_IPA_MAX_FILTERS_V01) {
+ IPAWANDBG(
+ "IPACM passes the number of filtering rules exceed limit\n");
+ return -EINVAL;
+ } else if (req->source_pipe_index_valid != 0) {
+ IPAWANDBG(
+ "IPACM passes source_pipe_index_valid not zero 0 != %d\n",
+ req->source_pipe_index_valid);
+ return -EINVAL;
+ } else if (req->source_pipe_index >= ipa3_ctx->ipa_num_pipes) {
+ IPAWANDBG(
+ "IPACM passes source pipe index not valid ID = %d\n",
+ req->source_pipe_index);
+ return -EINVAL;
+ }
+ for (i = 0; i < req->filter_spec_list_len; i++) {
+ if ((req->filter_spec_list[i].ip_type !=
+ QMI_IPA_IP_TYPE_V4_V01) &&
+ (req->filter_spec_list[i].ip_type !=
+ QMI_IPA_IP_TYPE_V6_V01))
+ return -EINVAL;
+ if (req->filter_spec_list[i].is_mux_id_valid == false)
+ return -EINVAL;
+ if (req->filter_spec_list[i].is_routing_table_index_valid
+ == false)
+ return -EINVAL;
+ if ((req->filter_spec_list[i].filter_action <=
+ QMI_IPA_FILTER_ACTION_INVALID_V01) &&
+ (req->filter_spec_list[i].filter_action >
+ QMI_IPA_FILTER_ACTION_EXCEPTION_V01))
+ return -EINVAL;
+ }
+
mutex_lock(&ipa3_qmi_lock);
if (ipa3_qmi_ctx != NULL) {
/* cache the qmi_filter_request */
@@ -653,6 +687,7 @@
struct ipa_install_fltr_rule_resp_ex_msg_v01 resp;
struct msg_desc req_desc, resp_desc;
int rc;
+ int i;
/* check if the filter rules from IPACM is valid */
if (req->filter_spec_ex_list_len == 0) {
@@ -662,6 +697,34 @@
req->filter_spec_ex_list_len);
}
+ if (req->filter_spec_ex_list_len >= QMI_IPA_MAX_FILTERS_EX_V01) {
+ IPAWANDBG(
+ "IPACM pass the number of filtering rules exceed limit\n");
+ return -EINVAL;
+ } else if (req->source_pipe_index_valid != 0) {
+ IPAWANDBG(
+ "IPACM passes source_pipe_index_valid not zero 0 != %d\n",
+ req->source_pipe_index_valid);
+ return -EINVAL;
+ }
+
+ for (i = 0; i < req->filter_spec_ex_list_len-1; i++) {
+ if ((req->filter_spec_ex_list[i].ip_type !=
+ QMI_IPA_IP_TYPE_V4_V01) &&
+ (req->filter_spec_ex_list[i].ip_type !=
+ QMI_IPA_IP_TYPE_V6_V01))
+ return -EINVAL;
+ if (req->filter_spec_ex_list[i].is_mux_id_valid == false)
+ return -EINVAL;
+ if (req->filter_spec_ex_list[i].is_routing_table_index_valid
+ == false)
+ return -EINVAL;
+ if ((req->filter_spec_ex_list[i].filter_action <=
+ QMI_IPA_FILTER_ACTION_INVALID_V01) &&
+ (req->filter_spec_ex_list[i].filter_action >
+ QMI_IPA_FILTER_ACTION_EXCEPTION_V01))
+ return -EINVAL;
+ }
mutex_lock(&ipa3_qmi_lock);
if (ipa3_qmi_ctx != NULL) {
/* cache the qmi_filter_request */
@@ -805,6 +868,30 @@
req->source_pipe_index,
req->rule_id_len);
return -EINVAL;
+ } else if (req->install_status != IPA_QMI_RESULT_SUCCESS_V01) {
+ IPAWANERR(" UL filter rule for pipe %d install_status = %d\n",
+ req->source_pipe_index, req->install_status);
+ return -EINVAL;
+ } else if (req->rule_id_valid != 1) {
+ IPAWANERR(" UL filter rule for pipe %d rule_id_valid = %d\n",
+ req->source_pipe_index, req->rule_id_valid);
+ return -EINVAL;
+ } else if (req->source_pipe_index >= ipa3_ctx->ipa_num_pipes) {
+ IPAWANDBG(
+ "IPACM passes source pipe index not valid ID = %d\n",
+ req->source_pipe_index);
+ return -EINVAL;
+ } else if (((req->embedded_pipe_index_valid != true) ||
+ (req->embedded_call_mux_id_valid != true)) &&
+ ((req->embedded_pipe_index_valid != false) ||
+ (req->embedded_call_mux_id_valid != false))) {
+ IPAWANERR(
+ "IPACM passes embedded pipe and mux valid not valid\n");
+ return -EINVAL;
+ } else if (req->embedded_pipe_index >= ipa3_ctx->ipa_num_pipes) {
+ IPAWANERR("IPACM passes source pipe index not valid ID = %d\n",
+ req->source_pipe_index);
+ return -EINVAL;
}
if (req->source_pipe_index == -1) {
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_fltrt.c b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_fltrt.c
index acc72f0..d6dbc85 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_fltrt.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_fltrt.c
@@ -1500,10 +1500,10 @@
static int ipa_fltrt_generate_hw_rule_bdy_from_eq(
const struct ipa_ipfltri_rule_eq *attrib, u8 **buf)
{
- int num_offset_meq_32 = attrib->num_offset_meq_32;
- int num_ihl_offset_range_16 = attrib->num_ihl_offset_range_16;
- int num_ihl_offset_meq_32 = attrib->num_ihl_offset_meq_32;
- int num_offset_meq_128 = attrib->num_offset_meq_128;
+ uint8_t num_offset_meq_32 = attrib->num_offset_meq_32;
+ uint8_t num_ihl_offset_range_16 = attrib->num_ihl_offset_range_16;
+ uint8_t num_ihl_offset_meq_32 = attrib->num_ihl_offset_meq_32;
+ uint8_t num_offset_meq_128 = attrib->num_offset_meq_128;
int i;
int extra_bytes;
u8 *extra;
diff --git a/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c b/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c
index e5791b1..e93210d 100644
--- a/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c
+++ b/drivers/platform/msm/ipa/ipa_v3/rmnet_ipa.c
@@ -677,6 +677,8 @@
param->global = false;
param->num_rules = (uint8_t)1;
+ memset(req, 0, sizeof(struct ipa_fltr_installed_notif_req_msg_v01));
+
for (i = 0; i < rmnet_ipa3_ctx->num_q6_rules; i++) {
param->ip = ipa3_qmi_ctx->q6_ul_filter_rule[i].ip;
memset(&flt_rule_entry, 0, sizeof(struct ipa_flt_rule_add));
@@ -1639,8 +1641,8 @@
/* Get driver name */
case RMNET_IOCTL_GET_DRIVER_NAME:
memcpy(&extend_ioctl_data.u.if_name,
- IPA_NETDEV()->name,
- sizeof(IFNAMSIZ));
+ IPA_NETDEV()->name, IFNAMSIZ);
+ extend_ioctl_data.u.if_name[IFNAMSIZ - 1] = '\0';
if (copy_to_user((u8 *)ifr->ifr_ifru.ifru_data,
&extend_ioctl_data,
sizeof(struct rmnet_ioctl_extended_s)))
@@ -1665,6 +1667,8 @@
add_mux_channel_lock);
return -EFAULT;
}
+ extend_ioctl_data.u.rmnet_mux_val.vchannel_name
+ [IFNAMSIZ-1] = '\0';
IPAWANDBG("ADD_MUX_CHANNEL(%d, name: %s)\n",
extend_ioctl_data.u.rmnet_mux_val.mux_id,
extend_ioctl_data.u.rmnet_mux_val.vchannel_name);
@@ -1731,6 +1735,7 @@
sizeof(wan_msg->upstream_ifname);
strlcpy(wan_msg->upstream_ifname,
extend_ioctl_data.u.if_name, len);
+ wan_msg->upstream_ifname[len-1] = '\0';
memset(&msg_meta, 0, sizeof(struct ipa_msg_meta));
msg_meta.msg_type = WAN_XLAT_CONNECT;
msg_meta.msg_len = sizeof(struct ipa_wan_msg);
diff --git a/drivers/platform/msm/ipa/test/ipa_ut_framework.c b/drivers/platform/msm/ipa/test/ipa_ut_framework.c
index 3bf9ac1..dfc8442 100644
--- a/drivers/platform/msm/ipa/test/ipa_ut_framework.c
+++ b/drivers/platform/msm/ipa/test/ipa_ut_framework.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
+/* 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
@@ -215,6 +215,10 @@
IPA_UT_DBG("Entry\n");
mutex_lock(&ipa_ut_ctx->lock);
+ if (file == NULL) {
+ rc = -EFAULT;
+ goto unlock_mutex;
+ }
suite = file->f_inode->i_private;
ipa_assert_on(!suite);
meta_type = (long)(file->private_data);
@@ -470,6 +474,10 @@
IPA_UT_DBG("Entry\n");
mutex_lock(&ipa_ut_ctx->lock);
+ if (file == NULL) {
+ rc = -EFAULT;
+ goto unlock_mutex;
+ }
test = file->f_inode->i_private;
ipa_assert_on(!test);
diff --git a/drivers/power/supply/qcom/qpnp-fg-gen3.c b/drivers/power/supply/qcom/qpnp-fg-gen3.c
index 48e42f2..2a47442 100644
--- a/drivers/power/supply/qcom/qpnp-fg-gen3.c
+++ b/drivers/power/supply/qcom/qpnp-fg-gen3.c
@@ -4642,7 +4642,7 @@
#define DEFAULT_BATT_TEMP_HOT 50
#define DEFAULT_CL_START_SOC 15
#define DEFAULT_CL_MIN_TEMP_DECIDEGC 150
-#define DEFAULT_CL_MAX_TEMP_DECIDEGC 450
+#define DEFAULT_CL_MAX_TEMP_DECIDEGC 500
#define DEFAULT_CL_MAX_INC_DECIPERC 5
#define DEFAULT_CL_MAX_DEC_DECIPERC 100
#define DEFAULT_CL_MIN_LIM_DECIPERC 0
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 0f87985..b98d2ae 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -172,6 +172,9 @@
}
#endif
+#define PWR_INFO_MASK 0xF
+#define PWR_RX_OFFSET 4
+
#define UFSHCD_REQ_SENSE_SIZE 18
#define UFSHCD_ENABLE_INTRS (UTP_TRANSFER_REQ_COMPL |\
@@ -4802,8 +4805,9 @@
int ret = 0;
/* if already configured to the requested pwr_mode */
- if (pwr_mode->gear_rx == hba->pwr_info.gear_rx &&
- pwr_mode->gear_tx == hba->pwr_info.gear_tx &&
+ if (!hba->restore_needed &&
+ pwr_mode->gear_rx == hba->pwr_info.gear_rx &&
+ pwr_mode->gear_tx == hba->pwr_info.gear_tx &&
pwr_mode->lane_rx == hba->pwr_info.lane_rx &&
pwr_mode->lane_tx == hba->pwr_info.lane_tx &&
pwr_mode->pwr_rx == hba->pwr_info.pwr_rx &&
@@ -6471,6 +6475,52 @@
reg_hist->pos = (reg_hist->pos + 1) % UIC_ERR_REG_HIST_LENGTH;
}
+static void ufshcd_rls_handler(struct work_struct *work)
+{
+ struct ufs_hba *hba;
+ int ret = 0;
+ u32 mode;
+
+ hba = container_of(work, struct ufs_hba, rls_work);
+ ufshcd_scsi_block_requests(hba);
+ pm_runtime_get_sync(hba->dev);
+ ret = ufshcd_wait_for_doorbell_clr(hba, U64_MAX);
+ if (ret) {
+ dev_err(hba->dev,
+ "Timed out (%d) waiting for DB to clear\n",
+ ret);
+ goto out;
+ }
+
+ ufshcd_dme_get(hba, UIC_ARG_MIB(PA_PWRMODE), &mode);
+ if (hba->pwr_info.pwr_rx != ((mode >> PWR_RX_OFFSET) & PWR_INFO_MASK))
+ hba->restore_needed = true;
+
+ if (hba->pwr_info.pwr_tx != (mode & PWR_INFO_MASK))
+ hba->restore_needed = true;
+
+ ufshcd_dme_get(hba, UIC_ARG_MIB(PA_RXGEAR), &mode);
+ if (hba->pwr_info.gear_rx != mode)
+ hba->restore_needed = true;
+
+ ufshcd_dme_get(hba, UIC_ARG_MIB(PA_TXGEAR), &mode);
+ if (hba->pwr_info.gear_tx != mode)
+ hba->restore_needed = true;
+
+ if (hba->restore_needed)
+ ret = ufshcd_config_pwr_mode(hba, &(hba->pwr_info));
+
+ if (ret)
+ dev_err(hba->dev, "%s: Failed setting power mode, err = %d\n",
+ __func__, ret);
+ else
+ hba->restore_needed = false;
+
+out:
+ ufshcd_scsi_unblock_requests(hba);
+ pm_runtime_put_sync(hba->dev);
+}
+
/**
* ufshcd_update_uic_error - check and set fatal UIC error flags.
* @hba: per-adapter instance
@@ -6510,6 +6560,8 @@
hba->full_init_linereset = true;
}
}
+ if (!hba->full_init_linereset)
+ schedule_work(&hba->rls_work);
}
retval |= IRQ_HANDLED;
}
@@ -10450,6 +10502,7 @@
INIT_WORK(&hba->eh_work, ufshcd_err_handler);
INIT_WORK(&hba->eeh_work, ufshcd_exception_event_handler);
INIT_WORK(&hba->card_detect_work, ufshcd_card_detect_handler);
+ INIT_WORK(&hba->rls_work, ufshcd_rls_handler);
/* Initialize UIC command mutex */
mutex_init(&hba->uic_cmd_mutex);
diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
index 1b21238..1f5c404 100644
--- a/drivers/scsi/ufs/ufshcd.h
+++ b/drivers/scsi/ufs/ufshcd.h
@@ -873,6 +873,7 @@
/* Work Queues */
struct work_struct eh_work;
struct work_struct eeh_work;
+ struct work_struct rls_work;
/* HBA Errors */
u32 errors;
@@ -987,6 +988,7 @@
int latency_hist_enabled;
struct io_latency_state io_lat_s;
struct ufs_desc_size desc_size;
+ bool restore_needed;
};
static inline void ufshcd_mark_shutdown_ongoing(struct ufs_hba *hba)
diff --git a/drivers/soc/qcom/llcc-sdm670.c b/drivers/soc/qcom/llcc-sdm670.c
index 68ad755..494b93b 100644
--- a/drivers/soc/qcom/llcc-sdm670.c
+++ b/drivers/soc/qcom/llcc-sdm670.c
@@ -57,13 +57,14 @@
}
static struct llcc_slice_config sdm670_data[] = {
- SCT_ENTRY("cpuss", 1, 1, 512, 1, 1, 0xF, 0x0, 0, 0, 0, 1, 1),
- SCT_ENTRY("vidsc0", 2, 2, 64, 2, 1, 0xF, 0x0, 0, 0, 0, 1, 0),
- SCT_ENTRY("vidsc1", 3, 3, 64, 2, 1, 0xF, 0x0, 0, 0, 0, 1, 0),
- SCT_ENTRY("rotator", 4, 4, 384, 2, 1, 0xF, 0x0, 0, 0, 0, 1, 0),
- SCT_ENTRY("modem", 8, 8, 512, 1, 0, 0xF, 0x0, 0, 0, 0, 1, 0),
- SCT_ENTRY("gpuhtw", 11, 11, 128, 1, 1, 0xF, 0x0, 0, 0, 0, 1, 0),
- SCT_ENTRY("gpu", 12, 12, 384, 1, 1, 0xF, 0x0, 0, 0, 0, 1, 0),
+ SCT_ENTRY("cpuss", 1, 1, 512, 1, 0, 0xF, 0x0, 0, 0, 1, 1, 1),
+ SCT_ENTRY("rotator", 4, 4, 384, 2, 1, 0x0, 0xE, 2, 0, 1, 1, 0),
+ SCT_ENTRY("voice", 5, 5, 512, 1, 0, 0xF, 0x0, 0, 0, 1, 1, 0),
+ SCT_ENTRY("audio", 6, 6, 512, 1, 0, 0xF, 0x0, 0, 0, 1, 1, 0),
+ SCT_ENTRY("modem", 8, 8, 512, 1, 0, 0xF, 0x0, 0, 0, 1, 1, 0),
+ SCT_ENTRY("gpu", 12, 12, 384, 1, 1, 0x0, 0x0, 0, 0, 1, 1, 0),
+ SCT_ENTRY("mmuhwt", 13, 13, 512, 1, 0, 0x0, 0x8, 0, 0, 1, 0, 1),
+ SCT_ENTRY("audiohw", 22, 22, 512, 1, 1, 0xF, 0x0, 0, 0, 1, 1, 0),
};
static int sdm670_qcom_llcc_probe(struct platform_device *pdev)
diff --git a/drivers/soc/qcom/msm_bus/msm_bus_arb_rpmh.c b/drivers/soc/qcom/msm_bus/msm_bus_arb_rpmh.c
index a40efcb..437984c 100644
--- a/drivers/soc/qcom/msm_bus/msm_bus_arb_rpmh.c
+++ b/drivers/soc/qcom/msm_bus/msm_bus_arb_rpmh.c
@@ -1294,7 +1294,7 @@
src = pdata->usecase->vectors[i].src;
dest = pdata->usecase->vectors[i].dst;
- if ((src < 0) || (dest < 0)) {
+ if ((src < 0) || (dest < 0) || (src == dest)) {
MSM_BUS_ERR("%s:Invalid src/dst.src %d dest %d",
__func__, src, dest);
goto exit_invalid_data;
diff --git a/drivers/soc/qcom/pil-msa.c b/drivers/soc/qcom/pil-msa.c
index 6f8e8b2..a3eb551 100644
--- a/drivers/soc/qcom/pil-msa.c
+++ b/drivers/soc/qcom/pil-msa.c
@@ -469,6 +469,13 @@
ret);
goto out;
}
+ ret = regulator_enable(drv->vreg);
+ if (ret) {
+ dev_err(pil->dev, "Failed to enable vreg(rc:%d)\n",
+ ret);
+ regulator_set_voltage(drv->vreg, 0, INT_MAX);
+ goto out;
+ }
}
ret = pil_q6v5_make_proxy_votes(pil);
diff --git a/drivers/soc/qcom/watchdog_v2.c b/drivers/soc/qcom/watchdog_v2.c
index 8bf5659..9aea6db 100644
--- a/drivers/soc/qcom/watchdog_v2.c
+++ b/drivers/soc/qcom/watchdog_v2.c
@@ -50,7 +50,7 @@
#define SCM_SET_REGSAVE_CMD 0x2
#define SCM_SVC_SEC_WDOG_DIS 0x7
#define MAX_CPU_CTX_SIZE 2048
-#define MAX_CPU_SCANDUMP_SIZE 0x10000
+#define MAX_CPU_SCANDUMP_SIZE 0x10100
static struct msm_watchdog_data *wdog_data;
diff --git a/drivers/spi/spi-geni-qcom.c b/drivers/spi/spi-geni-qcom.c
index 8dc42ac..7aaf08b 100644
--- a/drivers/spi/spi-geni-qcom.c
+++ b/drivers/spi/spi-geni-qcom.c
@@ -716,7 +716,7 @@
if (mas->cur_xfer_mode == FIFO_MODE) {
geni_se_select_mode(mas->base, FIFO_MODE);
reinit_completion(&mas->xfer_done);
- setup_fifo_params(spi_msg->spi, spi);
+ ret = setup_fifo_params(spi_msg->spi, spi);
} else if (mas->cur_xfer_mode == GSI_DMA) {
mas->num_tx_eot = 0;
mas->num_rx_eot = 0;
@@ -1199,6 +1199,7 @@
struct resource *res;
struct platform_device *wrapper_pdev;
struct device_node *wrapper_ph_node;
+ bool rt_pri;
spi = spi_alloc_master(&pdev->dev, sizeof(struct spi_geni_master));
if (!spi) {
@@ -1293,6 +1294,10 @@
goto spi_geni_probe_err;
}
+ rt_pri = of_property_read_bool(pdev->dev.of_node, "qcom,rt");
+ if (rt_pri)
+ spi->rt = true;
+
geni_mas->phys_addr = res->start;
geni_mas->size = resource_size(res);
geni_mas->base = devm_ioremap(&pdev->dev, res->start,
diff --git a/drivers/tty/serial/msm_geni_serial.c b/drivers/tty/serial/msm_geni_serial.c
index e7ed9f4..9c819fb 100644
--- a/drivers/tty/serial/msm_geni_serial.c
+++ b/drivers/tty/serial/msm_geni_serial.c
@@ -117,7 +117,7 @@
#define WAIT_XFER_MAX_TIMEOUT_US (10000)
#define WAIT_XFER_MIN_TIMEOUT_US (9000)
#define IPC_LOG_PWR_PAGES (6)
-#define IPC_LOG_MISC_PAGES (6)
+#define IPC_LOG_MISC_PAGES (10)
#define IPC_LOG_TX_RX_PAGES (8)
#define DATA_BYTES_PER_LINE (32)
@@ -242,26 +242,40 @@
(unsigned int)addr, size, buf);
}
+static bool device_pending_suspend(struct uart_port *uport)
+{
+ int usage_count = atomic_read(&uport->dev->power.usage_count);
+
+ return (pm_runtime_suspended(uport->dev) || !usage_count);
+}
+
static bool check_transfers_inflight(struct uart_port *uport)
{
bool xfer_on = false;
bool tx_active = false;
- bool tx_empty = false;
+ bool tx_fifo_status = false;
bool m_cmd_active = false;
bool rx_active = false;
u32 rx_fifo_status = 0;
+ struct msm_geni_serial_port *port = GET_DEV_PORT(uport);
u32 geni_status = geni_read_reg_nolog(uport->membase,
SE_GENI_STATUS);
+ struct circ_buf *xmit = &uport->state->xmit;
+
/* Possible stop tx is called multiple times. */
m_cmd_active = geni_status & M_GENI_CMD_ACTIVE;
- tx_empty = msm_geni_serial_tx_empty(uport);
- tx_active = m_cmd_active || !tx_empty;
+ if (port->xfer_mode == SE_DMA)
+ tx_fifo_status = port->tx_dma ? 1 : 0;
+ else
+ tx_fifo_status = geni_read_reg_nolog(uport->membase,
+ SE_GENI_TX_FIFO_STATUS);
+ tx_active = m_cmd_active || tx_fifo_status;
rx_fifo_status = geni_read_reg_nolog(uport->membase,
SE_GENI_RX_FIFO_STATUS);
if (rx_fifo_status)
rx_active = true;
- if (rx_active || tx_active)
+ if (rx_active || tx_active || !uart_circ_empty(xmit))
xfer_on = true;
return xfer_on;
@@ -330,6 +344,7 @@
__func__, port->ioctl_count);
return -EPERM;
}
+ wait_for_transfers_inflight(uport);
port->ioctl_count--;
msm_geni_serial_power_off(uport);
IPC_LOG_MSG(port->ipc_log_pwr, "%s%s ioctl %d\n", __func__,
@@ -363,8 +378,13 @@
static void msm_geni_serial_break_ctl(struct uart_port *uport, int ctl)
{
- if (!uart_console(uport) && pm_runtime_status_suspended(uport->dev))
+ struct msm_geni_serial_port *port = GET_DEV_PORT(uport);
+
+ if (!uart_console(uport) && device_pending_suspend(uport)) {
+ IPC_LOG_MSG(port->ipc_log_misc,
+ "%s.Device is suspended.\n", __func__);
return;
+ }
if (ctl) {
wait_for_transfers_inflight(uport);
@@ -385,9 +405,13 @@
{
u32 geni_ios = 0;
unsigned int mctrl = TIOCM_DSR | TIOCM_CAR;
+ struct msm_geni_serial_port *port = GET_DEV_PORT(uport);
- if (pm_runtime_status_suspended(uport->dev))
+ if (device_pending_suspend(uport)) {
+ IPC_LOG_MSG(port->ipc_log_misc,
+ "%s.Device is suspended.\n", __func__);
return TIOCM_DSR | TIOCM_CAR | TIOCM_CTS;
+ }
geni_ios = geni_read_reg_nolog(uport->membase, SE_GENI_IOS);
if (!(geni_ios & IO2_DATA_IN))
@@ -405,9 +429,13 @@
unsigned int mctrl)
{
u32 uart_manual_rfr = 0;
+ struct msm_geni_serial_port *port = GET_DEV_PORT(uport);
- if (pm_runtime_status_suspended(uport->dev))
+ if (device_pending_suspend(uport)) {
+ IPC_LOG_MSG(port->ipc_log_misc,
+ "%s.Device is suspended.\n", __func__);
return;
+ }
if (!(mctrl & TIOCM_RTS))
uart_manual_rfr |= (UART_MANUAL_RFR_EN | UART_RFR_NOT_READY);
geni_write_reg_nolog(uart_manual_rfr, uport->membase,
@@ -457,6 +485,14 @@
static void msm_geni_serial_power_off(struct uart_port *uport)
{
+ struct msm_geni_serial_port *port = GET_DEV_PORT(uport);
+ int usage_count = atomic_read(&uport->dev->power.usage_count);
+
+ if (!usage_count) {
+ IPC_LOG_MSG(port->ipc_log_pwr, "%s: Usage Count is already 0\n",
+ __func__);
+ return;
+ }
pm_runtime_mark_last_busy(uport->dev);
pm_runtime_put_autosuspend(uport->dev);
}
@@ -791,13 +827,16 @@
unsigned int geni_status;
unsigned int geni_ios;
- if (!uart_console(uport) && pm_runtime_status_suspended(uport->dev)) {
- dev_err(uport->dev, "%s.Device is suspended.\n", __func__);
+ if (!uart_console(uport) && !pm_runtime_active(uport->dev)) {
IPC_LOG_MSG(msm_port->ipc_log_misc,
- "%s.Device is suspended.\n", __func__);
- return;
+ "%s.Putting in async RPM vote\n", __func__);
+ pm_runtime_get(uport->dev);
+ goto exit_start_tx;
}
+ if (!uart_console(uport))
+ pm_runtime_get(uport->dev);
+
if (msm_port->xfer_mode == FIFO_MODE) {
geni_status = geni_read_reg_nolog(uport->membase,
SE_GENI_STATUS);
@@ -830,6 +869,9 @@
if (!(geni_ios & IO2_DATA_IN))
IPC_LOG_MSG(msm_port->ipc_log_misc, "%s: ios: 0x%08x\n",
__func__, geni_ios);
+exit_start_tx:
+ if (!uart_console(uport))
+ msm_geni_serial_power_off(uport);
}
static void msm_geni_serial_tx_fsm_rst(struct uart_port *uport)
@@ -857,7 +899,7 @@
unsigned int geni_status;
struct msm_geni_serial_port *port = GET_DEV_PORT(uport);
- if (!uart_console(uport) && pm_runtime_status_suspended(uport->dev)) {
+ if (!uart_console(uport) && device_pending_suspend(uport)) {
dev_err(uport->dev, "%s.Device is suspended.\n", __func__);
IPC_LOG_MSG(port->ipc_log_misc,
"%s.Device is suspended.\n", __func__);
@@ -909,7 +951,7 @@
struct msm_geni_serial_port *port = GET_DEV_PORT(uport);
int ret;
- if (!uart_console(uport) && pm_runtime_status_suspended(uport->dev)) {
+ if (!uart_console(uport) && device_pending_suspend(uport)) {
dev_err(uport->dev, "%s.Device is suspended.\n", __func__);
IPC_LOG_MSG(port->ipc_log_misc,
"%s.Device is suspended.\n", __func__);
@@ -942,7 +984,7 @@
dev_err(uport->dev, "%s: RX Prep dma failed %d\n",
__func__, ret);
msm_geni_serial_stop_rx(uport);
- return;
+ goto exit_geni_serial_start_rx;
}
}
/*
@@ -951,6 +993,7 @@
*/
mb();
geni_status = geni_read_reg_nolog(uport->membase, SE_GENI_STATUS);
+exit_geni_serial_start_rx:
IPC_LOG_MSG(port->ipc_log_misc, "%s 0x%x\n", __func__, geni_status);
}
@@ -981,8 +1024,7 @@
struct msm_geni_serial_port *port = GET_DEV_PORT(uport);
u32 irq_clear = S_CMD_DONE_EN;
- if (!uart_console(uport) && pm_runtime_status_suspended(uport->dev)) {
- dev_err(uport->dev, "%s.Device is suspended.\n", __func__);
+ if (!uart_console(uport) && device_pending_suspend(uport)) {
IPC_LOG_MSG(port->ipc_log_misc,
"%s.Device is suspended.\n", __func__);
return;
@@ -1110,6 +1152,15 @@
tx_fifo_status = geni_read_reg_nolog(uport->membase,
SE_GENI_TX_FIFO_STATUS);
if (uart_circ_empty(xmit) && !tx_fifo_status) {
+ /*
+ * This will balance out the power vote put in during start_tx
+ * allowing the device to suspend.
+ */
+ if (!uart_console(uport)) {
+ IPC_LOG_MSG(msm_port->ipc_log_misc,
+ "%s.Power Off.\n", __func__);
+ msm_geni_serial_power_off(uport);
+ }
msm_geni_serial_stop_tx(uport);
goto exit_handle_tx;
}
@@ -1166,8 +1217,7 @@
msm_port->xmit_size = xmit_size;
}
exit_handle_tx:
- if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
- uart_write_wakeup(uport);
+ uart_write_wakeup(uport);
return ret;
}
@@ -1234,8 +1284,18 @@
if (!uart_circ_empty(xmit))
msm_geni_serial_prep_dma_tx(uport);
- else
+ else {
+ /*
+ * This will balance out the power vote put in during start_tx
+ * allowing the device to suspend.
+ */
+ if (!uart_console(uport)) {
+ IPC_LOG_MSG(msm_port->ipc_log_misc,
+ "%s.Power Off.\n", __func__);
+ msm_geni_serial_power_off(uport);
+ }
uart_write_wakeup(uport);
+ }
return 0;
}
@@ -1255,7 +1315,7 @@
spin_lock_irqsave(&uport->lock, flags);
if (uart_console(uport) && uport->suspended)
goto exit_geni_serial_isr;
- if (!uart_console(uport) && pm_runtime_status_suspended(uport->dev)) {
+ if (!uart_console(uport) && pm_runtime_suspended(uport->dev)) {
dev_err(uport->dev, "%s.Device is suspended.\n", __func__);
IPC_LOG_MSG(msm_port->ipc_log_misc,
"%s.Device is suspended.\n", __func__);
@@ -1525,47 +1585,6 @@
* framework.
*/
mb();
- if (!uart_console(uport)) {
- char name[30];
-
- memset(name, 0, sizeof(name));
- if (!msm_port->ipc_log_rx) {
- scnprintf(name, sizeof(name), "%s%s",
- dev_name(uport->dev), "_rx");
- msm_port->ipc_log_rx = ipc_log_context_create(
- IPC_LOG_TX_RX_PAGES, name, 0);
- if (!msm_port->ipc_log_rx)
- dev_info(uport->dev, "Err in Rx IPC Log\n");
- }
- memset(name, 0, sizeof(name));
- if (!msm_port->ipc_log_tx) {
- scnprintf(name, sizeof(name), "%s%s",
- dev_name(uport->dev), "_tx");
- msm_port->ipc_log_tx = ipc_log_context_create(
- IPC_LOG_TX_RX_PAGES, name, 0);
- if (!msm_port->ipc_log_tx)
- dev_info(uport->dev, "Err in Tx IPC Log\n");
- }
- memset(name, 0, sizeof(name));
- if (!msm_port->ipc_log_pwr) {
- scnprintf(name, sizeof(name), "%s%s",
- dev_name(uport->dev), "_pwr");
- msm_port->ipc_log_pwr = ipc_log_context_create(
- IPC_LOG_PWR_PAGES, name, 0);
- if (!msm_port->ipc_log_pwr)
- dev_info(uport->dev, "Err in Pwr IPC Log\n");
- }
- memset(name, 0, sizeof(name));
- if (!msm_port->ipc_log_misc) {
- scnprintf(name, sizeof(name), "%s%s",
- dev_name(uport->dev), "_misc");
- msm_port->ipc_log_misc = ipc_log_context_create(
- IPC_LOG_MISC_PAGES, name, 0);
- if (!msm_port->ipc_log_misc)
- dev_info(uport->dev, "Err in Misc IPC Log\n");
- }
-
- }
exit_portsetup:
return ret;
}
@@ -1832,10 +1851,10 @@
unsigned int is_tx_empty = 1;
struct msm_geni_serial_port *port = GET_DEV_PORT(uport);
- if (!uart_console(uport) && pm_runtime_status_suspended(uport->dev)) {
+ if (!uart_console(uport) && device_pending_suspend(uport)) {
IPC_LOG_MSG(port->ipc_log_pwr,
"%s Device suspended,vote clocks on.\n", __func__);
- return 1;
+ return 0;
}
if (port->xfer_mode == SE_DMA)
@@ -2091,13 +2110,54 @@
}
#endif /* defined(CONFIG_SERIAL_CORE_CONSOLE) || defined(CONFIG_CONSOLE_POLL) */
-static void msm_geni_serial_debug_init(struct uart_port *uport)
+static void msm_geni_serial_debug_init(struct uart_port *uport, bool console)
{
struct msm_geni_serial_port *msm_port = GET_DEV_PORT(uport);
msm_port->dbg = debugfs_create_dir(dev_name(uport->dev), NULL);
if (IS_ERR_OR_NULL(msm_port->dbg))
dev_err(uport->dev, "Failed to create dbg dir\n");
+
+ if (!console) {
+ char name[30];
+
+ memset(name, 0, sizeof(name));
+ if (!msm_port->ipc_log_rx) {
+ scnprintf(name, sizeof(name), "%s%s",
+ dev_name(uport->dev), "_rx");
+ msm_port->ipc_log_rx = ipc_log_context_create(
+ IPC_LOG_TX_RX_PAGES, name, 0);
+ if (!msm_port->ipc_log_rx)
+ dev_info(uport->dev, "Err in Rx IPC Log\n");
+ }
+ memset(name, 0, sizeof(name));
+ if (!msm_port->ipc_log_tx) {
+ scnprintf(name, sizeof(name), "%s%s",
+ dev_name(uport->dev), "_tx");
+ msm_port->ipc_log_tx = ipc_log_context_create(
+ IPC_LOG_TX_RX_PAGES, name, 0);
+ if (!msm_port->ipc_log_tx)
+ dev_info(uport->dev, "Err in Tx IPC Log\n");
+ }
+ memset(name, 0, sizeof(name));
+ if (!msm_port->ipc_log_pwr) {
+ scnprintf(name, sizeof(name), "%s%s",
+ dev_name(uport->dev), "_pwr");
+ msm_port->ipc_log_pwr = ipc_log_context_create(
+ IPC_LOG_PWR_PAGES, name, 0);
+ if (!msm_port->ipc_log_pwr)
+ dev_info(uport->dev, "Err in Pwr IPC Log\n");
+ }
+ memset(name, 0, sizeof(name));
+ if (!msm_port->ipc_log_misc) {
+ scnprintf(name, sizeof(name), "%s%s",
+ dev_name(uport->dev), "_misc");
+ msm_port->ipc_log_misc = ipc_log_context_create(
+ IPC_LOG_MISC_PAGES, name, 0);
+ if (!msm_port->ipc_log_misc)
+ dev_info(uport->dev, "Err in Misc IPC Log\n");
+ }
+ }
}
static void msm_geni_serial_cons_pm(struct uart_port *uport,
@@ -2341,7 +2401,7 @@
line, uport->fifosize, is_console);
device_create_file(uport->dev, &dev_attr_loopback);
device_create_file(uport->dev, &dev_attr_xfer_mode);
- msm_geni_serial_debug_init(uport);
+ msm_geni_serial_debug_init(uport, is_console);
dev_port->port_setup = false;
return uart_add_one_port(drv, uport);
@@ -2369,12 +2429,12 @@
int ret = 0;
wait_for_transfers_inflight(&port->uport);
+ disable_irq(port->uport.irq);
ret = se_geni_resources_off(&port->serial_rsc);
if (ret) {
dev_err(dev, "%s: Error ret %d\n", __func__, ret);
goto exit_runtime_suspend;
}
- disable_irq(port->uport.irq);
if (port->wakeup_irq > 0) {
struct se_geni_rsc *rsc = &port->serial_rsc;
diff --git a/drivers/usb/gadget/function/f_gsi.c b/drivers/usb/gadget/function/f_gsi.c
index 76e0a32..a26d6df 100644
--- a/drivers/usb/gadget/function/f_gsi.c
+++ b/drivers/usb/gadget/function/f_gsi.c
@@ -2766,8 +2766,12 @@
f->name,
gadget_is_superspeed(c->cdev->gadget) ? "super" :
gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full",
- gsi->d_port.in_ep->name, gsi->d_port.out_ep->name,
- gsi->c_port.notify->name);
+ (gsi->d_port.in_ep == NULL ? "NULL" :
+ gsi->d_port.in_ep->name),
+ (gsi->d_port.out_ep == NULL ? "NULL" :
+ gsi->d_port.out_ep->name),
+ (gsi->c_port.notify == NULL ? "NULL" :
+ gsi->c_port.notify->name));
return 0;
dereg_rndis:
diff --git a/drivers/usb/phy/phy-msm-qusb-v2.c b/drivers/usb/phy/phy-msm-qusb-v2.c
index 68bd576..7ac7f1e 100644
--- a/drivers/usb/phy/phy-msm-qusb-v2.c
+++ b/drivers/usb/phy/phy-msm-qusb-v2.c
@@ -1049,6 +1049,21 @@
if (ret)
return ret;
+ /* ldo24 is turned on and eud is pet irrespective of cable
+ * cable connection status by boot sw. Assume usb cable is not
+ * connected and perform detach pet. If usb cable is connected,
+ * eud hw will be pet in the dpdm callback.
+ */
+ if (qphy->eud_base) {
+ if (qphy->cfg_ahb_clk)
+ clk_prepare_enable(qphy->cfg_ahb_clk);
+
+ writel_relaxed(0, qphy->eud_base + EUD_SW_ATTACH_DET);
+
+ if (qphy->cfg_ahb_clk)
+ clk_disable_unprepare(qphy->cfg_ahb_clk);
+ }
+
ret = qusb_phy_regulator_init(qphy);
if (ret)
usb_remove_phy(&qphy->phy);
diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h
index 6be0299..7a2ae2f 100644
--- a/include/linux/cpuhotplug.h
+++ b/include/linux/cpuhotplug.h
@@ -128,6 +128,7 @@
CPUHP_AP_WORKQUEUE_ONLINE,
CPUHP_AP_RCUTREE_ONLINE,
CPUHP_AP_NOTIFY_ONLINE,
+ CPUHP_AP_NOTIFY_PERF_ONLINE,
CPUHP_AP_ONLINE_DYN,
CPUHP_AP_ONLINE_DYN_END = CPUHP_AP_ONLINE_DYN + 30,
CPUHP_AP_X86_HPET_ONLINE,
diff --git a/include/linux/if_bridge.h b/include/linux/if_bridge.h
index c6587c0..6638a22 100644
--- a/include/linux/if_bridge.h
+++ b/include/linux/if_bridge.h
@@ -53,6 +53,8 @@
typedef int br_should_route_hook_t(struct sk_buff *skb);
extern br_should_route_hook_t __rcu *br_should_route_hook;
+extern struct net_device *br_port_dev_get(struct net_device *dev,
+ unsigned char *addr);
#if IS_ENABLED(CONFIG_BRIDGE) && IS_ENABLED(CONFIG_BRIDGE_IGMP_SNOOPING)
int br_multicast_list_adjacent(struct net_device *dev,
diff --git a/include/net/netfilter/nf_conntrack.h b/include/net/netfilter/nf_conntrack.h
index d9d52c0..7815545 100644
--- a/include/net/netfilter/nf_conntrack.h
+++ b/include/net/netfilter/nf_conntrack.h
@@ -314,6 +314,7 @@
extern unsigned int nf_conntrack_htable_size;
extern seqcount_t nf_conntrack_generation;
extern unsigned int nf_conntrack_max;
+extern unsigned int nf_conntrack_pkt_threshold;
/* must be called with rcu read lock held */
static inline void
diff --git a/include/trace/events/cpuhp.h b/include/trace/events/cpuhp.h
index 996953d..7f4eba4 100644
--- a/include/trace/events/cpuhp.h
+++ b/include/trace/events/cpuhp.h
@@ -88,6 +88,34 @@
__entry->cpu, __entry->state, __entry->idx, __entry->ret)
);
+TRACE_EVENT(cpuhp_latency,
+
+ TP_PROTO(unsigned int cpu, unsigned int state,
+ u64 start_time, int ret),
+
+ TP_ARGS(cpu, state, start_time, ret),
+
+ TP_STRUCT__entry(
+ __field(unsigned int, cpu)
+ __field(unsigned int, state)
+ __field(u64, time)
+ __field(int, ret)
+ ),
+
+ TP_fast_assign(
+ __entry->cpu = cpu;
+ __entry->state = state;
+ __entry->time = div64_u64(sched_clock() - start_time, 1000);
+ __entry->ret = ret;
+ ),
+
+ TP_printk(" cpu:%d state:%s latency:%llu USEC ret: %d",
+ __entry->cpu, __entry->state ? "online" : "offline",
+ __entry->time, __entry->ret)
+);
+
+
+
#endif
/* This part must be outside protection */
diff --git a/include/uapi/linux/netfilter/nf_conntrack_common.h b/include/uapi/linux/netfilter/nf_conntrack_common.h
index 6d074d1..1d7cd67 100644
--- a/include/uapi/linux/netfilter/nf_conntrack_common.h
+++ b/include/uapi/linux/netfilter/nf_conntrack_common.h
@@ -113,8 +113,11 @@
IPCT_NATSEQADJ = IPCT_SEQADJ,
IPCT_SECMARK, /* new security mark has been set */
IPCT_LABEL, /* new connlabel has been set */
+ IPCT_COUNTER, /* Packet counters have matched. */
};
+#define IPCT_COUNTER IPCT_COUNTER
+
enum ip_conntrack_expect_events {
IPEXP_NEW, /* new expectation */
IPEXP_DESTROY, /* destroyed expectation */
diff --git a/kernel/cpu.c b/kernel/cpu.c
index d2df1ce..0d10ef5 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -898,6 +898,7 @@
struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, cpu);
int prev_state, ret = 0;
bool hasdied = false;
+ u64 start_time = 0;
if (num_online_cpus() == 1)
return -EBUSY;
@@ -909,6 +910,8 @@
return -EBUSY;
cpu_hotplug_begin();
+ if (trace_cpuhp_latency_enabled())
+ start_time = sched_clock();
cpuhp_tasks_frozen = tasks_frozen;
@@ -947,6 +950,7 @@
hasdied = prev_state != st->state && st->state == CPUHP_OFFLINE;
out:
+ trace_cpuhp_latency(cpu, 0, start_time, ret);
cpu_hotplug_done();
/* This post dead nonsense must die */
if (!ret && hasdied)
@@ -1020,8 +1024,11 @@
struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, cpu);
struct task_struct *idle;
int ret = 0;
+ u64 start_time = 0;
cpu_hotplug_begin();
+ if (trace_cpuhp_latency_enabled())
+ start_time = sched_clock();
if (!cpu_present(cpu)) {
ret = -EINVAL;
@@ -1069,6 +1076,7 @@
target = min((int)target, CPUHP_BRINGUP_CPU);
ret = cpuhp_up_callbacks(cpu, st, target);
out:
+ trace_cpuhp_latency(cpu, 1, start_time, ret);
cpu_hotplug_done();
return ret;
}
diff --git a/kernel/sched/cputime.c b/kernel/sched/cputime.c
index 0d8cc06..e4f48f1 100644
--- a/kernel/sched/cputime.c
+++ b/kernel/sched/cputime.c
@@ -71,12 +71,12 @@
else
account = false;
+ u64_stats_update_end(&irqtime->sync);
+
if (account)
sched_account_irqtime(cpu, curr, delta, wallclock);
else if (curr != this_cpu_ksoftirqd())
sched_account_irqstart(cpu, curr, wallclock);
-
- u64_stats_update_end(&irqtime->sync);
}
EXPORT_SYMBOL_GPL(irqtime_account_irq);
diff --git a/kernel/sched/walt.c b/kernel/sched/walt.c
index 316c276..f50add7 100644
--- a/kernel/sched/walt.c
+++ b/kernel/sched/walt.c
@@ -2833,14 +2833,11 @@
rcu_read_unlock();
}
- if (cpu_max_table_freq[cpu] &&
- unlikely(thermal_max_freq && thermal_max_freq
- != cpu_max_table_freq[cpu])) {
+ if (cpu_max_table_freq[cpu])
return div64_ul(thermal_max_freq * max_cap[cpu],
cpu_max_table_freq[cpu]);
- } else {
+ else
return rq->cpu_capacity_orig;
- }
}
static DEFINE_SPINLOCK(cpu_freq_min_max_lock);
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
index ed0dd33..9218931 100644
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -655,3 +655,34 @@
if (mask & BR_AUTO_MASK)
nbp_update_port_count(br);
}
+
+/* br_port_dev_get()
+ * Using the given addr, identify the port to which it is reachable,
+ * returing a reference to the net device associated with that port.
+ *
+ * NOTE: Return NULL if given dev is not a bridge or
+ * the mac has no associated port
+ */
+struct net_device *br_port_dev_get(struct net_device *dev, unsigned char *addr)
+{
+ struct net_bridge_fdb_entry *fdbe;
+ struct net_bridge *br;
+ struct net_device *netdev = NULL;
+
+ /* Is this a bridge? */
+ if (!(dev->priv_flags & IFF_EBRIDGE))
+ return NULL;
+
+ br = netdev_priv(dev);
+
+ /* Lookup the fdb entry and get reference to the port dev */
+ rcu_read_lock();
+ fdbe = __br_fdb_get(br, addr, 0);
+ if (fdbe && fdbe->dst) {
+ netdev = fdbe->dst->dev; /* port device */
+ dev_hold(netdev);
+ }
+ rcu_read_unlock();
+ return netdev;
+}
+EXPORT_SYMBOL(br_port_dev_get);
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index ff2d32e..d5b49fc 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -181,6 +181,9 @@
unsigned int nf_conntrack_max __read_mostly;
seqcount_t nf_conntrack_generation __read_mostly;
+unsigned int nf_conntrack_pkt_threshold __read_mostly;
+EXPORT_SYMBOL(nf_conntrack_pkt_threshold);
+
DEFINE_PER_CPU(struct nf_conn, nf_conntrack_untracked);
EXPORT_PER_CPU_SYMBOL(nf_conntrack_untracked);
@@ -1434,6 +1437,9 @@
unsigned long extra_jiffies,
int do_acct)
{
+ struct nf_conn_acct *acct;
+ u64 pkts;
+
NF_CT_ASSERT(skb);
/* Only update if this is not a fixed timeout */
@@ -1446,8 +1452,27 @@
ct->timeout = extra_jiffies;
acct:
- if (do_acct)
- nf_ct_acct_update(ct, ctinfo, skb->len);
+ if (do_acct) {
+ acct = nf_conn_acct_find(ct);
+ if (acct) {
+ struct nf_conn_counter *counter = acct->counter;
+
+ atomic64_inc(&counter[CTINFO2DIR(ctinfo)].packets);
+ atomic64_add(skb->len, &counter
+ [CTINFO2DIR(ctinfo)].bytes);
+
+ pkts =
+ atomic64_read(&counter[CTINFO2DIR(ctinfo)].packets) +
+ atomic64_read(&counter[!CTINFO2DIR(ctinfo)].packets);
+ /* Report if the packet threshold is reached. */
+ if ((nf_conntrack_pkt_threshold > 0) &&
+ (pkts == nf_conntrack_pkt_threshold)) {
+ nf_conntrack_event_cache(IPCT_COUNTER, ct);
+ nf_conntrack_event_cache(IPCT_PROTOINFO, ct);
+ nf_ct_deliver_cached_events(ct);
+ }
+ }
+ }
}
EXPORT_SYMBOL_GPL(__nf_ct_refresh_acct);
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index 04111c1..08b24a9 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -729,6 +729,10 @@
if (events & (1 << IPCT_SEQADJ) &&
ctnetlink_dump_ct_seq_adj(skb, ct) < 0)
goto nla_put_failure;
+
+ if (events & (1 << IPCT_COUNTER) &&
+ ctnetlink_dump_acct(skb, ct, 0) < 0)
+ goto nla_put_failure;
}
#ifdef CONFIG_NF_CONNTRACK_MARK
diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c
index 5f446cd..2f1014e 100644
--- a/net/netfilter/nf_conntrack_standalone.c
+++ b/net/netfilter/nf_conntrack_standalone.c
@@ -517,6 +517,14 @@
.mode = 0644,
.proc_handler = proc_dointvec,
},
+ {
+ .procname = "nf_conntrack_pkt_threshold",
+ .data = &nf_conntrack_pkt_threshold,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = proc_dointvec,
+ },
+
{ }
};
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index adf7d03..3dd7b21 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -560,6 +560,14 @@
[NL80211_NAN_SRF_MAC_ADDRS] = { .type = NLA_NESTED },
};
+/* policy for packet pattern attributes */
+static const struct nla_policy
+nl80211_packet_pattern_policy[MAX_NL80211_PKTPAT + 1] = {
+ [NL80211_PKTPAT_MASK] = { .type = NLA_BINARY, },
+ [NL80211_PKTPAT_PATTERN] = { .type = NLA_BINARY, },
+ [NL80211_PKTPAT_OFFSET] = { .type = NLA_U32 },
+};
+
static int nl80211_prepare_wdev_dump(struct sk_buff *skb,
struct netlink_callback *cb,
struct cfg80211_registered_device **rdev,
@@ -10233,7 +10241,7 @@
u8 *mask_pat;
nla_parse(pat_tb, MAX_NL80211_PKTPAT, nla_data(pat),
- nla_len(pat), NULL);
+ nla_len(pat), nl80211_packet_pattern_policy);
err = -EINVAL;
if (!pat_tb[NL80211_PKTPAT_MASK] ||
!pat_tb[NL80211_PKTPAT_PATTERN])
@@ -10483,7 +10491,7 @@
u8 *mask_pat;
nla_parse(pat_tb, MAX_NL80211_PKTPAT, nla_data(pat),
- nla_len(pat), NULL);
+ nla_len(pat), nl80211_packet_pattern_policy);
if (!pat_tb[NL80211_PKTPAT_MASK] ||
!pat_tb[NL80211_PKTPAT_PATTERN])
return -EINVAL;