Merge "PM / devfreq: memlat: Don't ignore extremely latency sensitive workloads"
diff --git a/Documentation/devicetree/bindings/power/supply/qcom/smb138x-charger.txt b/Documentation/devicetree/bindings/power/supply/qcom/smb138x-charger.txt
index 92ef23c..fd2729f 100644
--- a/Documentation/devicetree/bindings/power/supply/qcom/smb138x-charger.txt
+++ b/Documentation/devicetree/bindings/power/supply/qcom/smb138x-charger.txt
@@ -43,6 +43,13 @@
Definition: Boolean flag which indicates that the charger should not draw
current from any of its input sources (USB, DC).
+- qcom,use-extcon
+ Usage: optional
+ Value type: <empty>
+ Definition: Boolean flag which specify that smb138x will act as main charger
+ to do extcon USB calls. If not defined, other charger driver can
+ act as main charger to do extcon USB calls.
+
- qcom,fcc-max-ua
Usage: optional
Value type: <u32>
diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile
index 041b304..f2cf941 100644
--- a/arch/arm64/boot/dts/qcom/Makefile
+++ b/arch/arm64/boot/dts/qcom/Makefile
@@ -69,15 +69,21 @@
dtbo-$(CONFIG_ARCH_SDM670) += \
sdm670-cdp-overlay.dtbo \
sdm670-mtp-overlay.dtbo \
- sdm670-rumi-overlay.dtbo
+ sdm670-rumi-overlay.dtbo \
+ sdm670-pm660a-cdp-overlay.dtbo \
+ sdm670-pm660a-mtp-overlay.dtbo
sdm670-cdp-overlay.dtbo-base := sdm670.dtb
sdm670-mtp-overlay.dtbo-base := sdm670.dtb
sdm670-rumi-overlay.dtbo-base := sdm670.dtb
+sdm670-pm660a-cdp-overlay.dtbo-base := sdm670.dtb
+sdm670-pm660a-mtp-overlay.dtbo-base := sdm670.dtb
else
dtb-$(CONFIG_ARCH_SDM670) += sdm670-rumi.dtb \
sdm670-mtp.dtb \
- sdm670-cdp.dtb
+ sdm670-cdp.dtb \
+ sdm670-pm660a-mtp.dtb \
+ sdm670-pm660a-cdp.dtb
endif
always := $(dtb-y)
diff --git a/arch/arm64/boot/dts/qcom/pm660.dtsi b/arch/arm64/boot/dts/qcom/pm660.dtsi
index 8075b9e..48d68a7 100644
--- a/arch/arm64/boot/dts/qcom/pm660.dtsi
+++ b/arch/arm64/boot/dts/qcom/pm660.dtsi
@@ -14,7 +14,7 @@
#include <dt-bindings/interrupt-controller/irq.h>
&spmi_bus {
- qcom,pm660@0 {
+ pm660_0: qcom,pm660@0 {
compatible ="qcom,spmi-pmic";
reg = <0x0 SPMI_USID>;
#address-cells = <2>;
@@ -245,149 +245,10 @@
};
};
- pm660_charger: qcom,qpnp-smb2 {
- compatible = "qcom,qpnp-smb2";
- #address-cells = <1>;
- #size-cells = <1>;
-
- qcom,pmic-revid = <&pm660_revid>;
-
- io-channels = <&pm660_rradc 8>,
- <&pm660_rradc 10>,
- <&pm660_rradc 3>,
- <&pm660_rradc 4>;
- io-channel-names = "charger_temp",
- "charger_temp_max",
- "usbin_i",
- "usbin_v";
-
- qcom,wipower-max-uw = <5000000>;
-
- /* Enable after the qusb_phy0 device node is added */
- /* dpdm-supply = <&qusb_phy0>; */
-
- qcom,thermal-mitigation
- = <3000000 2500000 2000000 1500000
- 1000000 500000>;
-
- qcom,chgr@1000 {
- reg = <0x1000 0x100>;
- interrupts =
- <0x0 0x10 0x0 IRQ_TYPE_EDGE_RISING>,
- <0x0 0x10 0x1 IRQ_TYPE_EDGE_RISING>,
- <0x0 0x10 0x2 IRQ_TYPE_EDGE_RISING>,
- <0x0 0x10 0x3 IRQ_TYPE_EDGE_RISING>,
- <0x0 0x10 0x4 IRQ_TYPE_EDGE_RISING>;
-
- interrupt-names = "chg-error",
- "chg-state-change",
- "step-chg-state-change",
- "step-chg-soc-update-fail",
- "step-chg-soc-update-request";
- };
-
- qcom,otg@1100 {
- reg = <0x1100 0x100>;
- interrupts = <0x0 0x11 0x0 IRQ_TYPE_EDGE_BOTH>,
- <0x0 0x11 0x1 IRQ_TYPE_EDGE_BOTH>,
- <0x0 0x11 0x2 IRQ_TYPE_EDGE_BOTH>,
- <0x0 0x11 0x3 IRQ_TYPE_EDGE_BOTH>;
-
- interrupt-names = "otg-fail",
- "otg-overcurrent",
- "otg-oc-dis-sw-sts",
- "testmode-change-detect";
- };
-
- qcom,bat-if@1200 {
- reg = <0x1200 0x100>;
- interrupts =
- <0x0 0x12 0x0 IRQ_TYPE_EDGE_RISING>,
- <0x0 0x12 0x1 IRQ_TYPE_EDGE_BOTH>,
- <0x0 0x12 0x2 IRQ_TYPE_EDGE_BOTH>,
- <0x0 0x12 0x3 IRQ_TYPE_EDGE_BOTH>,
- <0x0 0x12 0x4 IRQ_TYPE_EDGE_BOTH>,
- <0x0 0x12 0x5 IRQ_TYPE_EDGE_BOTH>;
-
- interrupt-names = "bat-temp",
- "bat-ocp",
- "bat-ov",
- "bat-low",
- "bat-therm-or-id-missing",
- "bat-terminal-missing";
- };
-
- qcom,usb-chgpth@1300 {
- reg = <0x1300 0x100>;
- interrupts =
- <0x0 0x13 0x0 IRQ_TYPE_EDGE_BOTH>,
- <0x0 0x13 0x1 IRQ_TYPE_EDGE_BOTH>,
- <0x0 0x13 0x2 IRQ_TYPE_EDGE_BOTH>,
- <0x0 0x13 0x3 IRQ_TYPE_EDGE_BOTH>,
- <0x0 0x13 0x4 IRQ_TYPE_EDGE_BOTH>,
- <0x0 0x13 0x5 IRQ_TYPE_EDGE_RISING>,
- <0x0 0x13 0x6 IRQ_TYPE_EDGE_RISING>,
- <0x0 0x13 0x7 IRQ_TYPE_EDGE_RISING>;
-
- interrupt-names = "usbin-collapse",
- "usbin-lt-3p6v",
- "usbin-uv",
- "usbin-ov",
- "usbin-plugin",
- "usbin-src-change",
- "usbin-icl-change",
- "type-c-change";
- };
-
- qcom,dc-chgpth@1400 {
- reg = <0x1400 0x100>;
- interrupts =
- <0x0 0x14 0x0 IRQ_TYPE_EDGE_BOTH>,
- <0x0 0x14 0x1 IRQ_TYPE_EDGE_BOTH>,
- <0x0 0x14 0x2 IRQ_TYPE_EDGE_BOTH>,
- <0x0 0x14 0x3 IRQ_TYPE_EDGE_BOTH>,
- <0x0 0x14 0x4 IRQ_TYPE_EDGE_BOTH>,
- <0x0 0x14 0x5 IRQ_TYPE_EDGE_BOTH>,
- <0x0 0x14 0x6 IRQ_TYPE_EDGE_RISING>;
-
- interrupt-names = "dcin-collapse",
- "dcin-lt-3p6v",
- "dcin-uv",
- "dcin-ov",
- "dcin-plugin",
- "div2-en-dg",
- "dcin-icl-change";
- };
-
- qcom,chgr-misc@1600 {
- reg = <0x1600 0x100>;
- interrupts =
- <0x0 0x16 0x0 IRQ_TYPE_EDGE_RISING>,
- <0x0 0x16 0x1 IRQ_TYPE_EDGE_RISING>,
- <0x0 0x16 0x2 IRQ_TYPE_EDGE_BOTH>,
- <0x0 0x16 0x3 IRQ_TYPE_EDGE_BOTH>,
- <0x0 0x16 0x4 IRQ_TYPE_EDGE_BOTH>,
- <0x0 0x16 0x5 IRQ_TYPE_EDGE_BOTH>,
- <0x0 0x16 0x6 IRQ_TYPE_EDGE_FALLING>,
- <0x0 0x16 0x7 IRQ_TYPE_EDGE_BOTH>;
-
- interrupt-names = "wdog-snarl",
- "wdog-bark",
- "aicl-fail",
- "aicl-done",
- "high-duty-cycle",
- "input-current-limiting",
- "temperature-change",
- "switcher-power-ok";
- };
- };
-
pm660_pdphy: qcom,usb-pdphy@1700 {
compatible = "qcom,qpnp-pdphy";
reg = <0x1700 0x100>;
vdd-pdphy-supply = <&pm660l_l7>;
- vbus-supply = <&smb2_vbus>;
- vconn-supply = <&smb2_vconn>;
interrupts = <0x0 0x17 0x0 IRQ_TYPE_EDGE_RISING>,
<0x0 0x17 0x1 IRQ_TYPE_EDGE_RISING>,
<0x0 0x17 0x2 IRQ_TYPE_EDGE_RISING>,
@@ -497,73 +358,6 @@
qcom,pmic-revid = <&pm660_revid>;
};
- pm660_fg: qpnp,fg {
- compatible = "qcom,fg-gen3";
- #address-cells = <1>;
- #size-cells = <1>;
- qcom,pmic-revid = <&pm660_revid>;
- io-channels = <&pm660_rradc 0>,
- <&pm660_rradc 7>;
- io-channel-names = "rradc_batt_id",
- "rradc_die_temp";
- qcom,rradc-base = <0x4500>;
- qcom,fg-esr-timer-awake = <96 96>;
- qcom,fg-esr-timer-asleep = <256 256>;
- qcom,fg-esr-timer-charging = <0 96>;
- qcom,cycle-counter-en;
- status = "okay";
-
- qcom,fg-batt-soc@4000 {
- status = "okay";
- reg = <0x4000 0x100>;
- interrupts = <0x0 0x40 0x0 IRQ_TYPE_EDGE_BOTH>,
- <0x0 0x40 0x1 IRQ_TYPE_EDGE_BOTH>,
- <0x0 0x40 0x2
- IRQ_TYPE_EDGE_RISING>,
- <0x0 0x40 0x3
- IRQ_TYPE_EDGE_RISING>,
- <0x0 0x40 0x4 IRQ_TYPE_EDGE_BOTH>,
- <0x0 0x40 0x5
- IRQ_TYPE_EDGE_RISING>,
- <0x0 0x40 0x6 IRQ_TYPE_EDGE_BOTH>,
- <0x0 0x40 0x7 IRQ_TYPE_EDGE_BOTH>;
- interrupt-names = "soc-update",
- "soc-ready",
- "bsoc-delta",
- "msoc-delta",
- "msoc-low",
- "msoc-empty",
- "msoc-high",
- "msoc-full";
- };
-
- qcom,fg-batt-info@4100 {
- status = "okay";
- reg = <0x4100 0x100>;
- interrupts = <0x0 0x41 0x0 IRQ_TYPE_EDGE_BOTH>,
- <0x0 0x41 0x1 IRQ_TYPE_EDGE_BOTH>,
- <0x0 0x41 0x2 IRQ_TYPE_EDGE_BOTH>,
- <0x0 0x41 0x3 IRQ_TYPE_EDGE_BOTH>,
- <0x0 0x41 0x6 IRQ_TYPE_EDGE_BOTH>;
- interrupt-names = "vbatt-pred-delta",
- "vbatt-low",
- "esr-delta",
- "batt-missing",
- "batt-temp-delta";
- };
-
- qcom,fg-memif@4400 {
- status = "okay";
- reg = <0x4400 0x100>;
- interrupts = <0x0 0x44 0x0 IRQ_TYPE_EDGE_BOTH>,
- <0x0 0x44 0x1 IRQ_TYPE_EDGE_BOTH>,
- <0x0 0x44 0x2 IRQ_TYPE_EDGE_BOTH>;
- interrupt-names = "ima-rdy",
- "mem-xcp",
- "dma-grant";
- };
- };
-
bcl@4200 {
compatible = "qcom,msm-bcl-lmh";
reg = <0x4200 0xff>,
@@ -579,32 +373,11 @@
};
};
- qcom,pm660@1 {
+ pm660_1: qcom,pm660@1 {
compatible ="qcom,spmi-pmic";
reg = <0x1 SPMI_USID>;
#address-cells = <2>;
#size-cells = <0>;
-
- pm660_haptics: qcom,haptics@c000 {
- compatible = "qcom,qpnp-haptics";
- reg = <0xc000 0x100>;
- interrupts = <0x1 0xc0 0x0 IRQ_TYPE_EDGE_BOTH>,
- <0x1 0xc0 0x1 IRQ_TYPE_EDGE_BOTH>;
- interrupt-names = "hap-sc-irq", "hap-play-irq";
- qcom,pmic-revid = <&pm660_revid>;
- qcom,pmic-misc = <&pm660_misc>;
- qcom,misc-clk-trim-error-reg = <0xf3>;
- qcom,actuator-type = <0>;
- qcom,play-mode = "direct";
- qcom,vmax-mv = <3200>;
- qcom,ilim-ma = <800>;
- qcom,sc-dbc-cycles = <8>;
- qcom,wave-play-rate-us = <6667>;
- qcom,en-brake;
- qcom,lra-high-z = "opt0";
- qcom,lra-auto-res-mode = "qwd";
- qcom,lra-res-cal-period = <4>;
- };
};
};
diff --git a/arch/arm64/boot/dts/qcom/pm660l.dtsi b/arch/arm64/boot/dts/qcom/pm660l.dtsi
index 11101ffe..771154a 100644
--- a/arch/arm64/boot/dts/qcom/pm660l.dtsi
+++ b/arch/arm64/boot/dts/qcom/pm660l.dtsi
@@ -185,35 +185,6 @@
};
};
- pm660l_wled: qcom,leds@d800 {
- compatible = "qcom,qpnp-wled";
- reg = <0xd800 0x100>,
- <0xd900 0x100>;
- reg-names = "qpnp-wled-ctrl-base",
- "qpnp-wled-sink-base";
- interrupts = <0x3 0xd8 0x1 IRQ_TYPE_EDGE_RISING>;
- interrupt-names = "ovp-irq";
- linux,name = "wled";
- linux,default-trigger = "bkl-trigger";
- qcom,fdbk-output = "auto";
- qcom,vref-uv = <127500>;
- qcom,switch-freq-khz = <800>;
- qcom,ovp-mv = <29600>;
- qcom,ilim-ma = <970>;
- qcom,boost-duty-ns = <26>;
- qcom,mod-freq-khz = <9600>;
- qcom,dim-mode = "hybrid";
- qcom,hyb-thres = <625>;
- qcom,sync-dly-us = <800>;
- qcom,fs-curr-ua = <25000>;
- qcom,cons-sync-write-delay-us = <1000>;
- qcom,led-strings-list = [00 01 02];
- qcom,loop-auto-gm-en;
- qcom,pmic-revid = <&pm660l_revid>;
- qcom,auto-calibration-enable;
- status = "ok";
- };
-
flash_led: qcom,leds@d300 {
compatible = "qcom,qpnp-flash-led-v2";
reg = <0xd300 0x100>;
@@ -322,89 +293,5 @@
qcom,default-led-trigger = "switch1_trigger";
};
};
-
- pm660l_lcdb: qpnp-lcdb@ec00 {
- compatible = "qcom,qpnp-lcdb-regulator";
- #address-cells = <1>;
- #size-cells = <1>;
- reg = <0xec00 0x100>;
- interrupts = <0x3 0xec 0x1 IRQ_TYPE_EDGE_RISING>;
- interrupt-names = "sc-irq";
-
- qcom,pmic-revid = <&pm660l_revid>;
-
- lcdb_ldo_vreg: ldo {
- label = "ldo";
- regulator-name = "lcdb_ldo";
- regulator-min-microvolt = <4000000>;
- regulator-max-microvolt = <6000000>;
- };
-
- lcdb_ncp_vreg: ncp {
- label = "ncp";
- regulator-name = "lcdb_ncp";
- regulator-min-microvolt = <4000000>;
- regulator-max-microvolt = <6000000>;
- };
- };
-
- pm660a_oledb: qpnp-oledb@e000 {
- compatible = "qcom,qpnp-oledb-regulator";
- #address-cells = <1>;
- #size-cells = <1>;
- qcom,pmic-revid = <&pm660l_revid>;
- reg = <0xe000 0x100>;
- qcom,pbs-client = <&pm660l_pbs>;
-
- label = "oledb";
- regulator-name = "regulator-oledb";
- regulator-min-microvolt = <5000000>;
- regulator-max-microvolt = <8100000>;
-
- qcom,swire-control;
- qcom,ext-pin-control;
- status = "disabled";
- };
-
- pm660a_labibb: qpnp-labibb-regulator {
- compatible = "qcom,qpnp-labibb-regulator";
- #address-cells = <1>;
- #size-cells = <1>;
- qcom,pmic-revid = <&pm660l_revid>;
- qcom,swire-control;
- status = "disabled";
-
- ibb_regulator: qcom,ibb@dc00 {
- reg = <0xdc00 0x100>;
- reg-names = "ibb_reg";
- regulator-name = "ibb_reg";
-
- regulator-min-microvolt = <4000000>;
- regulator-max-microvolt = <6300000>;
-
- qcom,qpnp-ibb-min-voltage = <1400000>;
- qcom,qpnp-ibb-step-size = <100000>;
- qcom,qpnp-ibb-slew-rate = <2000000>;
- qcom,qpnp-ibb-init-voltage = <4000000>;
- qcom,qpnp-ibb-init-amoled-voltage = <4000000>;
- };
-
- lab_regulator: qcom,lab@de00 {
- reg = <0xde00 0x100>;
- reg-names = "lab";
- regulator-name = "lab_reg";
-
- regulator-min-microvolt = <4600000>;
- regulator-max-microvolt = <6100000>;
-
- qcom,qpnp-lab-min-voltage = <4600000>;
- qcom,qpnp-lab-step-size = <100000>;
- qcom,qpnp-lab-slew-rate = <5000>;
- qcom,qpnp-lab-init-voltage = <4600000>;
- qcom,qpnp-lab-init-amoled-voltage = <4600000>;
-
- qcom,notify-lab-vreg-ok-sts;
- };
- };
};
};
diff --git a/arch/arm64/boot/dts/qcom/sdm670-cdp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm670-cdp-overlay.dts
index f0c820f..9feb5b4 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-cdp-overlay.dts
+++ b/arch/arm64/boot/dts/qcom/sdm670-cdp-overlay.dts
@@ -22,9 +22,12 @@
#include "sdm670-cdp.dtsi"
/ {
- model = "Qualcomm Technologies, Inc. SDM670 CDP";
+ model = "Qualcomm Technologies, Inc. SDM670 PM660 + PM660L CDP";
compatible = "qcom,sdm670-cdp", "qcom,sdm670", "qcom,cdp";
qcom,msm-id = <336 0x0>;
qcom,board-id = <1 0>;
+ qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>,
+ <0x0001001b 0x0102001a 0x0 0x0>,
+ <0x0001001b 0x0201011a 0x0 0x0>;
};
diff --git a/arch/arm64/boot/dts/qcom/sdm670-cdp.dts b/arch/arm64/boot/dts/qcom/sdm670-cdp.dts
index 7e5947b..27882dd 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-cdp.dts
+++ b/arch/arm64/boot/dts/qcom/sdm670-cdp.dts
@@ -17,7 +17,10 @@
#include "sdm670-cdp.dtsi"
/ {
- model = "Qualcomm Technologies, Inc. SDM670 CDP";
+ model = "Qualcomm Technologies, Inc. SDM670 PM660 + PM660L CDP";
compatible = "qcom,sdm670-cdp", "qcom,sdm670", "qcom,cdp";
qcom,board-id = <1 0>;
+ qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>,
+ <0x0001001b 0x0102001a 0x0 0x0>,
+ <0x0001001b 0x0201011a 0x0 0x0>;
};
diff --git a/arch/arm64/boot/dts/qcom/sdm670-cdp.dtsi b/arch/arm64/boot/dts/qcom/sdm670-cdp.dtsi
index 0cf48a3..4f40678 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-cdp.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-cdp.dtsi
@@ -10,6 +10,8 @@
* GNU General Public License for more details.
*/
+#include "sdm670-pmic-overlay.dtsi"
+
&qupv3_se9_2uart {
status = "disabled";
};
diff --git a/arch/arm64/boot/dts/qcom/sdm670-gpu.dtsi b/arch/arm64/boot/dts/qcom/sdm670-gpu.dtsi
new file mode 100644
index 0000000..d13aa15
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm670-gpu.dtsi
@@ -0,0 +1,310 @@
+/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+&soc {
+
+ pil_gpu: qcom,kgsl-hyp {
+ compatible = "qcom,pil-tz-generic";
+ qcom,pas-id = <13>;
+ qcom,firmware-name = "a615_zap";
+ };
+
+ msm_bus: qcom,kgsl-busmon{
+ label = "kgsl-busmon";
+ compatible = "qcom,kgsl-busmon";
+ };
+
+ gpubw: qcom,gpubw {
+ compatible = "qcom,devbw";
+ governor = "bw_vbif";
+ qcom,src-dst-ports = <26 512>;
+ qcom,bw-tbl =
+ < 0 /* off */ >,
+ < 381 /* 100 MHz */ >,
+ < 762 /* 200 MHz */ >,
+ < 1144 /* 300 MHz */ >,
+ < 1720 /* 451 MHz */ >,
+ < 2086 /* 547 MHz */ >,
+ < 2597 /* 681 MHz */ >,
+ < 3147 /* 825 MHz */ >,
+ < 3879 /* 1017 MHz */ >,
+ < 5161 /* 1353 MHz */ >,
+ < 5931 /* 1555 MHz */ >,
+ < 6881 /* 1804 MHz */ >;
+ };
+
+ msm_gpu: qcom,kgsl-3d0@5000000 {
+ label = "kgsl-3d0";
+ compatible = "qcom,kgsl-3d0", "qcom,kgsl-3d";
+ status = "ok";
+ reg = <0x5000000 0x40000>;
+ reg-names = "kgsl_3d0_reg_memory";
+ interrupts = <0 300 0>;
+ interrupt-names = "kgsl_3d0_irq";
+ qcom,id = <0>;
+
+ qcom,chipid = <0x06010500>;
+
+ qcom,initial-pwrlevel = <3>;
+
+ qcom,gpu-quirk-hfi-use-reg;
+
+ /* <HZ/12> */
+ qcom,idle-timeout = <80>;
+ qcom,no-nap;
+
+ qcom,highest-bank-bit = <14>;
+
+ qcom,min-access-length = <64>;
+
+ qcom,ubwc-mode = <2>;
+
+ /* size in bytes */
+ qcom,snapshot-size = <1048576>;
+
+ /* base addr, size */
+ qcom,gpu-qdss-stm = <0x161c0000 0x40000>;
+
+ clocks = <&clock_gfx GPU_CC_GX_GFX3D_CLK>,
+ <&clock_gpucc GPU_CC_CXO_CLK>,
+ <&clock_gcc GCC_DDRSS_GPU_AXI_CLK>,
+ <&clock_gcc GCC_GPU_MEMNOC_GFX_CLK>,
+ <&clock_gpucc GPU_CC_CX_GMU_CLK>,
+ <&clock_gpucc GPU_CC_AHB_CLK>;
+
+ clock-names = "core_clk", "rbbmtimer_clk", "mem_clk",
+ "mem_iface_clk", "gmu_clk", "ahb_clk";
+
+ /* Bus Scale Settings */
+ qcom,gpubw-dev = <&gpubw>;
+ qcom,bus-control;
+ qcom,msm-bus,name = "grp3d";
+ qcom,bus-width = <32>;
+ qcom,msm-bus,num-cases = <12>;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,vectors-KBps =
+ <26 512 0 0>,
+ <26 512 0 400000>, /* 1 bus=100 */
+ <26 512 0 800000>, /* 2 bus=200 */
+ <26 512 0 1200000>, /* 3 bus=300 */
+ <26 512 0 1804000>, /* 4 bus=451 */
+ <26 512 0 2188000>, /* 5 bus=547 */
+ <26 512 0 2724000>, /* 6 bus=681 */
+ <26 512 0 3300000>, /* 7 bus=825 */
+ <26 512 0 4068000>, /* 8 bus=1017 */
+ <26 512 0 5412000>, /* 9 bus=1353 */
+ <26 512 0 6220000>, /* 10 bus=1555 */
+ <26 512 0 7216000>; /* 11 bus=1804 */
+
+ /* GDSC regulator names */
+ regulator-names = "vddcx", "vdd";
+ /* GDSC oxili regulators */
+ vddcx-supply = <&gpu_cx_gdsc>;
+ vdd-supply = <&gpu_gx_gdsc>;
+
+ /* GPU related llc slices */
+ cache-slice-names = "gpu", "gpuhtw";
+ cache-slices = <&llcc 12>, <&llcc 11>;
+
+ /* CPU latency parameter */
+ qcom,pm-qos-active-latency = <660>;
+ qcom,pm-qos-wakeup-latency = <460>;
+
+ /* Enable context aware freq. scaling */
+ qcom,enable-ca-jump;
+ /* Context aware jump busy penalty in us */
+ qcom,ca-busy-penalty = <12000>;
+ /* Context aware jump target power level */
+ qcom,ca-target-pwrlevel = <1>;
+
+ /* GPU Mempools */
+ qcom,gpu-mempools {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "qcom,gpu-mempools";
+
+ /* 4K Page Pool configuration */
+ qcom,gpu-mempool@0 {
+ reg = <0>;
+ qcom,mempool-page-size = <4096>;
+ qcom,mempool-allocate;
+ };
+ /* 8K Page Pool configuration */
+ qcom,gpu-mempool@1 {
+ reg = <1>;
+ qcom,mempool-page-size = <8192>;
+ qcom,mempool-allocate;
+ };
+ /* 64K Page Pool configuration */
+ qcom,gpu-mempool@2 {
+ reg = <2>;
+ qcom,mempool-page-size = <65536>;
+ qcom,mempool-reserved = <256>;
+ };
+ /* 1M Page Pool configuration */
+ qcom,gpu-mempool@3 {
+ reg = <3>;
+ qcom,mempool-page-size = <1048576>;
+ qcom,mempool-reserved = <32>;
+ };
+ };
+
+ /* Power levels */
+ qcom,gpu-pwrlevels {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ compatible = "qcom,gpu-pwrlevels";
+
+ /* SVS_L1 */
+ qcom,gpu-pwrlevel@0 {
+ reg = <0>;
+ qcom,gpu-freq = <430000000>;
+ qcom,bus-freq = <11>;
+ qcom,bus-min = <10>;
+ qcom,bus-max = <11>;
+ };
+
+ /* SVS */
+ qcom,gpu-pwrlevel@1 {
+ reg = <1>;
+ qcom,gpu-freq = <355000000>;
+ qcom,bus-freq = <9>;
+ qcom,bus-min = <8>;
+ qcom,bus-max = <10>;
+ };
+
+ /* LOW SVS */
+ qcom,gpu-pwrlevel@2 {
+ reg = <2>;
+ qcom,gpu-freq = <267000000>;
+ qcom,bus-freq = <6>;
+ qcom,bus-min = <4>;
+ qcom,bus-max = <8>;
+ };
+
+ /* MIN SVS */
+ qcom,gpu-pwrlevel@3 {
+ reg = <3>;
+ qcom,gpu-freq = <180000000>;
+ qcom,bus-freq = <4>;
+ qcom,bus-min = <3>;
+ qcom,bus-max = <5>;
+ };
+
+ /* XO */
+ qcom,gpu-pwrlevel@4 {
+ reg = <4>;
+ qcom,gpu-freq = <0>;
+ qcom,bus-freq = <0>;
+ qcom,bus-min = <0>;
+ qcom,bus-max = <0>;
+ };
+ };
+
+ };
+
+ kgsl_msm_iommu: qcom,kgsl-iommu {
+ compatible = "qcom,kgsl-smmu-v2";
+
+ reg = <0x05040000 0x10000>;
+ qcom,protect = <0x40000 0x10000>;
+ qcom,micro-mmu-control = <0x6000>;
+
+ clocks =<&clock_gcc GCC_GPU_CFG_AHB_CLK>,
+ <&clock_gcc GCC_DDRSS_GPU_AXI_CLK>,
+ <&clock_gcc GCC_GPU_MEMNOC_GFX_CLK>;
+
+ clock-names = "iface_clk", "mem_clk", "mem_iface_clk";
+
+ qcom,secure_align_mask = <0xfff>;
+ qcom,retention;
+ qcom,hyp_secure_alloc;
+
+ gfx3d_user: gfx3d_user {
+ compatible = "qcom,smmu-kgsl-cb";
+ label = "gfx3d_user";
+ iommus = <&kgsl_smmu 0>;
+ qcom,gpu-offset = <0x48000>;
+ };
+
+ gfx3d_secure: gfx3d_secure {
+ compatible = "qcom,smmu-kgsl-cb";
+ iommus = <&kgsl_smmu 2>;
+ };
+ };
+
+ gmu: qcom,gmu {
+ label = "kgsl-gmu";
+ compatible = "qcom,gpu-gmu";
+
+ reg =
+ <0x506a000 0x31000>,
+ <0xb200000 0x300000>,
+ <0xc200000 0x10000>;
+ reg-names =
+ "kgsl_gmu_reg",
+ "kgsl_gmu_pdc_reg",
+ "kgsl_gmu_cpr_reg";
+
+ interrupts = <0 304 0>, <0 305 0>;
+ interrupt-names = "kgsl_hfi_irq", "kgsl_gmu_irq";
+
+ qcom,msm-bus,name = "cnoc";
+ qcom,msm-bus,num-cases = <2>;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,vectors-KBps =
+ <26 10036 0 0>, /* CNOC off */
+ <26 10036 0 100>; /* CNOC on */
+
+ regulator-names = "vddcx", "vdd";
+ vddcx-supply = <&gpu_cx_gdsc>;
+ vdd-supply = <&gpu_gx_gdsc>;
+
+
+ clocks = <&clock_gpucc GPU_CC_CX_GMU_CLK>,
+ <&clock_gpucc GPU_CC_CXO_CLK>,
+ <&clock_gcc GCC_DDRSS_GPU_AXI_CLK>,
+ <&clock_gcc GCC_GPU_MEMNOC_GFX_CLK>,
+ <&clock_gpucc GPU_CC_AHB_CLK>;
+
+ clock-names = "gmu_clk", "cxo_clk", "axi_clk",
+ "memnoc_clk", "ahb_clk";
+
+ qcom,gmu-pwrlevels {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ compatible = "qcom,gmu-pwrlevels";
+
+ qcom,gmu-pwrlevel@0 {
+ reg = <0>;
+ qcom,gmu-freq = <200000000>;
+ };
+
+ qcom,gmu-pwrlevel@1 {
+ reg = <1>;
+ qcom,gmu-freq = <0>;
+ };
+ };
+
+ gmu_user: gmu_user {
+ compatible = "qcom,smmu-gmu-user-cb";
+ iommus = <&kgsl_smmu 4>;
+ };
+
+ gmu_kernel: gmu_kernel {
+ compatible = "qcom,smmu-gmu-kernel-cb";
+ iommus = <&kgsl_smmu 5>;
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm670-mtp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm670-mtp-overlay.dts
index c8537bc..65c16c1 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-mtp-overlay.dts
+++ b/arch/arm64/boot/dts/qcom/sdm670-mtp-overlay.dts
@@ -22,8 +22,11 @@
#include "sdm670-mtp.dtsi"
/ {
- model = "Qualcomm Technologies, Inc. SDM670 MTP";
+ model = "Qualcomm Technologies, Inc. SDM670 PM660 + PM660L MTP";
compatible = "qcom,sdm670-mtp", "qcom,sdm670", "qcom,mtp";
qcom,msm-id = <336 0x0>;
qcom,board-id = <8 0>;
+ qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>,
+ <0x0001001b 0x0102001a 0x0 0x0>,
+ <0x0001001b 0x0201011a 0x0 0x0>;
};
diff --git a/arch/arm64/boot/dts/qcom/sdm670-mtp.dts b/arch/arm64/boot/dts/qcom/sdm670-mtp.dts
index 1de40b7..38a9fae 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-mtp.dts
+++ b/arch/arm64/boot/dts/qcom/sdm670-mtp.dts
@@ -17,7 +17,10 @@
#include "sdm670-mtp.dtsi"
/ {
- model = "Qualcomm Technologies, Inc. SDM670 MTP";
+ model = "Qualcomm Technologies, Inc. SDM670 PM660 + PM660L MTP";
compatible = "qcom,sdm670-mtp", "qcom,sdm670", "qcom,mtp";
qcom,board-id = <8 0>;
+ qcom,pmic-id = <0x0001001b 0x0101011a 0x0 0x0>,
+ <0x0001001b 0x0102001a 0x0 0x0>,
+ <0x0001001b 0x0201011a 0x0 0x0>;
};
diff --git a/arch/arm64/boot/dts/qcom/sdm670-mtp.dtsi b/arch/arm64/boot/dts/qcom/sdm670-mtp.dtsi
index 0cf48a3..4f40678 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-mtp.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-mtp.dtsi
@@ -10,6 +10,8 @@
* GNU General Public License for more details.
*/
+#include "sdm670-pmic-overlay.dtsi"
+
&qupv3_se9_2uart {
status = "disabled";
};
diff --git a/arch/arm64/boot/dts/qcom/sdm670-pm660a-cdp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm670-pm660a-cdp-overlay.dts
new file mode 100644
index 0000000..b3d2357
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm670-pm660a-cdp-overlay.dts
@@ -0,0 +1,34 @@
+/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/clock/qcom,gcc-sdm845.h>
+#include <dt-bindings/clock/qcom,camcc-sdm845.h>
+#include <dt-bindings/clock/qcom,dispcc-sdm845.h>
+#include <dt-bindings/clock/qcom,rpmh.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include "sdm670-cdp.dtsi"
+#include "pm660a.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDM670 PM660 + PM660A CDP";
+ compatible = "qcom,sdm670-cdp", "qcom,sdm670", "qcom,cdp";
+ qcom,msm-id = <336 0x0>;
+ qcom,board-id = <1 0>;
+ qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>,
+ <0x0001001b 0x0002001a 0x0 0x0>,
+ <0x0001001b 0x0202001a 0x0 0x0>;
+};
+
diff --git a/arch/arm64/boot/dts/qcom/sdm670-pm660a-cdp.dts b/arch/arm64/boot/dts/qcom/sdm670-pm660a-cdp.dts
new file mode 100644
index 0000000..5cf3513
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm670-pm660a-cdp.dts
@@ -0,0 +1,27 @@
+/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+
+/dts-v1/;
+
+#include "sdm670.dtsi"
+#include "sdm670-cdp.dtsi"
+#include "pm660a.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDM670 PM660 + PM660A CDP";
+ compatible = "qcom,sdm670-cdp", "qcom,sdm670", "qcom,cdp";
+ qcom,board-id = <1 0>;
+ qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>,
+ <0x0001001b 0x0002001a 0x0 0x0>,
+ <0x0001001b 0x0202001a 0x0 0x0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm670-pm660a-mtp-overlay.dts b/arch/arm64/boot/dts/qcom/sdm670-pm660a-mtp-overlay.dts
new file mode 100644
index 0000000..ff3270d
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm670-pm660a-mtp-overlay.dts
@@ -0,0 +1,33 @@
+/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/clock/qcom,gcc-sdm845.h>
+#include <dt-bindings/clock/qcom,camcc-sdm845.h>
+#include <dt-bindings/clock/qcom,dispcc-sdm845.h>
+#include <dt-bindings/clock/qcom,rpmh.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include "sdm670-mtp.dtsi"
+#include "pm660a.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDM670 PM660 + PM660A MTP";
+ compatible = "qcom,sdm670-mtp", "qcom,sdm670", "qcom,mtp";
+ qcom,msm-id = <336 0x0>;
+ qcom,board-id = <8 0>;
+ qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>,
+ <0x0001001b 0x0002001a 0x0 0x0>,
+ <0x0001001b 0x0202001a 0x0 0x0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm670-pm660a-mtp.dts b/arch/arm64/boot/dts/qcom/sdm670-pm660a-mtp.dts
new file mode 100644
index 0000000..febd5d9
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm670-pm660a-mtp.dts
@@ -0,0 +1,27 @@
+/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+
+/dts-v1/;
+
+#include "sdm670.dtsi"
+#include "sdm670-mtp.dtsi"
+#include "pm660a.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDM670 PM660 + PM660A MTP";
+ compatible = "qcom,sdm670-mtp", "qcom,sdm670", "qcom,mtp";
+ qcom,board-id = <8 0>;
+ qcom,pmic-id = <0x0001001b 0x0001011a 0x0 0x0>,
+ <0x0001001b 0x0002001a 0x0 0x0>,
+ <0x0001001b 0x0202001a 0x0 0x0>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm670-pmic-overlay.dtsi b/arch/arm64/boot/dts/qcom/sdm670-pmic-overlay.dtsi
new file mode 100644
index 0000000..cd8bfba
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm670-pmic-overlay.dtsi
@@ -0,0 +1,367 @@
+/* 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.
+ */
+
+&pm660_0{
+ pm660_charger: qcom,qpnp-smb2 {
+ compatible = "qcom,qpnp-smb2";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ qcom,pmic-revid = <&pm660_revid>;
+
+ io-channels = <&pm660_rradc 8>,
+ <&pm660_rradc 10>,
+ <&pm660_rradc 3>,
+ <&pm660_rradc 4>;
+ io-channel-names = "charger_temp",
+ "charger_temp_max",
+ "usbin_i",
+ "usbin_v";
+
+ qcom,wipower-max-uw = <5000000>;
+
+ /* Enable after the qusb_phy0 device node is added */
+ /* dpdm-supply = <&qusb_phy0>; */
+
+ qcom,thermal-mitigation
+ = <3000000 2500000 2000000 1500000
+ 1000000 500000>;
+
+ qcom,chgr@1000 {
+ reg = <0x1000 0x100>;
+ interrupts =
+ <0x0 0x10 0x0 IRQ_TYPE_EDGE_RISING>,
+ <0x0 0x10 0x1 IRQ_TYPE_EDGE_RISING>,
+ <0x0 0x10 0x2 IRQ_TYPE_EDGE_RISING>,
+ <0x0 0x10 0x3 IRQ_TYPE_EDGE_RISING>,
+ <0x0 0x10 0x4 IRQ_TYPE_EDGE_RISING>;
+
+ interrupt-names = "chg-error",
+ "chg-state-change",
+ "step-chg-state-change",
+ "step-chg-soc-update-fail",
+ "step-chg-soc-update-request";
+ };
+
+ qcom,otg@1100 {
+ reg = <0x1100 0x100>;
+ interrupts = <0x0 0x11 0x0 IRQ_TYPE_EDGE_BOTH>,
+ <0x0 0x11 0x1 IRQ_TYPE_EDGE_BOTH>,
+ <0x0 0x11 0x2 IRQ_TYPE_EDGE_BOTH>,
+ <0x0 0x11 0x3 IRQ_TYPE_EDGE_BOTH>;
+
+ interrupt-names = "otg-fail",
+ "otg-overcurrent",
+ "otg-oc-dis-sw-sts",
+ "testmode-change-detect";
+ };
+
+ qcom,bat-if@1200 {
+ reg = <0x1200 0x100>;
+ interrupts =
+ <0x0 0x12 0x0 IRQ_TYPE_EDGE_RISING>,
+ <0x0 0x12 0x1 IRQ_TYPE_EDGE_BOTH>,
+ <0x0 0x12 0x2 IRQ_TYPE_EDGE_BOTH>,
+ <0x0 0x12 0x3 IRQ_TYPE_EDGE_BOTH>,
+ <0x0 0x12 0x4 IRQ_TYPE_EDGE_BOTH>,
+ <0x0 0x12 0x5 IRQ_TYPE_EDGE_BOTH>;
+
+ interrupt-names = "bat-temp",
+ "bat-ocp",
+ "bat-ov",
+ "bat-low",
+ "bat-therm-or-id-missing",
+ "bat-terminal-missing";
+ };
+
+ qcom,usb-chgpth@1300 {
+ reg = <0x1300 0x100>;
+ interrupts =
+ <0x0 0x13 0x0 IRQ_TYPE_EDGE_BOTH>,
+ <0x0 0x13 0x1 IRQ_TYPE_EDGE_BOTH>,
+ <0x0 0x13 0x2 IRQ_TYPE_EDGE_BOTH>,
+ <0x0 0x13 0x3 IRQ_TYPE_EDGE_BOTH>,
+ <0x0 0x13 0x4 IRQ_TYPE_EDGE_BOTH>,
+ <0x0 0x13 0x5 IRQ_TYPE_EDGE_RISING>,
+ <0x0 0x13 0x6 IRQ_TYPE_EDGE_RISING>,
+ <0x0 0x13 0x7 IRQ_TYPE_EDGE_RISING>;
+
+ interrupt-names = "usbin-collapse",
+ "usbin-lt-3p6v",
+ "usbin-uv",
+ "usbin-ov",
+ "usbin-plugin",
+ "usbin-src-change",
+ "usbin-icl-change",
+ "type-c-change";
+ };
+
+ qcom,dc-chgpth@1400 {
+ reg = <0x1400 0x100>;
+ interrupts =
+ <0x0 0x14 0x0 IRQ_TYPE_EDGE_BOTH>,
+ <0x0 0x14 0x1 IRQ_TYPE_EDGE_BOTH>,
+ <0x0 0x14 0x2 IRQ_TYPE_EDGE_BOTH>,
+ <0x0 0x14 0x3 IRQ_TYPE_EDGE_BOTH>,
+ <0x0 0x14 0x4 IRQ_TYPE_EDGE_BOTH>,
+ <0x0 0x14 0x5 IRQ_TYPE_EDGE_BOTH>,
+ <0x0 0x14 0x6 IRQ_TYPE_EDGE_RISING>;
+
+ interrupt-names = "dcin-collapse",
+ "dcin-lt-3p6v",
+ "dcin-uv",
+ "dcin-ov",
+ "dcin-plugin",
+ "div2-en-dg",
+ "dcin-icl-change";
+ };
+
+ qcom,chgr-misc@1600 {
+ reg = <0x1600 0x100>;
+ interrupts =
+ <0x0 0x16 0x0 IRQ_TYPE_EDGE_RISING>,
+ <0x0 0x16 0x1 IRQ_TYPE_EDGE_RISING>,
+ <0x0 0x16 0x2 IRQ_TYPE_EDGE_BOTH>,
+ <0x0 0x16 0x3 IRQ_TYPE_EDGE_BOTH>,
+ <0x0 0x16 0x4 IRQ_TYPE_EDGE_BOTH>,
+ <0x0 0x16 0x5 IRQ_TYPE_EDGE_BOTH>,
+ <0x0 0x16 0x6 IRQ_TYPE_EDGE_FALLING>,
+ <0x0 0x16 0x7 IRQ_TYPE_EDGE_BOTH>;
+
+ interrupt-names = "wdog-snarl",
+ "wdog-bark",
+ "aicl-fail",
+ "aicl-done",
+ "high-duty-cycle",
+ "input-current-limiting",
+ "temperature-change",
+ "switcher-power-ok";
+ };
+ smb2_vbus: qcom,smb2-vbus {
+ regulator-name = "smb2-vbus";
+ };
+
+ smb2_vconn: qcom,smb2-vconn {
+ regulator-name = "smb2-vconn";
+ };
+ };
+
+ pm660_fg: qpnp,fg {
+ compatible = "qcom,fg-gen3";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ qcom,pmic-revid = <&pm660_revid>;
+ io-channels = <&pm660_rradc 0>,
+ <&pm660_rradc 7>;
+ io-channel-names = "rradc_batt_id",
+ "rradc_die_temp";
+ qcom,rradc-base = <0x4500>;
+ qcom,fg-esr-timer-awake = <96 96>;
+ qcom,fg-esr-timer-asleep = <256 256>;
+ qcom,fg-esr-timer-charging = <0 96>;
+ qcom,cycle-counter-en;
+ status = "okay";
+
+ qcom,fg-batt-soc@4000 {
+ status = "okay";
+ reg = <0x4000 0x100>;
+ interrupts = <0x0 0x40 0x0 IRQ_TYPE_EDGE_BOTH>,
+ <0x0 0x40 0x1 IRQ_TYPE_EDGE_BOTH>,
+ <0x0 0x40 0x2
+ IRQ_TYPE_EDGE_RISING>,
+ <0x0 0x40 0x3
+ IRQ_TYPE_EDGE_RISING>,
+ <0x0 0x40 0x4 IRQ_TYPE_EDGE_BOTH>,
+ <0x0 0x40 0x5
+ IRQ_TYPE_EDGE_RISING>,
+ <0x0 0x40 0x6 IRQ_TYPE_EDGE_BOTH>,
+ <0x0 0x40 0x7 IRQ_TYPE_EDGE_BOTH>;
+ interrupt-names = "soc-update",
+ "soc-ready",
+ "bsoc-delta",
+ "msoc-delta",
+ "msoc-low",
+ "msoc-empty",
+ "msoc-high",
+ "msoc-full";
+ };
+
+ qcom,fg-batt-info@4100 {
+ status = "okay";
+ reg = <0x4100 0x100>;
+ interrupts = <0x0 0x41 0x0 IRQ_TYPE_EDGE_BOTH>,
+ <0x0 0x41 0x1 IRQ_TYPE_EDGE_BOTH>,
+ <0x0 0x41 0x2 IRQ_TYPE_EDGE_BOTH>,
+ <0x0 0x41 0x3 IRQ_TYPE_EDGE_BOTH>,
+ <0x0 0x41 0x6 IRQ_TYPE_EDGE_BOTH>;
+ interrupt-names = "vbatt-pred-delta",
+ "vbatt-low",
+ "esr-delta",
+ "batt-missing",
+ "batt-temp-delta";
+ };
+
+ qcom,fg-memif@4400 {
+ status = "okay";
+ reg = <0x4400 0x100>;
+ interrupts = <0x0 0x44 0x0 IRQ_TYPE_EDGE_BOTH>,
+ <0x0 0x44 0x1 IRQ_TYPE_EDGE_BOTH>,
+ <0x0 0x44 0x2 IRQ_TYPE_EDGE_BOTH>;
+ interrupt-names = "ima-rdy",
+ "mem-xcp",
+ "dma-grant";
+ };
+ };
+};
+
+&pm660_1 {
+ pm660_haptics: qcom,haptics@c000 {
+ compatible = "qcom,qpnp-haptics";
+ reg = <0xc000 0x100>;
+ interrupts = <0x1 0xc0 0x0 IRQ_TYPE_EDGE_BOTH>,
+ <0x1 0xc0 0x1 IRQ_TYPE_EDGE_BOTH>;
+ interrupt-names = "hap-sc-irq", "hap-play-irq";
+ qcom,pmic-revid = <&pm660_revid>;
+ qcom,pmic-misc = <&pm660_misc>;
+ qcom,misc-clk-trim-error-reg = <0xf3>;
+ qcom,actuator-type = <0>;
+ qcom,play-mode = "direct";
+ qcom,vmax-mv = <3200>;
+ qcom,ilim-ma = <800>;
+ qcom,sc-dbc-cycles = <8>;
+ qcom,wave-play-rate-us = <6667>;
+ qcom,en-brake;
+ qcom,lra-high-z = "opt0";
+ qcom,lra-auto-res-mode = "qwd";
+ qcom,lra-res-cal-period = <4>;
+ };
+};
+
+&pm660l_3 {
+ pm660l_wled: qcom,leds@d800 {
+ compatible = "qcom,qpnp-wled";
+ reg = <0xd800 0x100>,
+ <0xd900 0x100>;
+ reg-names = "qpnp-wled-ctrl-base",
+ "qpnp-wled-sink-base";
+ interrupts = <0x3 0xd8 0x1 IRQ_TYPE_EDGE_RISING>;
+ interrupt-names = "ovp-irq";
+ linux,name = "wled";
+ linux,default-trigger = "bkl-trigger";
+ qcom,fdbk-output = "auto";
+ qcom,vref-uv = <127500>;
+ qcom,switch-freq-khz = <800>;
+ qcom,ovp-mv = <29600>;
+ qcom,ilim-ma = <970>;
+ qcom,boost-duty-ns = <26>;
+ qcom,mod-freq-khz = <9600>;
+ qcom,dim-mode = "hybrid";
+ qcom,hyb-thres = <625>;
+ qcom,sync-dly-us = <800>;
+ qcom,fs-curr-ua = <25000>;
+ qcom,cons-sync-write-delay-us = <1000>;
+ qcom,led-strings-list = [00 01 02];
+ qcom,loop-auto-gm-en;
+ qcom,pmic-revid = <&pm660l_revid>;
+ qcom,auto-calibration-enable;
+ status = "ok";
+ };
+
+ pm660l_lcdb: qpnp-lcdb@ec00 {
+ compatible = "qcom,qpnp-lcdb-regulator";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0xec00 0x100>;
+ interrupts = <0x3 0xec 0x1 IRQ_TYPE_EDGE_RISING>;
+ interrupt-names = "sc-irq";
+
+ qcom,pmic-revid = <&pm660l_revid>;
+
+ lcdb_ldo_vreg: ldo {
+ label = "ldo";
+ regulator-name = "lcdb_ldo";
+ regulator-min-microvolt = <4000000>;
+ regulator-max-microvolt = <6000000>;
+ };
+
+ lcdb_ncp_vreg: ncp {
+ label = "ncp";
+ regulator-name = "lcdb_ncp";
+ regulator-min-microvolt = <4000000>;
+ regulator-max-microvolt = <6000000>;
+ };
+ };
+
+ pm660a_oledb: qpnp-oledb@e000 {
+ compatible = "qcom,qpnp-oledb-regulator";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ qcom,pmic-revid = <&pm660l_revid>;
+ reg = <0xe000 0x100>;
+ qcom,pbs-client = <&pm660l_pbs>;
+
+ label = "oledb";
+ regulator-name = "regulator-oledb";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <8100000>;
+
+ qcom,swire-control;
+ qcom,ext-pin-control;
+ status = "disabled";
+ };
+
+ pm660a_labibb: qpnp-labibb-regulator {
+ compatible = "qcom,qpnp-labibb-regulator";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ qcom,pmic-revid = <&pm660l_revid>;
+ qcom,swire-control;
+ status = "disabled";
+
+ ibb_regulator: qcom,ibb@dc00 {
+ reg = <0xdc00 0x100>;
+ reg-names = "ibb_reg";
+ regulator-name = "ibb_reg";
+
+ regulator-min-microvolt = <4000000>;
+ regulator-max-microvolt = <6300000>;
+
+ qcom,qpnp-ibb-min-voltage = <1400000>;
+ qcom,qpnp-ibb-step-size = <100000>;
+ qcom,qpnp-ibb-slew-rate = <2000000>;
+ qcom,qpnp-ibb-init-voltage = <4000000>;
+ qcom,qpnp-ibb-init-amoled-voltage = <4000000>;
+ };
+
+ lab_regulator: qcom,lab@de00 {
+ reg = <0xde00 0x100>;
+ reg-names = "lab";
+ regulator-name = "lab_reg";
+
+ regulator-min-microvolt = <4600000>;
+ regulator-max-microvolt = <6100000>;
+
+ qcom,qpnp-lab-min-voltage = <4600000>;
+ qcom,qpnp-lab-step-size = <100000>;
+ qcom,qpnp-lab-slew-rate = <5000>;
+ qcom,qpnp-lab-init-voltage = <4600000>;
+ qcom,qpnp-lab-init-amoled-voltage = <4600000>;
+
+ qcom,notify-lab-vreg-ok-sts;
+ };
+ };
+};
+
+&pm660_pdphy {
+ vbus-supply = <&smb2_vbus>;
+ vconn-supply = <&smb2_vconn>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm670-regulator.dtsi b/arch/arm64/boot/dts/qcom/sdm670-regulator.dtsi
index 0a8c49f..1f76288 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-regulator.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-regulator.dtsi
@@ -628,13 +628,3 @@
};
};
};
-
-&pm660_charger {
- smb2_vbus: qcom,smb2-vbus {
- regulator-name = "smb2-vbus";
- };
-
- smb2_vconn: qcom,smb2-vconn {
- regulator-name = "smb2-vconn";
- };
-};
diff --git a/arch/arm64/boot/dts/qcom/sdm670-rumi-overlay.dts b/arch/arm64/boot/dts/qcom/sdm670-rumi-overlay.dts
index a770b3c..4a24d87 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-rumi-overlay.dts
+++ b/arch/arm64/boot/dts/qcom/sdm670-rumi-overlay.dts
@@ -13,6 +13,7 @@
/dts-v1/;
/plugin/;
+#include <dt-bindings/interrupt-controller/arm-gic.h>
#include "sdm670-rumi.dtsi"
/ {
diff --git a/arch/arm64/boot/dts/qcom/sdm670-rumi.dtsi b/arch/arm64/boot/dts/qcom/sdm670-rumi.dtsi
index cc97e3e..ca9d8c7 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-rumi.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-rumi.dtsi
@@ -10,6 +10,8 @@
* GNU General Public License for more details.
*/
+#include "sdm670-pmic-overlay.dtsi"
+
&soc {
/* Delete all regulators */
/delete-node/ rpmh-regulator-smpa4;
diff --git a/arch/arm64/boot/dts/qcom/sdm670.dtsi b/arch/arm64/boot/dts/qcom/sdm670.dtsi
index aeaa3ff..6e987f1 100644
--- a/arch/arm64/boot/dts/qcom/sdm670.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670.dtsi
@@ -72,6 +72,9 @@
compatible = "arm,arch-cache";
qcom,dump-size = <0x9000>;
};
+ L1_TLB_0: l1-tlb {
+ qcom,dump-size = <0x3000>;
+ };
};
CPU1: cpu@100 {
@@ -97,6 +100,9 @@
compatible = "arm,arch-cache";
qcom,dump-size = <0x9000>;
};
+ L1_TLB_100: l1-tlb {
+ qcom,dump-size = <0x3000>;
+ };
};
CPU2: cpu@200 {
@@ -122,6 +128,9 @@
compatible = "arm,arch-cache";
qcom,dump-size = <0x9000>;
};
+ L1_TLB_200: l1-tlb {
+ qcom,dump-size = <0x3000>;
+ };
};
CPU3: cpu@300 {
@@ -147,6 +156,9 @@
compatible = "arm,arch-cache";
qcom,dump-size = <0x9000>;
};
+ L1_TLB_300: l1-tlb {
+ qcom,dump-size = <0x3000>;
+ };
};
CPU4: cpu@400 {
@@ -172,6 +184,9 @@
compatible = "arm,arch-cache";
qcom,dump-size = <0x9000>;
};
+ L1_TLB_400: l1-tlb {
+ qcom,dump-size = <0x3000>;
+ };
};
CPU5: cpu@500 {
@@ -197,6 +212,9 @@
compatible = "arm,arch-cache";
qcom,dump-size = <0x9000>;
};
+ L1_TLB_500: l1-tlb {
+ qcom,dump-size = <0x3000>;
+ };
};
CPU6: cpu@600 {
@@ -222,6 +240,9 @@
compatible = "arm,arch-cache";
qcom,dump-size = <0x12000>;
};
+ L1_TLB_600: l1-tlb {
+ qcom,dump-size = <0x3c000>;
+ };
};
CPU7: cpu@700 {
@@ -247,6 +268,9 @@
compatible = "arm,arch-cache";
qcom,dump-size = <0x12000>;
};
+ L1_TLB_700: l1-tlb {
+ qcom,dump-size = <0x3c000>;
+ };
};
cpu-map {
@@ -1024,31 +1048,31 @@
qcom,dump-node = <&L1_I_0>;
qcom,dump-id = <0x60>;
};
- qcom,l1_i_cache1 {
+ qcom,l1_i_cache100 {
qcom,dump-node = <&L1_I_100>;
qcom,dump-id = <0x61>;
};
- qcom,l1_i_cache2 {
+ qcom,l1_i_cache200 {
qcom,dump-node = <&L1_I_200>;
qcom,dump-id = <0x62>;
};
- qcom,l1_i_cache3 {
+ qcom,l1_i_cache300 {
qcom,dump-node = <&L1_I_300>;
qcom,dump-id = <0x63>;
};
- qcom,l1_i_cache100 {
+ qcom,l1_i_cache400 {
qcom,dump-node = <&L1_I_400>;
qcom,dump-id = <0x64>;
};
- qcom,l1_i_cache101 {
+ qcom,l1_i_cache500 {
qcom,dump-node = <&L1_I_500>;
qcom,dump-id = <0x65>;
};
- qcom,l1_i_cache102 {
+ qcom,l1_i_cache600 {
qcom,dump-node = <&L1_I_600>;
qcom,dump-id = <0x66>;
};
- qcom,l1_i_cache103 {
+ qcom,l1_i_cache700 {
qcom,dump-node = <&L1_I_700>;
qcom,dump-id = <0x67>;
};
@@ -1056,31 +1080,31 @@
qcom,dump-node = <&L1_D_0>;
qcom,dump-id = <0x80>;
};
- qcom,l1_d_cache1 {
+ qcom,l1_d_cache100 {
qcom,dump-node = <&L1_D_100>;
qcom,dump-id = <0x81>;
};
- qcom,l1_d_cache2 {
+ qcom,l1_d_cache200 {
qcom,dump-node = <&L1_D_200>;
qcom,dump-id = <0x82>;
};
- qcom,l1_d_cache3 {
+ qcom,l1_d_cache300 {
qcom,dump-node = <&L1_D_300>;
qcom,dump-id = <0x83>;
};
- qcom,l1_d_cache100 {
+ qcom,l1_d_cache400 {
qcom,dump-node = <&L1_D_400>;
qcom,dump-id = <0x84>;
};
- qcom,l1_d_cache101 {
+ qcom,l1_d_cache500 {
qcom,dump-node = <&L1_D_500>;
qcom,dump-id = <0x85>;
};
- qcom,l1_d_cache102 {
+ qcom,l1_d_cache600 {
qcom,dump-node = <&L1_D_600>;
qcom,dump-id = <0x86>;
};
- qcom,l1_d_cache103 {
+ qcom,l1_d_cache700 {
qcom,dump-node = <&L1_D_700>;
qcom,dump-id = <0x87>;
};
@@ -1092,6 +1116,38 @@
qcom,dump-node = <&LLCC_2>;
qcom,dump-id = <0x141>;
};
+ qcom,l1_tlb_dump0 {
+ qcom,dump-node = <&L1_TLB_0>;
+ qcom,dump-id = <0x20>;
+ };
+ qcom,l1_tlb_dump100 {
+ qcom,dump-node = <&L1_TLB_100>;
+ qcom,dump-id = <0x21>;
+ };
+ qcom,l1_tlb_dump200 {
+ qcom,dump-node = <&L1_TLB_200>;
+ qcom,dump-id = <0x22>;
+ };
+ qcom,l1_tlb_dump300 {
+ qcom,dump-node = <&L1_TLB_300>;
+ qcom,dump-id = <0x23>;
+ };
+ qcom,l1_tlb_dump400 {
+ qcom,dump-node = <&L1_TLB_400>;
+ qcom,dump-id = <0x24>;
+ };
+ qcom,l1_tlb_dump500 {
+ qcom,dump-node = <&L1_TLB_500>;
+ qcom,dump-id = <0x25>;
+ };
+ qcom,l1_tlb_dump600 {
+ qcom,dump-node = <&L1_TLB_600>;
+ qcom,dump-id = <0x26>;
+ };
+ qcom,l1_tlb_dump700 {
+ qcom,dump-node = <&L1_TLB_700>;
+ qcom,dump-id = <0x27>;
+ };
};
kryo3xx-erp {
@@ -2047,3 +2103,4 @@
#include "sdm670-regulator.dtsi"
#include "sdm670-audio.dtsi"
#include "sdm670-usb.dtsi"
+#include "sdm670-gpu.dtsi"
diff --git a/arch/arm64/boot/dts/qcom/sdm845-coresight.dtsi b/arch/arm64/boot/dts/qcom/sdm845-coresight.dtsi
index c1fcb62..3cfcddb 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-coresight.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-coresight.dtsi
@@ -1430,6 +1430,15 @@
<&tpda_spss_out_funnel_spss>;
};
};
+
+ port@2 {
+ reg = <1>;
+ funnel_spss_in_spss_etm0: endpoint {
+ slave-mode;
+ remote-endpoint =
+ <&spss_etm0_out_funnel_spss>;
+ };
+ };
};
};
@@ -1931,6 +1940,20 @@
};
};
+ spss_etm0 {
+ compatible = "qcom,coresight-dummy";
+
+ coresight-name = "coresight-spss-etm0";
+
+ qcom,dummy-source;
+ port {
+ spss_etm0_out_funnel_spss: endpoint {
+ remote-endpoint =
+ <&funnel_spss_in_spss_etm0>;
+ };
+ };
+ };
+
funnel_apss_merg: funnel@7810000 {
compatible = "arm,primecell";
arm,primecell-periphid = <0x0003b908>;
diff --git a/arch/arm64/boot/dts/qcom/sdm845-interposer-pm660.dtsi b/arch/arm64/boot/dts/qcom/sdm845-interposer-pm660.dtsi
index 299f01b..e36a759e 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-interposer-pm660.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-interposer-pm660.dtsi
@@ -389,6 +389,7 @@
#include "pm660.dtsi"
#include "pm660l.dtsi"
#include "sdm670-regulator.dtsi"
+#include "sdm670-pmic-overlay.dtsi"
&soc {
/delete-node/ thermal-zones;
diff --git a/drivers/gpu/drm/msm/sde/sde_hw_ctl.c b/drivers/gpu/drm/msm/sde/sde_hw_ctl.c
index 6b1f33d..621a172 100644
--- a/drivers/gpu/drm/msm/sde/sde_hw_ctl.c
+++ b/drivers/gpu/drm/msm/sde/sde_hw_ctl.c
@@ -39,7 +39,7 @@
#define CTL_FLUSH_MASK_ROT BIT(27)
#define CTL_FLUSH_MASK_CTL BIT(17)
-#define SDE_REG_RESET_TIMEOUT_COUNT 20
+#define SDE_REG_RESET_TIMEOUT_US 2000
static struct sde_ctl_cfg *_ctl_offset(enum sde_ctl ctl,
struct sde_mdss_cfg *m,
@@ -298,14 +298,13 @@
return 0;
}
-static u32 sde_hw_ctl_poll_reset_status(struct sde_hw_ctl *ctx, u32 count)
+static u32 sde_hw_ctl_poll_reset_status(struct sde_hw_ctl *ctx, u32 timeout_us)
{
struct sde_hw_blk_reg_map *c = &ctx->hw;
+ ktime_t timeout;
u32 status;
- /* protect to do at least one iteration */
- if (!count)
- count = 1;
+ timeout = ktime_add_us(ktime_get(), timeout_us);
/*
* it takes around 30us to have mdp finish resetting its ctl path
@@ -313,10 +312,10 @@
*/
do {
status = SDE_REG_READ(c, CTL_SW_RESET);
- status &= 0x01;
+ status &= 0x1;
if (status)
usleep_range(20, 50);
- } while (status && --count > 0);
+ } while (status && ktime_compare_safe(ktime_get(), timeout) < 0);
return status;
}
@@ -327,7 +326,7 @@
pr_debug("issuing hw ctl reset for ctl:%d\n", ctx->idx);
SDE_REG_WRITE(c, CTL_SW_RESET, 0x1);
- if (sde_hw_ctl_poll_reset_status(ctx, SDE_REG_RESET_TIMEOUT_COUNT))
+ if (sde_hw_ctl_poll_reset_status(ctx, SDE_REG_RESET_TIMEOUT_US))
return -EINVAL;
return 0;
@@ -344,7 +343,7 @@
return 0;
pr_debug("hw ctl reset is set for ctl:%d\n", ctx->idx);
- if (sde_hw_ctl_poll_reset_status(ctx, SDE_REG_RESET_TIMEOUT_COUNT)) {
+ if (sde_hw_ctl_poll_reset_status(ctx, SDE_REG_RESET_TIMEOUT_US)) {
pr_err("hw recovery is not complete for ctl:%d\n", ctx->idx);
return -EINVAL;
}
diff --git a/drivers/gpu/msm/adreno_snapshot.c b/drivers/gpu/msm/adreno_snapshot.c
index 0840aba..f608927 100644
--- a/drivers/gpu/msm/adreno_snapshot.c
+++ b/drivers/gpu/msm/adreno_snapshot.c
@@ -837,7 +837,8 @@
snapshot_frozen_objsize = 0;
- setup_fault_process(device, snapshot,
+ if (!IS_ERR(context))
+ setup_fault_process(device, snapshot,
context ? context->proc_priv : NULL);
/* Add GPU specific sections - registers mainly, but other stuff too */
diff --git a/drivers/gpu/msm/kgsl_gmu.c b/drivers/gpu/msm/kgsl_gmu.c
index 2ddb082..9b04543 100644
--- a/drivers/gpu/msm/kgsl_gmu.c
+++ b/drivers/gpu/msm/kgsl_gmu.c
@@ -1364,7 +1364,7 @@
/* Wait for the NMI to be handled */
wmb();
udelay(100);
- kgsl_device_snapshot(device, NULL);
+ kgsl_device_snapshot(device, ERR_PTR(-EINVAL));
adreno_write_gmureg(adreno_dev,
ADRENO_REG_GMU_GMU2HOST_INTR_CLR, 0xFFFFFFFF);
diff --git a/drivers/gpu/msm/kgsl_snapshot.c b/drivers/gpu/msm/kgsl_snapshot.c
index 7cbda72..e704db7 100644
--- a/drivers/gpu/msm/kgsl_snapshot.c
+++ b/drivers/gpu/msm/kgsl_snapshot.c
@@ -182,7 +182,8 @@
context = kgsl_context_get(device, header->current_context);
/* Get the current PT base */
- header->ptbase = kgsl_mmu_get_current_ttbr0(&device->mmu);
+ if (!IS_ERR(priv))
+ header->ptbase = kgsl_mmu_get_current_ttbr0(&device->mmu);
/* And the PID for the task leader */
if (context) {
@@ -633,8 +634,10 @@
snapshot->size += sizeof(*header);
/* Build the Linux specific header */
+ /* Context err is implied a GMU fault, so limit dump */
kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_OS,
- snapshot, snapshot_os, NULL);
+ snapshot, snapshot_os,
+ IS_ERR(context) ? context : NULL);
/* Get the device specific sections */
if (device->ftbl->snapshot)
diff --git a/drivers/mailbox/mailbox.c b/drivers/mailbox/mailbox.c
index ecb77cc..9f340bf 100644
--- a/drivers/mailbox/mailbox.c
+++ b/drivers/mailbox/mailbox.c
@@ -296,8 +296,9 @@
EXPORT_SYMBOL_GPL(mbox_send_message);
/**
- * mbox_send_controller_data- For client to submit a message to be
- * sent only to the controller.
+ * mbox_write_controller_data - For client to submit a message to be
+ * written to the controller but not sent to
+ * the remote processor.
* @chan: Mailbox channel assigned to this client.
* @mssg: Client specific message typecasted.
*
@@ -308,7 +309,7 @@
* or transmission over chan (blocking mode).
* Negative value denotes failure.
*/
-int mbox_send_controller_data(struct mbox_chan *chan, void *mssg)
+int mbox_write_controller_data(struct mbox_chan *chan, void *mssg)
{
unsigned long flags;
int err;
@@ -317,12 +318,12 @@
return -EINVAL;
spin_lock_irqsave(&chan->lock, flags);
- err = chan->mbox->ops->send_controller_data(chan, mssg);
+ err = chan->mbox->ops->write_controller_data(chan, mssg);
spin_unlock_irqrestore(&chan->lock, flags);
return err;
}
-EXPORT_SYMBOL(mbox_send_controller_data);
+EXPORT_SYMBOL(mbox_write_controller_data);
bool mbox_controller_is_idle(struct mbox_chan *chan)
{
diff --git a/drivers/mailbox/qcom-rpmh-mailbox.c b/drivers/mailbox/qcom-rpmh-mailbox.c
index a69fe85..7bf8a18 100644
--- a/drivers/mailbox/qcom-rpmh-mailbox.c
+++ b/drivers/mailbox/qcom-rpmh-mailbox.c
@@ -1075,7 +1075,7 @@
static const struct mbox_chan_ops mbox_ops = {
.send_data = chan_tcs_write,
- .send_controller_data = chan_tcs_ctrl_write,
+ .write_controller_data = chan_tcs_ctrl_write,
.startup = chan_init,
.shutdown = chan_shutdown,
};
diff --git a/drivers/media/platform/msm/vidc/msm_vdec.c b/drivers/media/platform/msm/vidc/msm_vdec.c
index 56e7a99..cb03576 100644
--- a/drivers/media/platform/msm/vidc/msm_vdec.c
+++ b/drivers/media/platform/msm/vidc/msm_vdec.c
@@ -581,6 +581,13 @@
inst->prop.width[CAPTURE_PORT] = f->fmt.pix_mp.width;
inst->prop.height[CAPTURE_PORT] = f->fmt.pix_mp.height;
+ rc = msm_vidc_check_session_supported(inst);
+ if (rc) {
+ dprintk(VIDC_ERR,
+ "%s: session not supported\n", __func__);
+ goto err_invalid_fmt;
+ }
+
msm_comm_set_color_format(inst,
msm_comm_get_hal_output_buffer(inst),
f->fmt.pix_mp.pixelformat);
@@ -648,6 +655,12 @@
}
inst->prop.width[OUTPUT_PORT] = f->fmt.pix_mp.width;
inst->prop.height[OUTPUT_PORT] = f->fmt.pix_mp.height;
+ rc = msm_vidc_check_session_supported(inst);
+ if (rc) {
+ dprintk(VIDC_ERR,
+ "%s: session not supported\n", __func__);
+ goto err_invalid_fmt;
+ }
frame_sz.buffer_type = HAL_BUFFER_INPUT;
frame_sz.width = inst->prop.width[OUTPUT_PORT];
diff --git a/drivers/media/platform/msm/vidc/msm_venc.c b/drivers/media/platform/msm/vidc/msm_venc.c
index dfb2ad5..0d8cb76 100644
--- a/drivers/media/platform/msm/vidc/msm_venc.c
+++ b/drivers/media/platform/msm/vidc/msm_venc.c
@@ -2385,6 +2385,12 @@
inst->prop.width[CAPTURE_PORT] = f->fmt.pix_mp.width;
inst->prop.height[CAPTURE_PORT] = f->fmt.pix_mp.height;
+ rc = msm_vidc_check_session_supported(inst);
+ if (rc) {
+ dprintk(VIDC_ERR,
+ "%s: session not supported\n", __func__);
+ goto exit;
+ }
frame_sz.buffer_type = HAL_BUFFER_OUTPUT;
frame_sz.width = inst->prop.width[CAPTURE_PORT];
@@ -2443,6 +2449,12 @@
inst->prop.width[OUTPUT_PORT] = f->fmt.pix_mp.width;
inst->prop.height[OUTPUT_PORT] = f->fmt.pix_mp.height;
+ rc = msm_vidc_check_session_supported(inst);
+ if (rc) {
+ dprintk(VIDC_ERR,
+ "%s: session not supported\n", __func__);
+ goto exit;
+ }
frame_sz.buffer_type = HAL_BUFFER_INPUT;
frame_sz.width = inst->prop.width[OUTPUT_PORT];
diff --git a/drivers/media/platform/msm/vidc/msm_vidc.c b/drivers/media/platform/msm/vidc/msm_vidc.c
index 6a7588c..5149086 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc.c
@@ -883,6 +883,13 @@
goto fail_start;
}
+ rc = msm_vidc_check_scaling_supported(inst);
+ if (rc) {
+ dprintk(VIDC_ERR,
+ "This session scaling is not supported %pK\n", inst);
+ goto fail_start;
+ }
+
/* Decide work mode for current session */
rc = msm_vidc_decide_work_mode(inst);
if (rc) {
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.c b/drivers/media/platform/msm/vidc/msm_vidc_common.c
index 428bf71..6e29c53 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_common.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_common.c
@@ -2161,6 +2161,7 @@
"Got SYS_ERR but unable to identify core\n");
return;
}
+ hdev = core->device;
mutex_lock(&core->lock);
if (core->state == VIDC_CORE_UNINIT) {
@@ -2181,7 +2182,6 @@
msm_vidc_queue_v4l2_event(inst, V4L2_EVENT_MSM_VIDC_SYS_ERROR);
msm_comm_print_inst_info(inst);
}
- hdev = core->device;
dprintk(VIDC_DBG, "Calling core_release\n");
rc = call_hfi_op(hdev, core_release, hdev->hfi_device_data);
if (rc) {
@@ -3011,6 +3011,23 @@
return msm_vidc_deinit_core(inst);
}
+static int msm_comm_session_init_done(int flipped_state,
+ struct msm_vidc_inst *inst)
+{
+ int rc;
+
+ dprintk(VIDC_DBG, "inst %pK: waiting for session init done\n", inst);
+ rc = wait_for_state(inst, flipped_state, MSM_VIDC_OPEN_DONE,
+ HAL_SESSION_INIT_DONE);
+ if (rc) {
+ dprintk(VIDC_ERR, "Session init failed for inst %pK\n", inst);
+ msm_comm_generate_sys_error(inst);
+ return rc;
+ }
+
+ return rc;
+}
+
static int msm_comm_session_init(int flipped_state,
struct msm_vidc_inst *inst)
{
@@ -3693,8 +3710,7 @@
if (rc || state <= get_flipped_state(inst->state, state))
break;
case MSM_VIDC_OPEN_DONE:
- rc = wait_for_state(inst, flipped_state, MSM_VIDC_OPEN_DONE,
- HAL_SESSION_INIT_DONE);
+ rc = msm_comm_session_init_done(flipped_state, inst);
if (rc || state <= get_flipped_state(inst->state, state))
break;
case MSM_VIDC_LOAD_RESOURCES:
@@ -5472,10 +5488,6 @@
capability->width.max, capability->height.max);
rc = -ENOTSUPP;
}
-
- if (!rc && msm_vidc_check_scaling_supported(inst)) {
- rc = -ENOTSUPP;
- }
}
if (rc) {
dprintk(VIDC_ERR,
diff --git a/drivers/media/platform/msm/vidc/venus_hfi.c b/drivers/media/platform/msm/vidc/venus_hfi.c
index c94da61..dde6029 100644
--- a/drivers/media/platform/msm/vidc/venus_hfi.c
+++ b/drivers/media/platform/msm/vidc/venus_hfi.c
@@ -1047,9 +1047,9 @@
mutex_lock(&device->lock);
- if (device->power_enabled) {
- dprintk(VIDC_DBG, "Venus is busy\n");
- rc = -EBUSY;
+ if (!device->power_enabled) {
+ dprintk(VIDC_WARN, "%s: venus power off\n", __func__);
+ rc = -EINVAL;
goto exit;
}
__flush_debug_queue(device, NULL);
diff --git a/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c b/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c
index f06fb1f..2ecbd22 100644
--- a/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c
+++ b/drivers/pinctrl/qcom/pinctrl-spmi-gpio.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2014, 2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2014, 2016-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
@@ -471,6 +471,7 @@
pad = pctldev->desc->pins[pin].drv_data;
+ pad->is_enabled = true;
for (i = 0; i < nconfs; i++) {
param = pinconf_to_config_param(configs[i]);
arg = pinconf_to_config_argument(configs[i]);
@@ -619,6 +620,10 @@
return ret;
}
+ val = pad->is_enabled << PMIC_GPIO_REG_MASTER_EN_SHIFT;
+
+ ret = pmic_gpio_write(state, pad, PMIC_GPIO_REG_EN_CTL, val);
+
return ret;
}
diff --git a/drivers/power/supply/qcom/smb-lib.c b/drivers/power/supply/qcom/smb-lib.c
index 48e689f..aad7924 100644
--- a/drivers/power/supply/qcom/smb-lib.c
+++ b/drivers/power/supply/qcom/smb-lib.c
@@ -3642,6 +3642,37 @@
}
}
+static void smblib_notify_extcon_props(struct smb_charger *chg, int id)
+{
+ union extcon_property_value val;
+ union power_supply_propval prop_val;
+
+ smblib_get_prop_typec_cc_orientation(chg, &prop_val);
+ val.intval = ((prop_val.intval == 2) ? 1 : 0);
+ extcon_set_property(chg->extcon, id,
+ EXTCON_PROP_USB_TYPEC_POLARITY, val);
+
+ val.intval = true;
+ extcon_set_property(chg->extcon, id,
+ EXTCON_PROP_USB_SS, val);
+}
+
+static void smblib_notify_device_mode(struct smb_charger *chg, bool enable)
+{
+ if (enable)
+ smblib_notify_extcon_props(chg, EXTCON_USB);
+
+ extcon_set_state_sync(chg->extcon, EXTCON_USB, enable);
+}
+
+static void smblib_notify_usb_host(struct smb_charger *chg, bool enable)
+{
+ if (enable)
+ smblib_notify_extcon_props(chg, EXTCON_USB_HOST);
+
+ extcon_set_state_sync(chg->extcon, EXTCON_USB_HOST, enable);
+}
+
#define HVDCP_DET_MS 2500
static void smblib_handle_apsd_done(struct smb_charger *chg, bool rising)
{
@@ -3664,6 +3695,8 @@
/* if not DCP then no hvdcp timeout happens. Enable pd here */
vote(chg->pd_disallowed_votable_indirect, HVDCP_TIMEOUT_VOTER,
false, 0);
+ if (chg->use_extcon)
+ smblib_notify_device_mode(chg, true);
break;
case OCP_CHARGER_BIT:
case FLOAT_CHARGER_BIT:
@@ -3749,6 +3782,10 @@
*/
vote(chg->pd_disallowed_votable_indirect, HVDCP_TIMEOUT_VOTER,
false, 0);
+ if (chg->use_extcon) {
+ smblib_notify_usb_host(chg, true);
+ chg->otg_present = true;
+ }
}
static void typec_sink_removal(struct smb_charger *chg)
@@ -3899,6 +3936,14 @@
typec_sink_removal(chg);
smblib_update_usb_type(chg);
+
+ if (chg->use_extcon) {
+ if (chg->otg_present)
+ smblib_notify_usb_host(chg, false);
+ else
+ smblib_notify_device_mode(chg, false);
+ }
+ chg->otg_present = false;
}
static void smblib_handle_typec_insertion(struct smb_charger *chg)
diff --git a/drivers/power/supply/qcom/smb-lib.h b/drivers/power/supply/qcom/smb-lib.h
index 704a8db..5251b6f 100644
--- a/drivers/power/supply/qcom/smb-lib.h
+++ b/drivers/power/supply/qcom/smb-lib.h
@@ -144,6 +144,9 @@
EXTCON_NONE,
};
+/* EXTCON_USB and EXTCON_USB_HOST are mutually exclusive */
+static const u32 smblib_extcon_exclusive[] = {0x3, 0};
+
struct smb_regulator {
struct regulator_dev *rdev;
struct regulator_desc rdesc;
@@ -331,6 +334,8 @@
int usb_icl_change_irq_enabled;
u32 jeita_status;
u8 float_cfg;
+ bool use_extcon;
+ bool otg_present;
/* workaround flag */
u32 wa_flags;
diff --git a/drivers/power/supply/qcom/smb138x-charger.c b/drivers/power/supply/qcom/smb138x-charger.c
index 911dd69..e0c92c6 100644
--- a/drivers/power/supply/qcom/smb138x-charger.c
+++ b/drivers/power/supply/qcom/smb138x-charger.c
@@ -170,6 +170,9 @@
chip->dt.suspend_input = of_property_read_bool(node,
"qcom,suspend-input");
+ chg->use_extcon = of_property_read_bool(node,
+ "qcom,use-extcon");
+
rc = of_property_read_u32(node,
"qcom,fcc-max-ua", &chip->dt.fcc_ua);
if (rc < 0)
@@ -1405,55 +1408,95 @@
rc = smb138x_parse_dt(chip);
if (rc < 0) {
pr_err("Couldn't parse device tree rc=%d\n", rc);
- return rc;
+ goto cleanup;
}
rc = smb138x_init_vbus_regulator(chip);
if (rc < 0) {
pr_err("Couldn't initialize vbus regulator rc=%d\n",
rc);
- return rc;
+ goto cleanup;
}
rc = smb138x_init_vconn_regulator(chip);
if (rc < 0) {
pr_err("Couldn't initialize vconn regulator rc=%d\n",
rc);
- return rc;
+ goto cleanup;
+ }
+
+ if (chg->use_extcon) {
+ /* extcon registration */
+ chg->extcon = devm_extcon_dev_allocate(chg->dev,
+ smblib_extcon_cable);
+ if (IS_ERR(chg->extcon)) {
+ rc = PTR_ERR(chg->extcon);
+ dev_err(chg->dev, "failed to allocate extcon device rc=%d\n",
+ rc);
+ goto cleanup;
+ }
+
+ chg->extcon->mutually_exclusive = smblib_extcon_exclusive;
+ rc = devm_extcon_dev_register(chg->dev, chg->extcon);
+ if (rc < 0) {
+ dev_err(chg->dev, "failed to register extcon device rc=%d\n",
+ rc);
+ goto cleanup;
+ }
+
+ /* Support reporting polarity and speed via properties */
+ rc = extcon_set_property_capability(chg->extcon,
+ EXTCON_USB, EXTCON_PROP_USB_TYPEC_POLARITY);
+ rc |= extcon_set_property_capability(chg->extcon,
+ EXTCON_USB, EXTCON_PROP_USB_SS);
+ rc |= extcon_set_property_capability(chg->extcon,
+ EXTCON_USB_HOST,
+ EXTCON_PROP_USB_TYPEC_POLARITY);
+ rc |= extcon_set_property_capability(chg->extcon,
+ EXTCON_USB_HOST, EXTCON_PROP_USB_SS);
+ if (rc < 0) {
+ dev_err(chg->dev,
+ "failed to configure extcon capabilities\n");
+ goto cleanup;
+ }
}
rc = smb138x_init_usb_psy(chip);
if (rc < 0) {
pr_err("Couldn't initialize usb psy rc=%d\n", rc);
- return rc;
+ goto cleanup;
}
rc = smb138x_init_batt_psy(chip);
if (rc < 0) {
pr_err("Couldn't initialize batt psy rc=%d\n", rc);
- return rc;
+ goto cleanup;
}
rc = smb138x_init_hw(chip);
if (rc < 0) {
pr_err("Couldn't initialize hardware rc=%d\n", rc);
- return rc;
+ goto cleanup;
}
rc = smb138x_determine_initial_status(chip);
if (rc < 0) {
pr_err("Couldn't determine initial status rc=%d\n",
rc);
- return rc;
+ goto cleanup;
}
rc = smb138x_request_interrupts(chip);
if (rc < 0) {
pr_err("Couldn't request interrupts rc=%d\n", rc);
- return rc;
+ goto cleanup;
}
return rc;
+
+cleanup:
+ smblib_deinit(chg);
+ return rc;
}
static int smb138x_slave_probe(struct smb138x *chip)
diff --git a/drivers/soc/qcom/gladiator_erp.c b/drivers/soc/qcom/gladiator_erp.c
index 835d4b0..3b70ca4 100644
--- a/drivers/soc/qcom/gladiator_erp.c
+++ b/drivers/soc/qcom/gladiator_erp.c
@@ -163,6 +163,7 @@
DISCONNECT_ERROR,
DIRECTORY_ERROR,
PARITY_ERROR,
+ PHYSICAL_ADDRESS_ERROR,
};
static void clear_gladiator_error(void __iomem *gladiator_virt_base,
@@ -200,12 +201,14 @@
static inline void print_gld_errtype(unsigned int errtype)
{
+ char *errors = "Disconnect, Directory, Parity, Physical address";
+
if (errtype == 0)
pr_alert("Error type: Snoop data transfer\n");
else if (errtype == 1)
pr_alert("Error type: DVM error\n");
else if (errtype == 3)
- pr_alert("Error type: Disconnect, directory, or parity error\n");
+ pr_alert("Error type: %s\n", errors);
else
pr_alert("Error type: Unknown; value:%u\n", errtype);
}
@@ -288,7 +291,7 @@
log_err_type = (err_reg5 & mask_shifts->gld_errlog5_error_type_mask)
>> mask_shifts->gld_errlog5_error_type_shift;
- for (i = 0 ; i <= 6 ; i++) {
+ for (i = 0 ; i <= 7 ; i++) {
value = log_err_type & 0x1;
switch (i) {
case DATA_TRANSFER_ERROR:
@@ -337,7 +340,14 @@
mask_shifts);
decode_index_parity(err_reg5, mask_shifts);
break;
+ case PHYSICAL_ADDRESS_ERROR:
+ if (value == 0)
+ continue;
+ pr_alert("Error type: Physical address error\n");
+ pr_alert("Address is greater than SoC address range\n");
+ break;
}
+
log_err_type = log_err_type >> 1;
}
}
diff --git a/drivers/soc/qcom/rpmh.c b/drivers/soc/qcom/rpmh.c
index f4c35ab..f7902e1 100644
--- a/drivers/soc/qcom/rpmh.c
+++ b/drivers/soc/qcom/rpmh.c
@@ -563,7 +563,7 @@
spin_lock_irqsave(&rpm->lock, flags);
for (i = 0; rpm->passthru_cache[i]; i++) {
rpm_msg = rpm->passthru_cache[i];
- ret = mbox_send_controller_data(rc->chan, &rpm_msg->msg);
+ ret = mbox_write_controller_data(rc->chan, &rpm_msg->msg);
if (ret)
goto fail;
}
@@ -762,7 +762,7 @@
rpm_msg.msg.is_control = true;
rpm_msg.msg.is_complete = false;
- return mbox_send_controller_data(rc->chan, &rpm_msg.msg);
+ return mbox_write_controller_data(rc->chan, &rpm_msg.msg);
}
EXPORT_SYMBOL(rpmh_write_control);
@@ -797,7 +797,7 @@
rpm->dirty = true;
spin_unlock_irqrestore(&rpm->lock, flags);
- return mbox_send_controller_data(rc->chan, &rpm_msg.msg);
+ return mbox_write_controller_data(rc->chan, &rpm_msg.msg);
}
EXPORT_SYMBOL(rpmh_invalidate);
@@ -886,7 +886,7 @@
rpm_msg.msg.num_payload = 1;
rpm_msg.msg.is_complete = false;
- return mbox_send_controller_data(rc->chan, &rpm_msg.msg);
+ return mbox_write_controller_data(rc->chan, &rpm_msg.msg);
}
/**
diff --git a/include/linux/mailbox_client.h b/include/linux/mailbox_client.h
index 86a2dc6..073391b 100644
--- a/include/linux/mailbox_client.h
+++ b/include/linux/mailbox_client.h
@@ -44,7 +44,7 @@
const char *name);
struct mbox_chan *mbox_request_channel(struct mbox_client *cl, int index);
int mbox_send_message(struct mbox_chan *chan, void *mssg);
-int mbox_send_controller_data(struct mbox_chan *chan, void *mssg);
+int mbox_write_controller_data(struct mbox_chan *chan, void *mssg);
void mbox_client_txdone(struct mbox_chan *chan, int r); /* atomic */
bool mbox_client_peek_data(struct mbox_chan *chan); /* atomic */
void mbox_free_channel(struct mbox_chan *chan); /* may sleep */
diff --git a/include/linux/mailbox_controller.h b/include/linux/mailbox_controller.h
index 7827c68..751b354 100644
--- a/include/linux/mailbox_controller.h
+++ b/include/linux/mailbox_controller.h
@@ -24,8 +24,8 @@
* transmission of data is reported by the controller via
* mbox_chan_txdone (if it has some TX ACK irq). It must not
* sleep.
- * @send_controller_data:
- * Send data for the controller driver. This could be data to
+ * @write_controller_data:
+ * Write data for the controller driver. This could be data to
* configure the controller or data that may be cached in the
* controller and not transmitted immediately. There is no ACK
* for this request and the request is not buffered in the
@@ -54,7 +54,7 @@
*/
struct mbox_chan_ops {
int (*send_data)(struct mbox_chan *chan, void *data);
- int (*send_controller_data)(struct mbox_chan *chan, void *data);
+ int (*write_controller_data)(struct mbox_chan *chan, void *data);
int (*startup)(struct mbox_chan *chan);
void (*shutdown)(struct mbox_chan *chan);
bool (*last_tx_done)(struct mbox_chan *chan);
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index ed0099c9..07e1acb 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -158,7 +158,6 @@
NR_UNEVICTABLE, /* " " " " " */
NR_ISOLATED_ANON, /* Temporary isolated pages from anon lru */
NR_ISOLATED_FILE, /* Temporary isolated pages from file lru */
- NR_PAGES_SCANNED, /* pages scanned since last reclaim */
WORKINGSET_REFAULT,
WORKINGSET_ACTIVATE,
WORKINGSET_NODERECLAIM,
@@ -645,6 +644,8 @@
int kswapd_order;
enum zone_type kswapd_classzone_idx;
+ int kswapd_failures; /* Number of 'reclaimed == 0' runs */
+
#ifdef CONFIG_COMPACTION
int kcompactd_max_order;
enum zone_type kcompactd_classzone_idx;
diff --git a/include/net/fib_rules.h b/include/net/fib_rules.h
index 261202f..8dbfdf7 100644
--- a/include/net/fib_rules.h
+++ b/include/net/fib_rules.h
@@ -95,8 +95,6 @@
[FRA_FWMARK] = { .type = NLA_U32 }, \
[FRA_FWMASK] = { .type = NLA_U32 }, \
[FRA_TABLE] = { .type = NLA_U32 }, \
- [FRA_UID_START] = { .type = NLA_U32 }, \
- [FRA_UID_END] = { .type = NLA_U32 }, \
[FRA_SUPPRESS_PREFIXLEN] = { .type = NLA_U32 }, \
[FRA_SUPPRESS_IFGROUP] = { .type = NLA_U32 }, \
[FRA_GOTO] = { .type = NLA_U32 }, \
diff --git a/include/trace/events/vmscan.h b/include/trace/events/vmscan.h
index c88fd09..2f8536b 100644
--- a/include/trace/events/vmscan.h
+++ b/include/trace/events/vmscan.h
@@ -269,23 +269,24 @@
__entry->retval)
);
-DECLARE_EVENT_CLASS(mm_vmscan_lru_isolate_template,
-
+TRACE_EVENT(mm_vmscan_lru_isolate,
TP_PROTO(int classzone_idx,
int order,
unsigned long nr_requested,
unsigned long nr_scanned,
+ unsigned long nr_skipped,
unsigned long nr_taken,
isolate_mode_t isolate_mode,
int file),
- TP_ARGS(classzone_idx, order, nr_requested, nr_scanned, nr_taken, isolate_mode, file),
+ TP_ARGS(classzone_idx, order, nr_requested, nr_scanned, nr_skipped, nr_taken, isolate_mode, file),
TP_STRUCT__entry(
__field(int, classzone_idx)
__field(int, order)
__field(unsigned long, nr_requested)
__field(unsigned long, nr_scanned)
+ __field(unsigned long, nr_skipped)
__field(unsigned long, nr_taken)
__field(isolate_mode_t, isolate_mode)
__field(int, file)
@@ -296,49 +297,23 @@
__entry->order = order;
__entry->nr_requested = nr_requested;
__entry->nr_scanned = nr_scanned;
+ __entry->nr_skipped = nr_skipped;
__entry->nr_taken = nr_taken;
__entry->isolate_mode = isolate_mode;
__entry->file = file;
),
- TP_printk("isolate_mode=%d classzone=%d order=%d nr_requested=%lu nr_scanned=%lu nr_taken=%lu file=%d",
+ TP_printk("isolate_mode=%d classzone=%d order=%d nr_requested=%lu nr_scanned=%lu nr_skipped=%lu nr_taken=%lu file=%d",
__entry->isolate_mode,
__entry->classzone_idx,
__entry->order,
__entry->nr_requested,
__entry->nr_scanned,
+ __entry->nr_skipped,
__entry->nr_taken,
__entry->file)
);
-DEFINE_EVENT(mm_vmscan_lru_isolate_template, mm_vmscan_lru_isolate,
-
- TP_PROTO(int classzone_idx,
- int order,
- unsigned long nr_requested,
- unsigned long nr_scanned,
- unsigned long nr_taken,
- isolate_mode_t isolate_mode,
- int file),
-
- TP_ARGS(classzone_idx, order, nr_requested, nr_scanned, nr_taken, isolate_mode, file)
-
-);
-
-DEFINE_EVENT(mm_vmscan_lru_isolate_template, mm_vmscan_memcg_isolate,
-
- TP_PROTO(int classzone_idx,
- int order,
- unsigned long nr_requested,
- unsigned long nr_scanned,
- unsigned long nr_taken,
- isolate_mode_t isolate_mode,
- int file),
-
- TP_ARGS(classzone_idx, order, nr_requested, nr_scanned, nr_taken, isolate_mode, file)
-
-);
-
TRACE_EVENT(mm_vmscan_writepage,
TP_PROTO(struct page *page),
diff --git a/include/uapi/linux/fib_rules.h b/include/uapi/linux/fib_rules.h
index a66c4ba..bbf02a6 100644
--- a/include/uapi/linux/fib_rules.h
+++ b/include/uapi/linux/fib_rules.h
@@ -54,8 +54,6 @@
FRA_TABLE, /* Extended table id */
FRA_FWMASK, /* mask for netfilter mark */
FRA_OIFNAME,
- FRA_UID_START, /* UID range */
- FRA_UID_END,
FRA_PAD,
FRA_L3MDEV, /* iif or oif is l3mdev goto its table */
FRA_UID_RANGE, /* UID range */
diff --git a/mm/internal.h b/mm/internal.h
index 537ac99..df6319f 100644
--- a/mm/internal.h
+++ b/mm/internal.h
@@ -74,11 +74,16 @@
extern unsigned long highest_memmap_pfn;
/*
+ * Maximum number of reclaim retries without progress before the OOM
+ * killer is consider the only way forward.
+ */
+#define MAX_RECLAIM_RETRIES 16
+
+/*
* in mm/vmscan.c:
*/
extern int isolate_lru_page(struct page *page);
extern void putback_lru_page(struct page *page);
-extern bool pgdat_reclaimable(struct pglist_data *pgdat);
/*
* in mm/rmap.c:
diff --git a/mm/migrate.c b/mm/migrate.c
index f0b786d..4213d27 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -1738,9 +1738,6 @@
{
int z;
- if (!pgdat_reclaimable(pgdat))
- return false;
-
for (z = pgdat->nr_zones - 1; z >= 0; z--) {
struct zone *zone = pgdat->node_zones + z;
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 44085b2..3eb5f68 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -1099,14 +1099,10 @@
{
int migratetype = 0;
int batch_free = 0;
- unsigned long nr_scanned;
bool isolated_pageblocks;
spin_lock(&zone->lock);
isolated_pageblocks = has_isolate_pageblock(zone);
- nr_scanned = node_page_state(zone->zone_pgdat, NR_PAGES_SCANNED);
- if (nr_scanned)
- __mod_node_page_state(zone->zone_pgdat, NR_PAGES_SCANNED, -nr_scanned);
while (count) {
struct page *page;
@@ -1159,12 +1155,7 @@
unsigned int order,
int migratetype)
{
- unsigned long nr_scanned;
spin_lock(&zone->lock);
- nr_scanned = node_page_state(zone->zone_pgdat, NR_PAGES_SCANNED);
- if (nr_scanned)
- __mod_node_page_state(zone->zone_pgdat, NR_PAGES_SCANNED, -nr_scanned);
-
if (unlikely(has_isolate_pageblock(zone) ||
is_migrate_isolate(migratetype))) {
migratetype = get_pfnblock_migratetype(page, pfn);
@@ -3501,19 +3492,12 @@
}
/*
- * Maximum number of reclaim retries without any progress before OOM killer
- * is consider as the only way to move forward.
- */
-#define MAX_RECLAIM_RETRIES 16
-
-/*
* Checks whether it makes sense to retry the reclaim to make a forward progress
* for the given allocation request.
- * The reclaim feedback represented by did_some_progress (any progress during
- * the last reclaim round) and no_progress_loops (number of reclaim rounds without
- * any progress in a row) is considered as well as the reclaimable pages on the
- * applicable zone list (with a backoff mechanism which is a function of
- * no_progress_loops).
+ *
+ * We give up when we either have tried MAX_RECLAIM_RETRIES in a row
+ * without success, or when we couldn't even meet the watermark if we
+ * reclaimed all remaining pages on the LRU lists.
*
* Returns true if a retry is viable or false to enter the oom path.
*/
@@ -3556,13 +3540,11 @@
unsigned long reclaimable;
available = reclaimable = zone_reclaimable_pages(zone);
- available -= DIV_ROUND_UP((*no_progress_loops) * available,
- MAX_RECLAIM_RETRIES);
available += zone_page_state_snapshot(zone, NR_FREE_PAGES);
/*
- * Would the allocation succeed if we reclaimed the whole
- * available?
+ * Would the allocation succeed if we reclaimed all
+ * reclaimable pages?
*/
if (__zone_watermark_ok(zone, order, min_wmark_pages(zone),
ac_classzone_idx(ac), alloc_flags, available)) {
@@ -4442,7 +4424,6 @@
#endif
" writeback_tmp:%lukB"
" unstable:%lukB"
- " pages_scanned:%lu"
" all_unreclaimable? %s"
"\n",
pgdat->node_id,
@@ -4465,8 +4446,8 @@
#endif
K(node_page_state(pgdat, NR_WRITEBACK_TEMP)),
K(node_page_state(pgdat, NR_UNSTABLE_NFS)),
- node_page_state(pgdat, NR_PAGES_SCANNED),
- !pgdat_reclaimable(pgdat) ? "yes" : "no");
+ pgdat->kswapd_failures >= MAX_RECLAIM_RETRIES ?
+ "yes" : "no");
}
for_each_populated_zone(zone) {
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 7b5848cf..ecd6c359 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -235,12 +235,6 @@
return nr;
}
-bool pgdat_reclaimable(struct pglist_data *pgdat)
-{
- return node_page_state_snapshot(pgdat, NR_PAGES_SCANNED) <
- pgdat_reclaimable_pages(pgdat) * 6;
-}
-
/**
* lruvec_lru_size - Returns the number of pages on the given LRU list.
* @lruvec: lru vector
@@ -1514,11 +1508,12 @@
unsigned long nr_taken = 0;
unsigned long nr_zone_taken[MAX_NR_ZONES] = { 0 };
unsigned long nr_skipped[MAX_NR_ZONES] = { 0, };
+ unsigned long skipped = 0;
unsigned long scan, nr_pages;
LIST_HEAD(pages_skipped);
for (scan = 0; scan < nr_to_scan && nr_taken < nr_to_scan &&
- !list_empty(src);) {
+ !list_empty(src); scan++) {
struct page *page;
page = lru_to_page(src);
@@ -1532,12 +1527,6 @@
continue;
}
- /*
- * Account for scanned and skipped separetly to avoid the pgdat
- * being prematurely marked unreclaimable by pgdat_reclaimable.
- */
- scan++;
-
switch (__isolate_lru_page(page, mode)) {
case 0:
nr_pages = hpage_nr_pages(page);
@@ -1565,28 +1554,20 @@
*/
if (!list_empty(&pages_skipped)) {
int zid;
- unsigned long total_skipped = 0;
+ list_splice(&pages_skipped, src);
for (zid = 0; zid < MAX_NR_ZONES; zid++) {
if (!nr_skipped[zid])
continue;
__count_zid_vm_events(PGSCAN_SKIP, zid, nr_skipped[zid]);
- total_skipped += nr_skipped[zid];
+ skipped += nr_skipped[zid];
}
-
- /*
- * Account skipped pages as a partial scan as the pgdat may be
- * close to unreclaimable. If the LRU list is empty, account
- * skipped pages as a full scan.
- */
- scan += list_empty(src) ? total_skipped : total_skipped >> 2;
-
- list_splice(&pages_skipped, src);
}
*nr_scanned = scan;
- trace_mm_vmscan_lru_isolate(sc->reclaim_idx, sc->order, nr_to_scan, scan,
- nr_taken, mode, is_file_lru(lru));
+ trace_mm_vmscan_lru_isolate(sc->reclaim_idx, sc->order, nr_to_scan,
+ scan, skipped, nr_taken, mode,
+ is_file_lru(lru));
update_lru_sizes(lruvec, lru, nr_zone_taken);
return nr_taken;
}
@@ -1849,7 +1830,6 @@
reclaim_stat->recent_scanned[file] += nr_taken;
if (global_reclaim(sc)) {
- __mod_node_page_state(pgdat, NR_PAGES_SCANNED, nr_scanned);
if (current_is_kswapd())
__count_vm_events(PGSCAN_KSWAPD, nr_scanned);
else
@@ -2038,8 +2018,6 @@
__mod_node_page_state(pgdat, NR_ISOLATED_ANON + file, nr_taken);
reclaim_stat->recent_scanned[file] += nr_taken;
- if (global_reclaim(sc))
- __mod_node_page_state(pgdat, NR_PAGES_SCANNED, nr_scanned);
__count_vm_events(PGREFILL, nr_scanned);
spin_unlock_irq(&pgdat->lru_lock);
@@ -2199,30 +2177,8 @@
unsigned long anon_prio, file_prio;
enum scan_balance scan_balance;
unsigned long anon, file;
- bool force_scan = false;
unsigned long ap, fp;
enum lru_list lru;
- bool some_scanned;
- int pass;
-
- /*
- * If the zone or memcg is small, nr[l] can be 0. This
- * results in no scanning on this priority and a potential
- * priority drop. Global direct reclaim can go to the next
- * zone and tends to have no problems. Global kswapd is for
- * zone balancing and it needs to scan a minimum amount. When
- * reclaiming for a memcg, a priority drop can cause high
- * latencies, so it's better to scan a minimum amount there as
- * well.
- */
- if (current_is_kswapd()) {
- if (!pgdat_reclaimable(pgdat))
- force_scan = true;
- if (!mem_cgroup_online(memcg))
- force_scan = true;
- }
- if (!global_reclaim(sc))
- force_scan = true;
/* If we have no swap space, do not bother scanning anon pages. */
if (!sc->may_swap || mem_cgroup_get_nr_swap_pages(memcg) <= 0) {
@@ -2354,55 +2310,48 @@
fraction[1] = fp;
denominator = ap + fp + 1;
out:
- some_scanned = false;
- /* Only use force_scan on second pass. */
- for (pass = 0; !some_scanned && pass < 2; pass++) {
- *lru_pages = 0;
- for_each_evictable_lru(lru) {
- int file = is_file_lru(lru);
- unsigned long size;
- unsigned long scan;
+ *lru_pages = 0;
+ for_each_evictable_lru(lru) {
+ int file = is_file_lru(lru);
+ unsigned long size;
+ unsigned long scan;
- size = lruvec_lru_size(lruvec, lru, sc->reclaim_idx);
- scan = size >> sc->priority;
+ size = lruvec_lru_size(lruvec, lru, sc->reclaim_idx);
+ scan = size >> sc->priority;
+ /*
+ * If the cgroup's already been deleted, make sure to
+ * scrape out the remaining cache.
+ */
+ if (!scan && !mem_cgroup_online(memcg))
+ scan = min(size, SWAP_CLUSTER_MAX);
- if (!scan && pass && force_scan)
- scan = min(size, SWAP_CLUSTER_MAX);
-
- switch (scan_balance) {
- case SCAN_EQUAL:
- /* Scan lists relative to size */
- break;
- case SCAN_FRACT:
- /*
- * Scan types proportional to swappiness and
- * their relative recent reclaim efficiency.
- */
- scan = div64_u64(scan * fraction[file],
- denominator);
- break;
- case SCAN_FILE:
- case SCAN_ANON:
- /* Scan one type exclusively */
- if ((scan_balance == SCAN_FILE) != file) {
- size = 0;
- scan = 0;
- }
- break;
- default:
- /* Look ma, no brain */
- BUG();
- }
-
- *lru_pages += size;
- nr[lru] = scan;
-
+ switch (scan_balance) {
+ case SCAN_EQUAL:
+ /* Scan lists relative to size */
+ break;
+ case SCAN_FRACT:
/*
- * Skip the second pass and don't force_scan,
- * if we found something to scan.
+ * Scan types proportional to swappiness and
+ * their relative recent reclaim efficiency.
*/
- some_scanned |= !!scan;
+ scan = div64_u64(scan * fraction[file],
+ denominator);
+ break;
+ case SCAN_FILE:
+ case SCAN_ANON:
+ /* Scan one type exclusively */
+ if ((scan_balance == SCAN_FILE) != file) {
+ size = 0;
+ scan = 0;
+ }
+ break;
+ default:
+ /* Look ma, no brain */
+ BUG();
}
+
+ *lru_pages += size;
+ nr[lru] = scan;
}
}
@@ -2704,6 +2653,15 @@
} while (should_continue_reclaim(pgdat, sc->nr_reclaimed - nr_reclaimed,
sc->nr_scanned - nr_scanned, sc));
+ /*
+ * Kswapd gives up on balancing particular nodes after too
+ * many failures to reclaim anything from them and goes to
+ * sleep. On reclaim progress, reset the failure counter. A
+ * successful direct reclaim run will revive a dormant kswapd.
+ */
+ if (reclaimable)
+ pgdat->kswapd_failures = 0;
+
return reclaimable;
}
@@ -2778,10 +2736,6 @@
GFP_KERNEL | __GFP_HARDWALL))
continue;
- if (sc->priority != DEF_PRIORITY &&
- !pgdat_reclaimable(zone->zone_pgdat))
- continue; /* Let kswapd poll it */
-
/*
* If we already have plenty of memory free for
* compaction in this zone, don't free any more.
@@ -2918,7 +2872,7 @@
return 0;
}
-static bool pfmemalloc_watermark_ok(pg_data_t *pgdat)
+static bool allow_direct_reclaim(pg_data_t *pgdat)
{
struct zone *zone;
unsigned long pfmemalloc_reserve = 0;
@@ -2926,10 +2880,15 @@
int i;
bool wmark_ok;
+ if (pgdat->kswapd_failures >= MAX_RECLAIM_RETRIES)
+ return true;
+
for (i = 0; i <= ZONE_NORMAL; i++) {
zone = &pgdat->node_zones[i];
- if (!managed_zone(zone) ||
- pgdat_reclaimable_pages(pgdat) == 0)
+ if (!managed_zone(zone))
+ continue;
+
+ if (!zone_reclaimable_pages(zone))
continue;
pfmemalloc_reserve += min_wmark_pages(zone);
@@ -3006,7 +2965,7 @@
/* Throttle based on the first usable node */
pgdat = zone->zone_pgdat;
- if (pfmemalloc_watermark_ok(pgdat))
+ if (allow_direct_reclaim(pgdat))
goto out;
break;
}
@@ -3028,14 +2987,14 @@
*/
if (!(gfp_mask & __GFP_FS)) {
wait_event_interruptible_timeout(pgdat->pfmemalloc_wait,
- pfmemalloc_watermark_ok(pgdat), HZ);
+ allow_direct_reclaim(pgdat), HZ);
goto check_pending;
}
/* Throttle until kswapd wakes the process */
wait_event_killable(zone->zone_pgdat->pfmemalloc_wait,
- pfmemalloc_watermark_ok(pgdat));
+ allow_direct_reclaim(pgdat));
check_pending:
if (fatal_signal_pending(current))
@@ -3198,6 +3157,7 @@
*/
clear_bit(PGDAT_CONGESTED, &zone->zone_pgdat->flags);
clear_bit(PGDAT_DIRTY, &zone->zone_pgdat->flags);
+ clear_bit(PGDAT_WRITEBACK, &zone->zone_pgdat->flags);
return true;
}
@@ -3214,7 +3174,7 @@
/*
* The throttled processes are normally woken up in balance_pgdat() as
- * soon as pfmemalloc_watermark_ok() is true. But there is a potential
+ * soon as allow_direct_reclaim() is true. But there is a potential
* race between when kswapd checks the watermarks and a process gets
* throttled. There is also a potential race if processes get
* throttled, kswapd wakes, a large process exits thereby balancing the
@@ -3228,17 +3188,21 @@
if (waitqueue_active(&pgdat->pfmemalloc_wait))
wake_up_all(&pgdat->pfmemalloc_wait);
+ /* Hopeless node, leave it to direct reclaim */
+ if (pgdat->kswapd_failures >= MAX_RECLAIM_RETRIES)
+ return true;
+
for (i = 0; i <= classzone_idx; i++) {
struct zone *zone = pgdat->node_zones + i;
if (!managed_zone(zone))
continue;
- if (!zone_balanced(zone, order, classzone_idx))
- return false;
+ if (zone_balanced(zone, order, classzone_idx))
+ return true;
}
- return true;
+ return false;
}
/*
@@ -3314,9 +3278,9 @@
count_vm_event(PAGEOUTRUN);
do {
+ unsigned long nr_reclaimed = sc.nr_reclaimed;
bool raise_priority = true;
- sc.nr_reclaimed = 0;
sc.reclaim_idx = classzone_idx;
/*
@@ -3371,7 +3335,7 @@
* If we're getting trouble reclaiming, start doing writepage
* even in laptop mode.
*/
- if (sc.priority < DEF_PRIORITY - 2 || !pgdat_reclaimable(pgdat))
+ if (sc.priority < DEF_PRIORITY - 2)
sc.may_writepage = 1;
/* Call soft limit reclaim before calling shrink_node. */
@@ -3395,7 +3359,7 @@
* able to safely make forward progress. Wake them
*/
if (waitqueue_active(&pgdat->pfmemalloc_wait) &&
- pfmemalloc_watermark_ok(pgdat))
+ allow_direct_reclaim(pgdat))
wake_up_all(&pgdat->pfmemalloc_wait);
/* Check if kswapd should be suspending */
@@ -3406,10 +3370,14 @@
* Raise priority if scanning rate is too low or there was no
* progress in reclaiming pages
*/
- if (raise_priority || !sc.nr_reclaimed)
+ nr_reclaimed = sc.nr_reclaimed - nr_reclaimed;
+ if (raise_priority || !nr_reclaimed)
sc.priority--;
} while (sc.priority >= 1);
+ if (!sc.nr_reclaimed)
+ pgdat->kswapd_failures++;
+
out:
/*
* Return the order kswapd stopped reclaiming at as
@@ -3431,7 +3399,13 @@
prepare_to_wait(&pgdat->kswapd_wait, &wait, TASK_INTERRUPTIBLE);
- /* Try to sleep for a short interval */
+ /*
+ * Try to sleep for a short interval. Note that kcompactd will only be
+ * woken if it is possible to sleep for a short interval. This is
+ * deliberate on the assumption that if reclaim cannot keep an
+ * eligible zone balanced that it's also unlikely that compaction will
+ * succeed.
+ */
if (prepare_kswapd_sleep(pgdat, reclaim_order, classzone_idx)) {
/*
* Compaction records what page blocks it recently failed to
@@ -3609,6 +3583,10 @@
if (!waitqueue_active(&pgdat->kswapd_wait))
return;
+ /* Hopeless node, leave it to direct reclaim */
+ if (pgdat->kswapd_failures >= MAX_RECLAIM_RETRIES)
+ return;
+
/* Only wake kswapd if all zones are unbalanced */
for (z = 0; z <= classzone_idx; z++) {
zone = pgdat->node_zones + z;
@@ -3879,9 +3857,6 @@
sum_zone_node_page_state(pgdat->node_id, NR_SLAB_RECLAIMABLE) <= pgdat->min_slab_pages)
return NODE_RECLAIM_FULL;
- if (!pgdat_reclaimable(pgdat))
- return NODE_RECLAIM_FULL;
-
/*
* Do not scan if the allocation should not be delayed.
*/
diff --git a/mm/vmstat.c b/mm/vmstat.c
index 513c37a..2ab7973 100644
--- a/mm/vmstat.c
+++ b/mm/vmstat.c
@@ -954,7 +954,6 @@
"nr_unevictable",
"nr_isolated_anon",
"nr_isolated_file",
- "nr_pages_scanned",
"workingset_refault",
"workingset_activate",
"workingset_nodereclaim",
@@ -1379,7 +1378,6 @@
"\n min %lu"
"\n low %lu"
"\n high %lu"
- "\n node_scanned %lu"
"\n spanned %lu"
"\n present %lu"
"\n managed %lu",
@@ -1387,7 +1385,6 @@
min_wmark_pages(zone),
low_wmark_pages(zone),
high_wmark_pages(zone),
- node_page_state(zone->zone_pgdat, NR_PAGES_SCANNED),
zone->spanned_pages,
zone->present_pages,
zone->managed_pages);
@@ -1426,7 +1423,7 @@
"\n node_unreclaimable: %u"
"\n start_pfn: %lu"
"\n node_inactive_ratio: %u",
- !pgdat_reclaimable(zone->zone_pgdat),
+ pgdat->kswapd_failures >= MAX_RECLAIM_RETRIES,
zone->zone_start_pfn,
zone->zone_pgdat->inactive_ratio);
seq_putc(m, '\n');
@@ -1588,22 +1585,9 @@
for (i = 0; i < NR_VM_ZONE_STAT_ITEMS; i++) {
val = atomic_long_read(&vm_zone_stat[i]);
if (val < 0) {
- switch (i) {
- case NR_PAGES_SCANNED:
- /*
- * This is often seen to go negative in
- * recent kernels, but not to go permanently
- * negative. Whilst it would be nicer not to
- * have exceptions, rooting them out would be
- * another task, of rather low priority.
- */
- break;
- default:
- pr_warn("%s: %s %ld\n",
- __func__, vmstat_text[i], val);
- err = -EINVAL;
- break;
- }
+ pr_warn("%s: %s %ld\n",
+ __func__, vmstat_text[i], val);
+ err = -EINVAL;
}
}
if (err)