Merge "locking/rwsem-xadd: Fix missed wakeup due to reordering of load"
diff --git a/Documentation/devicetree/bindings/arm/msm/msm.txt b/Documentation/devicetree/bindings/arm/msm/msm.txt
index 765b5e4..b29a11f 100644
--- a/Documentation/devicetree/bindings/arm/msm/msm.txt
+++ b/Documentation/devicetree/bindings/arm/msm/msm.txt
@@ -282,6 +282,7 @@
compatible = "qcom,sdm670-rumi"
compatible = "qcom,sdm670-cdp"
compatible = "qcom,sdm670-mtp"
+compatible = "qcom,sdm670-qrd"
compatible = "qcom,qcs605-cdp"
compatible = "qcom,qcs605-mtp"
compatible = "qcom,sda670-cdp"
@@ -321,3 +322,5 @@
compatible = "qcom,apq8009-cdp"
compatible = "qcom,apq8009-mtp"
compatible = "qcom,sdxpoorwills-rumi"
+compatible = "qcom,sdxpoorwills-mtp"
+compatible = "qcom,sdxpoorwills-cdp"
diff --git a/Documentation/devicetree/bindings/devfreq/arm-memlat-mon.txt b/Documentation/devicetree/bindings/devfreq/arm-memlat-mon.txt
index 67dc991..6f2fac7 100644
--- a/Documentation/devicetree/bindings/devfreq/arm-memlat-mon.txt
+++ b/Documentation/devicetree/bindings/devfreq/arm-memlat-mon.txt
@@ -15,6 +15,8 @@
Defaults to 0x17 if not specified.
- qcom,inst-ev: The instruction count event that this monitor is supposed to measure.
Defaults to 0x08 if not specified.
+- qcom,stall-cycle-ev: The stall cycle count that this monitor is supposed to measure.
+ Assumes 100% stall if not specified.
Example:
@@ -24,6 +26,7 @@
qcom,target-dev = <&memlat0>;
qcom,cachemiss-ev = <0x2A>;
qcom,inst-ev = <0x08>;
+ qcom,stall-cycle-ev = <0xE7>;
qcom,core-dev-table =
< 300000 1525>,
< 499200 3143>,
diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,msm8953-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/qcom,msm8953-pinctrl.txt
index d4bf1ce..4b483e5 100644
--- a/Documentation/devicetree/bindings/pinctrl/qcom,msm8953-pinctrl.txt
+++ b/Documentation/devicetree/bindings/pinctrl/qcom,msm8953-pinctrl.txt
@@ -1,4 +1,4 @@
-Qualcomm MSM8953 TLMM block
+Qualcomm Technologies, Inc. MSM8953 TLMM block
This binding describes the Top Level Mode Multiplexer block found in the
MSM8953 platform.
diff --git a/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt b/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt
index c3e2cab..7f79f40 100644
--- a/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt
+++ b/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt
@@ -73,6 +73,8 @@
3: 52 MHz
Defaults to 26 MHz if not specified.
- extcon: phandle to external connector (Refer Documentation/devicetree/bindings/extcon/extcon-gpio.txt for more details).
+- non-removable : defines if the connected ufs device is not removable
+
Note: If above properties are not defined it can be assumed that the supply
regulators or clocks are always on.
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 21c66eb..63da745 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -55,6 +55,7 @@
select HAVE_FTRACE_MCOUNT_RECORD if (!XIP_KERNEL)
select HAVE_FUNCTION_GRAPH_TRACER if (!THUMB2_KERNEL)
select HAVE_FUNCTION_TRACER if (!XIP_KERNEL)
+ select HAVE_FUTEX_CMPXCHG if FUTEX
select HAVE_GCC_PLUGINS
select HAVE_GENERIC_DMA_COHERENT
select HAVE_HW_BREAKPOINT if (PERF_EVENTS && (CPU_V6 || CPU_V6K || CPU_V7))
diff --git a/arch/arm/boot/dts/qcom/Makefile b/arch/arm/boot/dts/qcom/Makefile
index 7eb0c7f..3826bad 100644
--- a/arch/arm/boot/dts/qcom/Makefile
+++ b/arch/arm/boot/dts/qcom/Makefile
@@ -1,5 +1,7 @@
-dtb-$(CONFIG_ARCH_SDXPOORWILLS) += sdxpoorwills-rumi.dtb
+dtb-$(CONFIG_ARCH_SDXPOORWILLS) += sdxpoorwills-rumi.dtb \
+ sdxpoorwills-cdp.dtb \
+ sdxpoorwills-mtp.dtb
ifeq ($(CONFIG_ARM64),y)
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills-blsp.dtsi b/arch/arm/boot/dts/qcom/sdxpoorwills-blsp.dtsi
new file mode 100644
index 0000000..4fe2d1e
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills-blsp.dtsi
@@ -0,0 +1,573 @@
+/* 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 "sdxpoorwills-pinctrl.dtsi"
+
+/ {
+ aliases {
+ spi1 = &spi_1;
+ spi2 = &spi_2;
+ spi3 = &spi_3;
+ spi4 = &spi_4;
+ i2c1 = &i2c_1;
+ i2c2 = &i2c_2;
+ i2c3 = &i2c_3;
+ i2c4 = &i2c_4;
+ i2c5 = &i2c_5;
+ i2c6 = &i2c_6;
+ i2c7 = &i2c_7;
+ };
+};
+
+
+&soc {
+ dma_blsp1: qcom,sps-dma@804000 { /* BLSP1 */
+ #dma-cells = <4>;
+ compatible = "qcom,sps-dma";
+ reg = <0x804000 0x23000>;
+ interrupts = <0 58 0>;
+ qcom,summing-threshold = <0x10>;
+ };
+
+ i2c_1: i2c@835000 { /* BLSP1 QUP1: GPIO: 2,3 */
+ compatible = "qcom,i2c-msm-v2";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x835000 0x600>;
+ reg-names = "qup_phys_addr";
+ interrupt-names = "qup_irq";
+ interrupts = <0 31 0>;
+ dmas = <&dma_blsp1 8 64 0x20000020 0x20>,
+ <&dma_blsp1 9 32 0x20000020 0x20>;
+ dma-names = "tx", "rx";
+ qcom,master-id = <86>;
+ qcom,clk-freq-out = <400000>;
+ qcom,clk-freq-in = <19200000>;
+ clock-names = "iface_clk", "core_clk";
+ clocks = <&clock_gcc GCC_BLSP1_AHB_CLK>,
+ <&clock_gcc GCC_BLSP1_QUP1_I2C_APPS_CLK>;
+ pinctrl-names = "i2c_active", "i2c_sleep";
+ pinctrl-0 = <&i2c_1_active>;
+ pinctrl-1 = <&i2c_1_sleep>;
+ status = "disabled";
+ };
+
+ i2c_2: i2c@836000 { /* BLSP1 QUP2: GPIO: 6,7 */
+ compatible = "qcom,i2c-msm-v2";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x836000 0x600>;
+ reg-names = "qup_phys_addr";
+ interrupt-names = "qup_irq";
+ interrupts = <0 32 0>;
+ dmas = <&dma_blsp1 10 64 0x20000020 0x20>,
+ <&dma_blsp1 11 32 0x20000020 0x20>;
+ dma-names = "tx", "rx";
+ qcom,master-id = <86>;
+ qcom,clk-freq-out = <400000>;
+ qcom,clk-freq-in = <19200000>;
+ clock-names = "iface_clk", "core_clk";
+ clocks = <&clock_gcc GCC_BLSP1_AHB_CLK>,
+ <&clock_gcc GCC_BLSP1_QUP2_I2C_APPS_CLK>;
+ pinctrl-names = "i2c_active", "i2c_sleep";
+ pinctrl-0 = <&i2c_2_active>;
+ pinctrl-1 = <&i2c_2_sleep>;
+ status = "disabled";
+ };
+
+ i2c_3: i2c@837000 { /* BLSP1 QUP3: GPIO: 10,11 */
+ compatible = "qcom,i2c-msm-v2";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x837000 0x600>;
+ reg-names = "qup_phys_addr";
+ interrupt-names = "qup_irq";
+ interrupts = <0 33 0>;
+ dmas = <&dma_blsp1 12 64 0x20000020 0x20>,
+ <&dma_blsp1 13 32 0x20000020 0x20>;
+ dma-names = "tx", "rx";
+ qcom,master-id = <86>;
+ qcom,clk-freq-out = <400000>;
+ qcom,clk-freq-in = <19200000>;
+ clock-names = "iface_clk", "core_clk";
+ clocks = <&clock_gcc GCC_BLSP1_AHB_CLK>,
+ <&clock_gcc GCC_BLSP1_QUP3_I2C_APPS_CLK>;
+ pinctrl-names = "i2c_active", "i2c_sleep";
+ pinctrl-0 = <&i2c_3_active>;
+ pinctrl-1 = <&i2c_3_sleep>;
+ status = "disabled";
+ };
+
+ i2c_4: i2c@838000 { /* BLSP1 QUP4: GPIO: 76,77 */
+ compatible = "qcom,i2c-msm-v2";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x838000 0x600>;
+ reg-names = "qup_phys_addr";
+ interrupt-names = "qup_irq";
+ interrupts = <0 34 0>;
+ dmas = <&dma_blsp1 14 64 0x20000020 0x20>,
+ <&dma_blsp1 15 32 0x20000020 0x20>;
+ dma-names = "tx", "rx";
+ qcom,master-id = <86>;
+ qcom,clk-freq-out = <400000>;
+ qcom,clk-freq-in = <19200000>;
+ clock-names = "iface_clk", "core_clk";
+ clocks = <&clock_gcc GCC_BLSP1_AHB_CLK>,
+ <&clock_gcc GCC_BLSP1_QUP4_I2C_APPS_CLK>;
+ pinctrl-names = "i2c_active", "i2c_sleep";
+ pinctrl-0 = <&i2c_4_active>;
+ pinctrl-1 = <&i2c_4_sleep>;
+ status = "disabled";
+ };
+
+ i2c_5: i2c@835000 { /* BLSP1 QUP1: GPIO: 74,75 */
+ compatible = "qcom,i2c-msm-v2";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x835000 0x600>;
+ reg-names = "qup_phys_addr";
+ interrupt-names = "qup_irq";
+ interrupts = <0 31 0>;
+ dmas = <&dma_blsp1 8 64 0x20000020 0x20>,
+ <&dma_blsp1 9 32 0x20000020 0x20>;
+ dma-names = "tx", "rx";
+ qcom,master-id = <86>;
+ qcom,clk-freq-out = <400000>;
+ qcom,clk-freq-in = <19200000>;
+ clock-names = "iface_clk", "core_clk";
+ clocks = <&clock_gcc GCC_BLSP1_AHB_CLK>,
+ <&clock_gcc GCC_BLSP1_QUP1_I2C_APPS_CLK>;
+ pinctrl-names = "i2c_active", "i2c_sleep";
+ pinctrl-0 = <&i2c_5_active>;
+ pinctrl-1 = <&i2c_5_sleep>;
+ status = "disabled";
+ };
+
+ i2c_6: i2c@836000 { /* BLSP1 QUP2: GPIO: 65,66 */
+ compatible = "qcom,i2c-msm-v2";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x836000 0x600>;
+ reg-names = "qup_phys_addr";
+ interrupt-names = "qup_irq";
+ interrupts = <0 32 0>;
+ dmas = <&dma_blsp1 10 64 0x20000020 0x20>,
+ <&dma_blsp1 11 32 0x20000020 0x20>;
+ dma-names = "tx", "rx";
+ qcom,master-id = <86>;
+ qcom,clk-freq-out = <400000>;
+ qcom,clk-freq-in = <19200000>;
+ clock-names = "iface_clk", "core_clk";
+ clocks = <&clock_gcc GCC_BLSP1_AHB_CLK>,
+ <&clock_gcc GCC_BLSP1_QUP2_I2C_APPS_CLK>;
+ pinctrl-names = "i2c_active", "i2c_sleep";
+ pinctrl-0 = <&i2c_6_active>;
+ pinctrl-1 = <&i2c_6_sleep>;
+ status = "disabled";
+ };
+
+ i2c_7: i2c@838000 { /* BLSP1 QUP4: GPIO: 18,19 */
+ compatible = "qcom,i2c-msm-v2";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x838000 0x600>;
+ reg-names = "qup_phys_addr";
+ interrupt-names = "qup_irq";
+ interrupts = <0 34 0>;
+ dmas = <&dma_blsp1 14 64 0x20000020 0x20>,
+ <&dma_blsp1 15 32 0x20000020 0x20>;
+ dma-names = "tx", "rx";
+ qcom,master-id = <86>;
+ qcom,clk-freq-out = <400000>;
+ qcom,clk-freq-in = <19200000>;
+ clock-names = "iface_clk", "core_clk";
+ clocks = <&clock_gcc GCC_BLSP1_AHB_CLK>,
+ <&clock_gcc GCC_BLSP1_QUP4_I2C_APPS_CLK>;
+ pinctrl-names = "i2c_active", "i2c_sleep";
+ pinctrl-0 = <&i2c_7_active>;
+ pinctrl-1 = <&i2c_7_sleep>;
+ status = "disabled";
+ };
+
+ spi_1: spi@835000 { /* BLSP1 QUP1: GPIO: 72,73,74,75 */
+ compatible = "qcom,spi-qup-v2";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg-names = "spi_physical", "spi_bam_physical";
+ reg = <0x835000 0x600>,
+ <0x804000 0x23000>;
+ interrupt-names = "spi_irq", "spi_bam_irq";
+ interrupts = <0 31 0>, <0 58 0>;
+ spi-max-frequency = <50000000>;
+ qcom,use-bam;
+ qcom,ver-reg-exists;
+ qcom,bam-consumer-pipe-index = <8>;
+ qcom,bam-producer-pipe-index = <9>;
+ qcom,master-id = <86>;
+ qcom,use-pinctrl;
+ pinctrl-names = "spi_default", "spi_sleep";
+ pinctrl-0 = <&spi_1_active>;
+ pinctrl-1 = <&spi_1_sleep>;
+ clock-names = "iface_clk", "core_clk";
+ clocks = <&clock_gcc GCC_BLSP1_AHB_CLK>,
+ <&clock_gcc GCC_BLSP1_QUP1_SPI_APPS_CLK>;
+ status = "disabled";
+ };
+
+ spi_2: spi@836000 { /* BLSP1 QUP2: GPIO: 4,5,6,7 */
+ compatible = "qcom,spi-qup-v2";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg-names = "spi_physical", "spi_bam_physical";
+ reg = <0x836000 0x600>,
+ <0x804000 0x23000>;
+ interrupt-names = "spi_irq", "spi_bam_irq";
+ interrupts = <0 32 0>, <0 58 0>;
+ spi-max-frequency = <50000000>;
+ qcom,use-bam;
+ qcom,ver-reg-exists;
+ qcom,bam-consumer-pipe-index = <10>;
+ qcom,bam-producer-pipe-index = <11>;
+ qcom,master-id = <86>;
+ qcom,use-pinctrl;
+ pinctrl-names = "spi_default", "spi_sleep";
+ pinctrl-0 = <&spi_2_active>;
+ pinctrl-1 = <&spi_2_sleep>;
+ clock-names = "iface_clk", "core_clk";
+ clocks = <&clock_gcc GCC_BLSP1_AHB_CLK>,
+ <&clock_gcc GCC_BLSP1_QUP2_SPI_APPS_CLK>;
+ status = "disabled";
+ };
+
+ spi_3: spi@837000 { /* BLSP1 QUP3: GPIO: 8,9,10,11 */
+ compatible = "qcom,spi-qup-v2";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg-names = "spi_physical", "spi_bam_physical";
+ reg = <0x837000 0x600>,
+ <0x804000 0x23000>;
+ interrupt-names = "spi_irq", "spi_bam_irq";
+ interrupts = <0 33 0>, <0 58 0>;
+ spi-max-frequency = <50000000>;
+ qcom,use-bam;
+ qcom,ver-reg-exists;
+ qcom,bam-consumer-pipe-index = <12>;
+ qcom,bam-producer-pipe-index = <13>;
+ qcom,master-id = <86>;
+ qcom,use-pinctrl;
+ pinctrl-names = "spi_default", "spi_sleep";
+ pinctrl-0 = <&spi_3_active>;
+ pinctrl-1 = <&spi_3_sleep>;
+ clock-names = "iface_clk", "core_clk";
+ clocks = <&clock_gcc GCC_BLSP1_AHB_CLK>,
+ <&clock_gcc GCC_BLSP1_QUP3_SPI_APPS_CLK>;
+ status = "disabled";
+ };
+
+ spi_4: spi@838000 { /* BLSP1 QUP4: GPIO: 16,17,18,19 */
+ compatible = "qcom,spi-qup-v2";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg-names = "spi_physical", "spi_bam_physical";
+ reg = <0x838000 0x600>,
+ <0x804000 0x23000>;
+ interrupt-names = "spi_irq", "spi_bam_irq";
+ interrupts = <0 34 0>, <0 58 0>;
+ spi-max-frequency = <50000000>;
+ qcom,use-bam;
+ qcom,ver-reg-exists;
+ qcom,bam-consumer-pipe-index = <14>;
+ qcom,bam-producer-pipe-index = <15>;
+ qcom,master-id = <86>;
+ qcom,use-pinctrl;
+ pinctrl-names = "spi_default", "spi_sleep";
+ pinctrl-0 = <&spi_4_active>;
+ pinctrl-1 = <&spi_4_sleep>;
+ clock-names = "iface_clk", "core_clk";
+ clocks = <&clock_gcc GCC_BLSP1_AHB_CLK>,
+ <&clock_gcc GCC_BLSP1_QUP4_SPI_APPS_CLK>;
+ status = "disabled";
+ };
+
+ blsp1_uart1a_hs: uarta@82f000 { /* BLSP1 UART1: GPIO: 0,1,2,3 */
+ compatible = "qcom,msm-hsuart-v14";
+ reg = <0x82f000 0x200>,
+ <0x804000 0x23000>;
+ reg-names = "core_mem", "bam_mem";
+ interrupt-names = "core_irq", "bam_irq", "wakeup_irq";
+ #address-cells = <0>;
+ interrupt-parent = <&blsp1_uart1a_hs>;
+ interrupts = <0 1 2>;
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0xffffffff>;
+ interrupt-map = <0 &intc 0 24 0
+ 1 &intc 0 58 0
+ 2 &tlmm 1 0>;
+
+ qcom,inject-rx-on-wakeup;
+ qcom,rx-char-to-inject = <0xfd>;
+
+ qcom,bam-tx-ep-pipe-index = <0>;
+ qcom,bam-rx-ep-pipe-index = <1>;
+ qcom,master-id = <86>;
+ clock-names = "core_clk", "iface_clk";
+ clocks = <&clock_gcc GCC_BLSP1_UART1_APPS_CLK>,
+ <&clock_gcc GCC_BLSP1_AHB_CLK>;
+ pinctrl-names = "sleep", "default";
+ pinctrl-0 = <&blsp1_uart1a_tx_sleep>,
+ <&blsp1_uart1a_rxcts_sleep>, <&blsp1_uart1a_rfr_sleep>;
+ pinctrl-1 = <&blsp1_uart1a_tx_active>,
+ <&blsp1_uart1a_rxcts_active>, <&blsp1_uart1a_rfr_active>;
+
+ qcom,msm-bus,name = "buart1a";
+ qcom,msm-bus,num-cases = <2>;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,vectors-KBps =
+ <86 512 0 0>,
+ <86 512 500 800>;
+ status = "disabled";
+ };
+
+ blsp1_uart1b_hs: uartb@82f000 { /* BLSP1 UART1: GPIO: 20,21,22,23 */
+ compatible = "qcom,msm-hsuart-v14";
+ reg = <0x82f000 0x200>,
+ <0x804000 0x23000>;
+ reg-names = "core_mem", "bam_mem";
+ interrupt-names = "core_irq", "bam_irq", "wakeup_irq";
+ #address-cells = <0>;
+ interrupt-parent = <&blsp1_uart1b_hs>;
+ interrupts = <0 1 2>;
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0xffffffff>;
+ interrupt-map = <0 &intc 0 24 0
+ 1 &intc 0 58 0
+ 2 &tlmm 21 0>;
+
+ qcom,inject-rx-on-wakeup;
+ qcom,rx-char-to-inject = <0xfd>;
+
+ qcom,bam-tx-ep-pipe-index = <0>;
+ qcom,bam-rx-ep-pipe-index = <1>;
+ qcom,master-id = <86>;
+ clock-names = "core_clk", "iface_clk";
+ clocks = <&clock_gcc GCC_BLSP1_UART1_APPS_CLK>,
+ <&clock_gcc GCC_BLSP1_AHB_CLK>;
+ pinctrl-names = "sleep", "default";
+ pinctrl-0 = <&blsp1_uart1b_tx_sleep>,
+ <&blsp1_uart1b_rxcts_sleep>, <&blsp1_uart1b_rfr_sleep>;
+ pinctrl-1 = <&blsp1_uart1b_tx_active>,
+ <&blsp1_uart1b_rxcts_active>, <&blsp1_uart1b_rfr_active>;
+
+ qcom,msm-bus,name = "buart1b";
+ qcom,msm-bus,num-cases = <2>;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,vectors-KBps =
+ <86 512 0 0>,
+ <86 512 500 800>;
+ status = "disabled";
+ };
+
+ blsp1_uart2a_hs: uarta@830000 { /* BLSP1 UART2 : GPIO: 4,5,6,7 */
+ compatible = "qcom,msm-hsuart-v14";
+ reg = <0x830000 0x200>,
+ <0x804000 0x23000>;
+ reg-names = "core_mem", "bam_mem";
+ interrupt-names = "core_irq", "bam_irq", "wakeup_irq";
+ #address-cells = <0>;
+ interrupt-parent = <&blsp1_uart2a_hs>;
+ interrupts = <0 1 2>;
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0xffffffff>;
+ interrupt-map = <0 &intc 0 25 0
+ 1 &intc 0 58 0
+ 2 &tlmm 5 0>;
+
+ qcom,inject-rx-on-wakeup;
+ qcom,rx-char-to-inject = <0xfd>;
+
+ qcom,bam-tx-ep-pipe-index = <2>;
+ qcom,bam-rx-ep-pipe-index = <3>;
+ qcom,master-id = <86>;
+ clock-names = "core_clk", "iface_clk";
+ clocks = <&clock_gcc GCC_BLSP1_UART2_APPS_CLK>,
+ <&clock_gcc GCC_BLSP1_AHB_CLK>;
+ pinctrl-names = "sleep", "default";
+ pinctrl-0 = <&blsp1_uart2a_tx_sleep>,
+ <&blsp1_uart2a_rxcts_sleep>, <&blsp1_uart2a_rfr_sleep>;
+ pinctrl-1 = <&blsp1_uart2b_tx_active>,
+ <&blsp1_uart2b_rxcts_active>, <&blsp1_uart2b_rfr_active>;
+
+ qcom,msm-bus,name = "buart2a";
+ qcom,msm-bus,num-cases = <2>;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,vectors-KBps =
+ <86 512 0 0>,
+ <86 512 500 800>;
+ status = "disabled";
+ };
+
+ blsp1_uart2b_hs: uartb@830000 { /* BLSP1 UART2 : GPIO: 63,64,65,66 */
+ compatible = "qcom,msm-hsuart-v14";
+ reg = <0x830000 0x200>,
+ <0x804000 0x23000>;
+ reg-names = "core_mem", "bam_mem";
+ interrupt-names = "core_irq", "bam_irq", "wakeup_irq";
+ #address-cells = <0>;
+ interrupt-parent = <&blsp1_uart2b_hs>;
+ interrupts = <0 1 2>;
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0xffffffff>;
+ interrupt-map = <0 &intc 0 25 0
+ 1 &intc 0 58 0
+ 2 &tlmm 64 0>;
+
+ qcom,inject-rx-on-wakeup;
+ qcom,rx-char-to-inject = <0xfd>;
+
+ qcom,bam-tx-ep-pipe-index = <2>;
+ qcom,bam-rx-ep-pipe-index = <3>;
+ qcom,master-id = <86>;
+ clock-names = "core_clk", "iface_clk";
+ clocks = <&clock_gcc GCC_BLSP1_UART2_APPS_CLK>,
+ <&clock_gcc GCC_BLSP1_AHB_CLK>;
+ pinctrl-names = "sleep", "default";
+ pinctrl-0 = <&blsp1_uart2b_tx_sleep>,
+ <&blsp1_uart2b_rxcts_sleep>, <&blsp1_uart2b_rfr_sleep>;
+ pinctrl-1 = <&blsp1_uart2b_tx_active>,
+ <&blsp1_uart2b_rxcts_active>, <&blsp1_uart2b_rfr_active>;
+
+ qcom,msm-bus,name = "buart2b";
+ qcom,msm-bus,num-cases = <2>;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,vectors-KBps =
+ <86 512 0 0>,
+ <86 512 500 800>;
+ status = "disabled";
+ };
+
+ blsp1_uart3_hs: uart@831000 { /* BLSP1 UART3: GPIO: 8,9,10,11 */
+ compatible = "qcom,msm-hsuart-v14";
+ reg = <0x831000 0x200>,
+ <0x804000 0x23000>;
+ reg-names = "core_mem", "bam_mem";
+ interrupt-names = "core_irq", "bam_irq", "wakeup_irq";
+ #address-cells = <0>;
+ interrupt-parent = <&blsp1_uart3_hs>;
+ interrupts = <0 1 2>;
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0xffffffff>;
+ interrupt-map = <0 &intc 0 26 0
+ 1 &intc 0 58 0
+ 2 &tlmm 9 0>;
+
+ qcom,inject-rx-on-wakeup;
+ qcom,rx-char-to-inject = <0xfd>;
+
+ qcom,bam-tx-ep-pipe-index = <4>;
+ qcom,bam-rx-ep-pipe-index = <5>;
+ qcom,master-id = <86>;
+ clock-names = "core_clk", "iface_clk";
+ clocks = <&clock_gcc GCC_BLSP1_UART3_APPS_CLK>,
+ <&clock_gcc GCC_BLSP1_AHB_CLK>;
+ pinctrl-names = "sleep", "default";
+ pinctrl-0 = <&blsp1_uart3_tx_sleep>,
+ <&blsp1_uart3_rxcts_sleep>, <&blsp1_uart3_rfr_sleep>;
+ pinctrl-1 = <&blsp1_uart3_tx_active>,
+ <&blsp1_uart3_rxcts_active>, <&blsp1_uart3_rfr_active>;
+
+ qcom,msm-bus,name = "buart3";
+ qcom,msm-bus,num-cases = <2>;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,vectors-KBps =
+ <86 512 0 0>,
+ <86 512 500 800>;
+ status = "disabled";
+ };
+
+ blsp1_uart4a_hs: uarta@832000 { /* BLSP1 UART4 : GPIO: 20,21,22,23 */
+ compatible = "qcom,msm-hsuart-v14";
+ reg = <0x832000 0x200>,
+ <0x804000 0x23000>;
+ reg-names = "core_mem", "bam_mem";
+ interrupt-names = "core_irq", "bam_irq", "wakeup_irq";
+ #address-cells = <0>;
+ interrupt-parent = <&blsp1_uart4a_hs>;
+ interrupts = <0 1 2>;
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0xffffffff>;
+ interrupt-map = <0 &intc 0 27 0
+ 1 &intc 0 58 0
+ 2 &tlmm 21 0>;
+
+ qcom,inject-rx-on-wakeup;
+ qcom,rx-char-to-inject = <0xfd>;
+
+ qcom,bam-tx-ep-pipe-index = <6>;
+ qcom,bam-rx-ep-pipe-index = <7>;
+ qcom,master-id = <86>;
+ clock-names = "core_clk", "iface_clk";
+ clocks = <&clock_gcc GCC_BLSP1_UART4_APPS_CLK>,
+ <&clock_gcc GCC_BLSP1_AHB_CLK>;
+ pinctrl-names = "sleep", "default";
+ pinctrl-0 = <&blsp1_uart4a_tx_active>,
+ <&blsp1_uart4a_rxcts_sleep>, <&blsp1_uart4a_rfr_sleep>;
+ pinctrl-1 = <&blsp1_uart4a_tx_active>,
+ <&blsp1_uart4a_rxcts_active>, <&blsp1_uart4a_rfr_active>;
+
+ qcom,msm-bus,name = "buart4a";
+ qcom,msm-bus,num-cases = <2>;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,vectors-KBps =
+ <86 512 0 0>,
+ <86 512 500 800>;
+ status = "disabled";
+ };
+
+ blsp1_uart4b_hs: uartb@832000 { /* BLSP1 UART4 : GPIO: 16,17,18,19 */
+ compatible = "qcom,msm-hsuart-v14";
+ reg = <0x832000 0x200>,
+ <0x804000 0x23000>;
+ reg-names = "core_mem", "bam_mem";
+ interrupt-names = "core_irq", "bam_irq", "wakeup_irq";
+ #address-cells = <0>;
+ interrupt-parent = <&blsp1_uart4b_hs>;
+ interrupts = <0 1 2>;
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0xffffffff>;
+ interrupt-map = <0 &intc 0 27 0
+ 1 &intc 0 58 0
+ 2 &tlmm 17 0>;
+
+ qcom,inject-rx-on-wakeup;
+ qcom,rx-char-to-inject = <0xfd>;
+
+ qcom,bam-tx-ep-pipe-index = <6>;
+ qcom,bam-rx-ep-pipe-index = <7>;
+ qcom,master-id = <86>;
+ clock-names = "core_clk", "iface_clk";
+ clocks = <&clock_gcc GCC_BLSP1_UART4_APPS_CLK>,
+ <&clock_gcc GCC_BLSP1_AHB_CLK>;
+ pinctrl-names = "sleep", "default";
+ pinctrl-0 = <&blsp1_uart4b_tx_sleep>,
+ <&blsp1_uart4b_rxcts_sleep>, <&blsp1_uart4b_rfr_sleep>;
+ pinctrl-1 = <&blsp1_uart4b_tx_active>,
+ <&blsp1_uart4b_rxcts_active>, <&blsp1_uart4b_rfr_active>;
+
+ qcom,msm-bus,name = "buart4b";
+ qcom,msm-bus,num-cases = <2>;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,vectors-KBps =
+ <86 512 0 0>,
+ <86 512 500 800>;
+ status = "disabled";
+ };
+};
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills-cdp.dts b/arch/arm/boot/dts/qcom/sdxpoorwills-cdp.dts
new file mode 100644
index 0000000..6be47b4
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills-cdp.dts
@@ -0,0 +1,31 @@
+/* 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 "sdxpoorwills.dtsi"
+#include "sdxpoorwills-pinctrl.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDXPOORWILLS CDP";
+ compatible = "qcom,sdxpoorwills-cdp",
+ "qcom,sdxpoorwills", "qcom,cdp";
+ qcom,board-id = <1 0x0>, <1 0x100>;
+};
+
+&blsp1_uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart2_console_active>;
+ status = "ok";
+};
+
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills-mtp.dts b/arch/arm/boot/dts/qcom/sdxpoorwills-mtp.dts
new file mode 100644
index 0000000..15ae24c
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills-mtp.dts
@@ -0,0 +1,31 @@
+/* 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 "sdxpoorwills.dtsi"
+#include "sdxpoorwills-pinctrl.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDXPOORWILLS MTP";
+ compatible = "qcom,sdxpoorwills-mtp",
+ "qcom,sdxpoorwills", "qcom,mtp";
+ qcom,board-id = <8 0x0>, <8 0x100>;
+};
+
+&blsp1_uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart2_console_active>;
+ status = "ok";
+};
+
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills-pinctrl.dtsi b/arch/arm/boot/dts/qcom/sdxpoorwills-pinctrl.dtsi
index ac02429..8181fa8 100644
--- a/arch/arm/boot/dts/qcom/sdxpoorwills-pinctrl.dtsi
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills-pinctrl.dtsi
@@ -31,5 +31,893 @@
bias-disable;
};
};
+
+ /* I2C CONFIGURATION */
+ i2c_1 {
+ i2c_1_active: i2c_1_active {
+ mux {
+ pins = "gpio2", "gpio3";
+ function = "blsp_i2c1";
+ };
+
+ config {
+ pins = "gpio2", "gpio3";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ i2c_1_sleep: i2c_1_sleep {
+ mux {
+ pins = "gpio2", "gpio3";
+ function = "blsp_i2c1";
+ };
+
+ config {
+ pins = "gpio2", "gpio3";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+ };
+ };
+
+ i2c_2 {
+ i2c_2_active: i2c_2_active {
+ mux {
+ pins = "gpio6", "gpio7";
+ function = "blsp_i2c2";
+ };
+
+ config {
+ pins = "gpio6", "gpio7";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ i2c_2_sleep: i2c_2_sleep {
+ mux {
+ pins = "gpio6", "gpio7";
+ function = "blsp_i2c2";
+ };
+
+ config {
+ pins = "gpio6", "gpio7";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+ };
+ };
+
+ i2c_3 {
+ i2c_3_active: i2c_3_active {
+ mux {
+ pins = "gpio10", "gpio11";
+ function = "blsp_i2c3";
+ };
+
+ config {
+ pins = "gpio10", "gpio11";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ i2c_3_sleep: i2c_3_sleep {
+ mux {
+ pins = "gpio10", "gpio11";
+ function = "blsp_i2c3";
+ };
+
+ config {
+ pins = "gpio10", "gpio11";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+ };
+ };
+
+ i2c_4 {
+ i2c_4_active: i2c_4_active {
+ mux {
+ pins = "gpio76", "gpio77";
+ function = "blsp_i2c4";
+ };
+
+ config {
+ pins = "gpio76", "gpio77";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ i2c_4_sleep: i2c_4_sleep {
+ mux {
+ pins = "gpio76", "gpio77";
+ function = "blsp_i2c4";
+ };
+
+ config {
+ pins = "gpio76", "gpio77";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+ };
+ };
+
+ i2c_5 {
+ i2c_5_active: i2c_5_active {
+ mux {
+ pins = "gpio74", "gpio75";
+ function = "blsp_i2c1";
+ };
+
+ config {
+ pins = "gpio74", "gpio75";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ i2c_5_sleep: i2c_5_sleep {
+ mux {
+ pins = "gpio74", "gpio75";
+ function = "blsp_i2c1";
+ };
+
+ config {
+ pins = "gpio74", "gpio75";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+ };
+ };
+
+ i2c_6 {
+ i2c_6_active: i2c_6_active {
+ mux {
+ pins = "gpio65", "gpio66";
+ function = "blsp_i2c2";
+ };
+
+ config {
+ pins = "gpio65", "gpio66";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ i2c_6_sleep: i2c_6_sleep {
+ mux {
+ pins = "gpio65", "gpio66";
+ function = "blsp_i2c2";
+ };
+
+ config {
+ pins = "gpio65", "gpio66";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+ };
+ };
+
+ i2c_7 {
+ i2c_7_active: i2c_7_active {
+ mux {
+ pins = "gpio18", "gpio19";
+ function = "blsp_i2c4";
+ };
+
+ config {
+ pins = "gpio18", "gpio19";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ i2c_7_sleep: i2c_7_sleep {
+ mux {
+ pins = "gpio18", "gpio19";
+ function = "blsp_i2c4";
+ };
+
+ config {
+ pins = "gpio18", "gpio19";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+ };
+ };
+
+ /* SPI CONFIGURATION */
+ spi_1 {
+ spi_1_active: spi_1_active {
+ mux {
+ pins = "gpio72", "gpio73",
+ "gpio74", "gpio75";
+ function = "blsp_spi1";
+ };
+
+ config {
+ pins = "gpio72", "gpio73",
+ "gpio74", "gpio75";
+ drive-strength = <6>;
+ bias-disable;
+ };
+ };
+
+ spi_1_sleep: spi_1_sleep {
+ mux {
+ pins = "gpio72", "gpio73",
+ "gpio74", "gpio75";
+ function = "blsp_spi1";
+ };
+
+ config {
+ pins = "gpio72", "gpio73",
+ "gpio74", "gpio75";
+ drive-strength = <6>;
+ bias-disable;
+ };
+ };
+ };
+
+ spi_2 {
+ spi_2_active: spi_2_active {
+ mux {
+ pins = "gpio4", "gpio5",
+ "gpio6", "gpio7";
+ function = "blsp_spi2";
+ };
+
+ config {
+ pins = "gpio4", "gpio5",
+ "gpio6", "gpio7";
+ drive-strength = <6>;
+ bias-disable;
+ };
+ };
+
+ spi_2_sleep: spi_2_sleep {
+ mux {
+ pins = "gpio4", "gpio5",
+ "gpio6", "gpio7";
+ function = "blsp_spi2";
+ };
+
+ config {
+ pins = "gpio4", "gpio5",
+ "gpio6", "gpio7";
+ drive-strength = <6>;
+ bias-disable;
+ };
+ };
+ };
+
+ spi_3 {
+ spi_3_active: spi_3_active {
+ mux {
+ pins = "gpio8", "gpio9",
+ "gpio10", "gpio11";
+ function = "blsp_spi3";
+ };
+
+ config {
+ pins = "gpio8", "gpio9",
+ "gpio10", "gpio11";
+ drive-strength = <6>;
+ bias-disable;
+ };
+ };
+
+ spi_3_sleep: spi_3_sleep {
+ mux {
+ pins = "gpio8", "gpio9",
+ "gpio10", "gpio11";
+ function = "blsp_spi3";
+ };
+
+ config {
+ pins = "gpio8", "gpio9",
+ "gpio10", "gpio11";
+ drive-strength = <6>;
+ bias-disable;
+ };
+ };
+ };
+
+ spi_4 {
+ spi_4_active: spi_4_active {
+ mux {
+ pins = "gpio16", "gpio17",
+ "gpio18", "gpio19";
+ function = "blsp_spi4";
+ };
+
+ config {
+ pins = "gpio16", "gpio17",
+ "gpio18", "gpio19";
+ drive-strength = <6>;
+ bias-disable;
+ };
+ };
+
+ spi_4_sleep: spi_4_sleep {
+ mux {
+ pins = "gpio16", "gpio17",
+ "gpio18", "gpio19";
+ function = "blsp_spi4";
+ };
+
+ config {
+ pins = "gpio16", "gpio17",
+ "gpio18", "gpio19";
+ drive-strength = <6>;
+ bias-disable;
+ };
+ };
+ };
+
+ /* HS UART CONFIGURATION */
+
+ blsp1_uart1a: blsp1_uart1a {
+ blsp1_uart1a_tx_active: blsp1_uart1a_tx_active {
+ mux {
+ pins = "gpio0";
+ function = "blsp_uart1";
+ };
+
+ config {
+ pins = "gpio0";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ blsp1_uart1a_tx_sleep: blsp1_uart1a_tx_sleep {
+ mux {
+ pins = "gpio0";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio0";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+ };
+
+ blsp1_uart1a_rxcts_active: blsp1_uart1a_rxcts_active {
+ mux {
+ pins = "gpio1", "gpio2";
+ function = "blsp_uart1";
+ };
+
+ config {
+ pins = "gpio1", "gpio2";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ blsp1_uart1a_rxcts_sleep: blsp1_uart1a_rxcts_sleep {
+ mux {
+ pins = "gpio1", "gpio2";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio1", "gpio2";
+ drive-strength = <2>;
+ bias-no-pull;
+ };
+ };
+
+ blsp1_uart1a_rfr_active: blsp1_uart1a_rfr_active {
+ mux {
+ pins = "gpio3";
+ function = "blsp_uart1";
+ };
+
+ config {
+ pins = "gpio3";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ blsp1_uart1a_rfr_sleep: blsp1_uart1a_rfr_sleep {
+ mux {
+ pins = "gpio3";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio3";
+ drive-strength = <2>;
+ bias-no-pull;
+ };
+ };
+ };
+
+ blsp1_uart1b: blsp1_uart1b {
+ blsp1_uart1b_tx_active: blsp1_uart1b_tx_active {
+ mux {
+ pins = "gpio20";
+ function = "blsp_uart1";
+ };
+
+ config {
+ pins = "gpio20";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ blsp1_uart1b_tx_sleep: blsp1_uart1b_tx_sleep {
+ mux {
+ pins = "gpio20";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio20";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+ };
+
+ blsp1_uart1b_rxcts_active: blsp1_uart1b_rxcts_active {
+ mux {
+ pins = "gpio21", "gpio22";
+ function = "blsp_uart1";
+ };
+
+ config {
+ pins = "gpio21", "gpio22";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ blsp1_uart1b_rxcts_sleep: blsp1_uart1b_rxcts_sleep {
+ mux {
+ pins = "gpio21", "gpio22";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio21", "gpio22";
+ drive-strength = <2>;
+ bias-no-pull;
+ };
+ };
+
+ blsp1_uart1b_rfr_active: blsp1_uart1b_rfr_active {
+ mux {
+ pins = "gpio23";
+ function = "blsp_uart1";
+ };
+
+ config {
+ pins = "gpio23";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ blsp1_uart1b_rfr_sleep: blsp1_uart1b_rfr_sleep {
+ mux {
+ pins = "gpio23";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio23";
+ drive-strength = <2>;
+ bias-no-pull;
+ };
+ };
+ };
+
+ blsp1_uart2a: blsp1_uart2a {
+ blsp1_uart2a_tx_active: blsp1_uart2a_tx_active {
+ mux {
+ pins = "gpio4";
+ function = "blsp_uart2";
+ };
+
+ config {
+ pins = "gpio4";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ blsp1_uart2a_tx_sleep: blsp1_uart2a_tx_sleep {
+ mux {
+ pins = "gpio4";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio4";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+ };
+
+ blsp1_uart2a_rxcts_active: blsp1_uart2a_rxcts_active {
+ mux {
+ pins = "gpio5", "gpio6";
+ function = "blsp_uart2";
+ };
+
+ config {
+ pins = "gpio5", "gpio6";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ blsp1_uart2a_rxcts_sleep: blsp1_uart2a_rxcts_sleep {
+ mux {
+ pins = "gpio5", "gpio6";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio1", "gpio2";
+ drive-strength = <2>;
+ bias-no-pull;
+ };
+ };
+
+ blsp1_uart2a_rfr_active: blsp1_uart2a_rfr_active {
+ mux {
+ pins = "gpio7";
+ function = "blsp_uart2";
+ };
+
+ config {
+ pins = "gpio7";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ blsp1_uart2a_rfr_sleep: blsp1_uart2a_rfr_sleep {
+ mux {
+ pins = "gpio7";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio7";
+ drive-strength = <2>;
+ bias-no-pull;
+ };
+ };
+ };
+
+ blsp1_uart2b: blsp1_uart2b {
+ blsp1_uart2b_tx_active: blsp1_uart2b_tx_active {
+ mux {
+ pins = "gpio63";
+ function = "blsp_uart2";
+ };
+
+ config {
+ pins = "gpio63";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ blsp1_uart2b_tx_sleep: blsp1_uart2b_tx_sleep {
+ mux {
+ pins = "gpio63";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio63";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+ };
+
+ blsp1_uart2b_rxcts_active: blsp1_uart2b_rxcts_active {
+ mux {
+ pins = "gpio64", "gpio65";
+ function = "blsp_uart2";
+ };
+
+ config {
+ pins = "gpio64", "gpio65";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ blsp1_uart2b_rxcts_sleep: blsp1_uart2b_rxcts_sleep {
+ mux {
+ pins = "gpio64", "gpio65";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio64", "gpio65";
+ drive-strength = <2>;
+ bias-no-pull;
+ };
+ };
+
+ blsp1_uart2b_rfr_active: blsp1_uart2b_rfr_active {
+ mux {
+ pins = "gpio66";
+ function = "blsp_uart2";
+ };
+
+ config {
+ pins = "gpio66";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ blsp1_uart2b_rfr_sleep: blsp1_uart2b_rfr_sleep {
+ mux {
+ pins = "gpio66";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio66";
+ drive-strength = <2>;
+ bias-no-pull;
+ };
+ };
+ };
+
+ blsp1_uart3: blsp1_uart3 {
+ blsp1_uart3_tx_active: blsp1_uart3_tx_active {
+ mux {
+ pins = "gpio8";
+ function = "blsp_uart3";
+ };
+
+ config {
+ pins = "gpio8";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ blsp1_uart3_tx_sleep: blsp1_uart3_tx_sleep {
+ mux {
+ pins = "gpio8";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio8";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+ };
+
+ blsp1_uart3_rxcts_active: blsp1_uart3_rxcts_active {
+ mux {
+ pins = "gpio9", "gpio10";
+ function = "blsp_uart3";
+ };
+
+ config {
+ pins = "gpio9", "gpio10";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ blsp1_uart3_rxcts_sleep: blsp1_uart3_rxcts_sleep {
+ mux {
+ pins = "gpio9", "gpio10";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio9", "gpio10";
+ drive-strength = <2>;
+ bias-no-pull;
+ };
+ };
+
+ blsp1_uart3_rfr_active: blsp1_uart3_rfr_active {
+ mux {
+ pins = "gpio11";
+ function = "blsp_uart3";
+ };
+
+ config {
+ pins = "gpio11";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ blsp1_uart3_rfr_sleep: blsp1_uart3_rfr_sleep {
+ mux {
+ pins = "gpio11";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio11";
+ drive-strength = <2>;
+ bias-no-pull;
+ };
+ };
+ };
+
+ blsp1_uart4a: blsp1_uart4a {
+ blsp1_uart4a_tx_active: blsp1_uart4a_tx_active {
+ mux {
+ pins = "gpio20";
+ function = "blsp_uart4";
+ };
+
+ config {
+ pins = "gpio20";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ blsp1_uart4a_tx_sleep: blsp1_uart4a_tx_sleep {
+ mux {
+ pins = "gpio20";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio20";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+ };
+
+ blsp1_uart4a_rxcts_active: blsp1_uart4a_rxcts_active {
+ mux {
+ pins = "gpio21", "gpio22";
+ function = "blsp_uart4";
+ };
+
+ config {
+ pins = "gpio21", "gpio22";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ blsp1_uart4a_rxcts_sleep: blsp1_uart4a_rxcts_sleep {
+ mux {
+ pins = "gpio21", "gpio22";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio21", "gpio22";
+ drive-strength = <2>;
+ bias-no-pull;
+ };
+ };
+
+ blsp1_uart4a_rfr_active: blsp1_uart4a_rfr_active {
+ mux {
+ pins = "gpio23";
+ function = "blsp_uart4";
+ };
+
+ config {
+ pins = "gpio23";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ blsp1_uart4a_rfr_sleep: blsp1_uart4a_rfr_sleep {
+ mux {
+ pins = "gpio23";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio23";
+ drive-strength = <2>;
+ bias-no-pull;
+ };
+ };
+ };
+
+ blsp1_uart4b: blsp1_uart4b {
+ blsp1_uart4b_tx_active: blsp1_uart4b_tx_active {
+ mux {
+ pins = "gpio16";
+ function = "blsp_uart4";
+ };
+
+ config {
+ pins = "gpio16";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ blsp1_uart4b_tx_sleep: blsp1_uart4b_tx_sleep {
+ mux {
+ pins = "gpio16";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio16";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+ };
+
+ blsp1_uart4b_rxcts_active: blsp1_uart4b_rxcts_active {
+ mux {
+ pins = "gpio17", "gpio18";
+ function = "blsp_uart4";
+ };
+
+ config {
+ pins = "gpio17", "gpio18";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ blsp1_uart4b_rxcts_sleep: blsp1_uart4b_rxcts_sleep {
+ mux {
+ pins = "gpio17", "gpio18";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio17", "gpio18";
+ drive-strength = <2>;
+ bias-no-pull;
+ };
+ };
+
+ blsp1_uart4b_rfr_active: blsp1_uart4b_rfr_active {
+ mux {
+ pins = "gpio19";
+ function = "blsp_uart4";
+ };
+
+ config {
+ pins = "gpio19";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+
+ blsp1_uart4b_rfr_sleep: blsp1_uart4b_rfr_sleep {
+ mux {
+ pins = "gpio19";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio19";
+ drive-strength = <2>;
+ bias-no-pull;
+ };
+ };
+ };
};
};
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi b/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi
index d538efe..aa8e31b 100644
--- a/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi
@@ -459,6 +459,7 @@
};
#include "pmxpoorwills.dtsi"
+#include "sdxpoorwills-blsp.dtsi"
#include "sdxpoorwills-regulator.dtsi"
#include "sdxpoorwills-smp2p.dtsi"
#include "sdxpoorwills-usb.dtsi"
diff --git a/arch/arm/configs/sdxpoorwills-perf_defconfig b/arch/arm/configs/sdxpoorwills-perf_defconfig
index e3b5dbc..877406f 100644
--- a/arch/arm/configs/sdxpoorwills-perf_defconfig
+++ b/arch/arm/configs/sdxpoorwills-perf_defconfig
@@ -28,6 +28,7 @@
CONFIG_PREEMPT=y
CONFIG_AEABI=y
CONFIG_CMA=y
+CONFIG_BUILD_ARM_APPENDED_DTB_IMAGE=y
CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_GOV_INTERACTIVE=y
CONFIG_CPU_IDLE=y
@@ -201,6 +202,7 @@
CONFIG_HW_RANDOM=y
CONFIG_I2C=y
CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_MSM_V2=y
CONFIG_SPI=y
CONFIG_SPI_QUP=y
CONFIG_SPI_SPIDEV=m
@@ -276,6 +278,7 @@
CONFIG_RTC_CLASS=y
CONFIG_RTC_DRV_QPNP=y
CONFIG_DMADEVICES=y
+CONFIG_QCOM_SPS_DMA=y
CONFIG_UIO=y
CONFIG_STAGING=y
CONFIG_GSI=y
diff --git a/arch/arm/configs/sdxpoorwills_defconfig b/arch/arm/configs/sdxpoorwills_defconfig
index b076dcf..d860595 100644
--- a/arch/arm/configs/sdxpoorwills_defconfig
+++ b/arch/arm/configs/sdxpoorwills_defconfig
@@ -30,6 +30,7 @@
CONFIG_PREEMPT=y
CONFIG_AEABI=y
CONFIG_CMA=y
+CONFIG_BUILD_ARM_APPENDED_DTB_IMAGE=y
CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_GOV_INTERACTIVE=y
CONFIG_CPU_IDLE=y
diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile
index aefdb52..ee803e2 100644
--- a/arch/arm64/boot/dts/qcom/Makefile
+++ b/arch/arm64/boot/dts/qcom/Makefile
@@ -79,6 +79,8 @@
sdm670-cdp-overlay.dtbo \
sdm670-mtp-overlay.dtbo \
sdm670-rumi-overlay.dtbo \
+ sdm670-qrd-overlay.dtbo \
+ sdm670-qrd-sku2-overlay.dtbo \
sdm670-pm660a-cdp-overlay.dtbo \
sdm670-pm660a-mtp-overlay.dtbo \
sdm670-external-codec-cdp-overlay.dtbo \
@@ -104,6 +106,8 @@
sdm670-cdp-overlay.dtbo-base := sdm670.dtb
sdm670-mtp-overlay.dtbo-base := sdm670.dtb
sdm670-rumi-overlay.dtbo-base := sdm670.dtb
+sdm670-qrd-overlay.dtbo-base := sdm670.dtb
+sdm670-qrd-sku2-overlay.dtbo-base := sdm670.dtb
sdm670-pm660a-cdp-overlay.dtbo-base := sdm670.dtb
sdm670-pm660a-mtp-overlay.dtbo-base := sdm670.dtb
sdm670-external-codec-cdp-overlay.dtbo-base := sdm670.dtb
@@ -130,6 +134,8 @@
dtb-$(CONFIG_ARCH_SDM670) += sdm670-rumi.dtb \
sdm670-mtp.dtb \
sdm670-cdp.dtb \
+ sdm670-qrd.dtb \
+ sdm670-qrd-sku2.dtb \
sdm670-pm660a-mtp.dtb \
sdm670-pm660a-cdp.dtb \
sdm670-external-codec-cdp.dtb \
diff --git a/arch/arm64/boot/dts/qcom/sdm670-gpu.dtsi b/arch/arm64/boot/dts/qcom/sdm670-gpu.dtsi
index 89dee0c..e51b700 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-gpu.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-gpu.dtsi
@@ -289,12 +289,12 @@
qcom,gmu-pwrlevel@0 {
reg = <0>;
- qcom,gmu-freq = <200000000>;
+ qcom,gmu-freq = <0>;
};
qcom,gmu-pwrlevel@1 {
reg = <1>;
- qcom,gmu-freq = <0>;
+ qcom,gmu-freq = <200000000>;
};
};
diff --git a/arch/arm64/boot/dts/qcom/sdm670-pmic-overlay.dtsi b/arch/arm64/boot/dts/qcom/sdm670-pmic-overlay.dtsi
index aa6be24..c39978e 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-pmic-overlay.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-pmic-overlay.dtsi
@@ -30,8 +30,7 @@
qcom,wipower-max-uw = <5000000>;
- /* Enable after the qusb_phy0 device node is added */
- /* dpdm-supply = <&qusb_phy0>; */
+ dpdm-supply = <&qusb_phy0>;
qcom,thermal-mitigation
= <3000000 2500000 2000000 1500000
diff --git a/arch/arm64/boot/dts/qcom/sdm670-qrd-overlay.dts b/arch/arm64/boot/dts/qcom/sdm670-qrd-overlay.dts
new file mode 100644
index 0000000..36d485e
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm670-qrd-overlay.dts
@@ -0,0 +1,32 @@
+/* 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-qrd.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDM670 PM660 + PM660L QRD";
+ compatible = "qcom,sdm670-qrd", "qcom,sdm670", "qcom,qrd";
+ qcom,msm-id = <336 0x0>;
+ qcom,board-id = <0x0002000b 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-qrd-sku2-overlay.dts b/arch/arm64/boot/dts/qcom/sdm670-qrd-sku2-overlay.dts
new file mode 100644
index 0000000..37eb4cd
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm670-qrd-sku2-overlay.dts
@@ -0,0 +1,32 @@
+/* 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-qrd.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDM670 PM660 + PM660L QRD SKU2";
+ compatible = "qcom,sdm670-qrd", "qcom,sdm670", "qcom,qrd";
+ qcom,msm-id = <336 0x0>;
+ qcom,board-id = <0x0012000b 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-qrd-sku2.dts b/arch/arm64/boot/dts/qcom/sdm670-qrd-sku2.dts
new file mode 100644
index 0000000..dada4c6
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm670-qrd-sku2.dts
@@ -0,0 +1,26 @@
+/* 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-qrd.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDM670 PM660 + PM660L QRD SKU2";
+ compatible = "qcom,sdm670-qrd", "qcom,sdm670", "qcom,qrd";
+ qcom,board-id = <0x0012000b 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-qrd.dts b/arch/arm64/boot/dts/qcom/sdm670-qrd.dts
new file mode 100644
index 0000000..c22afa4
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm670-qrd.dts
@@ -0,0 +1,26 @@
+/* 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-qrd.dtsi"
+
+/ {
+ model = "Qualcomm Technologies, Inc. SDM670 PM660 + PM660L QRD";
+ compatible = "qcom,sdm670-qrd", "qcom,sdm670", "qcom,qrd";
+ qcom,board-id = <0x0002000b 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-qrd.dtsi b/arch/arm64/boot/dts/qcom/sdm670-qrd.dtsi
new file mode 100644
index 0000000..4f40678
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm670-qrd.dtsi
@@ -0,0 +1,37 @@
+/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include "sdm670-pmic-overlay.dtsi"
+
+&qupv3_se9_2uart {
+ status = "disabled";
+};
+
+&qupv3_se12_2uart {
+ status = "ok";
+};
+
+&qupv3_se8_spi {
+ status = "disabled";
+};
+
+&qupv3_se3_i2c {
+ status = "disabled";
+};
+
+&qupv3_se10_i2c {
+ status = "disabled";
+};
+
+&qupv3_se6_4uart {
+ status = "disabled";
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm670-sde-display.dtsi b/arch/arm64/boot/dts/qcom/sdm670-sde-display.dtsi
index fdf8ba8..2a61e18 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-sde-display.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-sde-display.dtsi
@@ -477,7 +477,6 @@
ext_disp: qcom,msm-ext-disp {
compatible = "qcom,msm-ext-disp";
- status = "disabled";
ext_disp_audio_codec: qcom,msm-ext-disp-audio-codec-rx {
compatible = "qcom,msm-ext-disp-audio-codec-rx";
@@ -487,7 +486,6 @@
sde_dp: qcom,dp_display@0{
cell-index = <0>;
compatible = "qcom,dp-display";
- status = "disabled";
gdsc-supply = <&mdss_core_gdsc>;
vdda-1p2-supply = <&pm660_l1>;
@@ -500,10 +498,11 @@
<0xaf02000 0x1a0>,
<0x780000 0x621c>,
<0x88ea030 0x10>,
+ <0x88e8000 0x20>,
<0x0aee1000 0x034>;
reg-names = "dp_ctrl", "dp_phy", "dp_ln_tx0", "dp_ln_tx1",
"dp_mmss_cc", "qfprom_physical", "dp_pll",
- "hdcp_physical";
+ "usb3_dp_com", "hdcp_physical";
interrupt-parent = <&mdss_mdp>;
interrupts = <12 0>;
@@ -586,7 +585,6 @@
};
&sde_dp {
- status = "disabled";
pinctrl-names = "mdss_dp_active", "mdss_dp_sleep";
pinctrl-0 = <&sde_dp_aux_active &sde_dp_usbplug_cc_active>;
pinctrl-1 = <&sde_dp_aux_suspend &sde_dp_usbplug_cc_suspend>;
@@ -596,7 +594,7 @@
};
&mdss_mdp {
- connectors = <&sde_rscc &sde_wb>;
+ connectors = <&sde_rscc &sde_wb &sde_dp>;
};
&dsi_dual_nt35597_truly_video {
diff --git a/arch/arm64/boot/dts/qcom/sdm670-sde-pll.dtsi b/arch/arm64/boot/dts/qcom/sdm670-sde-pll.dtsi
index 78e5d94..72e3f5f 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-sde-pll.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-sde-pll.dtsi
@@ -67,7 +67,6 @@
mdss_dp_pll: qcom,mdss_dp_pll@88ea000 {
compatible = "qcom,mdss_dp_pll_10nm";
- status = "disabled";
label = "MDSS DP PLL";
cell-index = <0>;
#clock-cells = <1>;
diff --git a/arch/arm64/boot/dts/qcom/sdm670-thermal.dtsi b/arch/arm64/boot/dts/qcom/sdm670-thermal.dtsi
index e4993d6..1ce8dba 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-thermal.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-thermal.dtsi
@@ -518,7 +518,7 @@
cooling-device = <&CPU6 9 9>;
};
gpu_vdd_cdev {
- trip = <&aoss0_trip>;
+ trip = <&cpu0_trip>;
cooling-device = <&msm_gpu 1 1>;
};
cx_vdd_cdev {
@@ -567,7 +567,7 @@
cooling-device = <&CPU6 9 9>;
};
gpu_vdd_cdev {
- trip = <&aoss0_trip>;
+ trip = <&cpu1_trip>;
cooling-device = <&msm_gpu 1 1>;
};
cx_vdd_cdev {
@@ -616,7 +616,7 @@
cooling-device = <&CPU6 9 9>;
};
gpu_vdd_cdev {
- trip = <&aoss0_trip>;
+ trip = <&cpu2_trip>;
cooling-device = <&msm_gpu 1 1>;
};
cx_vdd_cdev {
@@ -665,7 +665,7 @@
cooling-device = <&CPU6 9 9>;
};
gpu_vdd_cdev {
- trip = <&aoss0_trip>;
+ trip = <&cpu3_trip>;
cooling-device = <&msm_gpu 1 1>;
};
cx_vdd_cdev {
@@ -714,7 +714,7 @@
cooling-device = <&CPU6 9 9>;
};
gpu_vdd_cdev {
- trip = <&aoss0_trip>;
+ trip = <&cpu4_trip>;
cooling-device = <&msm_gpu 1 1>;
};
cx_vdd_cdev {
@@ -763,7 +763,7 @@
cooling-device = <&CPU6 9 9>;
};
gpu_vdd_cdev {
- trip = <&aoss0_trip>;
+ trip = <&cpu5_trip>;
cooling-device = <&msm_gpu 1 1>;
};
cx_vdd_cdev {
@@ -812,7 +812,7 @@
cooling-device = <&CPU6 9 9>;
};
gpu_vdd_cdev {
- trip = <&aoss0_trip>;
+ trip = <&l3_0_trip>;
cooling-device = <&msm_gpu 1 1>;
};
cx_vdd_cdev {
@@ -861,7 +861,7 @@
cooling-device = <&CPU6 9 9>;
};
gpu_vdd_cdev {
- trip = <&aoss0_trip>;
+ trip = <&l3_1_trip>;
cooling-device = <&msm_gpu 1 1>;
};
cx_vdd_cdev {
@@ -910,7 +910,7 @@
cooling-device = <&CPU6 9 9>;
};
gpu_vdd_cdev {
- trip = <&aoss0_trip>;
+ trip = <&cpug0_trip>;
cooling-device = <&msm_gpu 1 1>;
};
cx_vdd_cdev {
@@ -959,7 +959,7 @@
cooling-device = <&CPU6 9 9>;
};
gpu_vdd_cdev {
- trip = <&aoss0_trip>;
+ trip = <&cpug1_trip>;
cooling-device = <&msm_gpu 1 1>;
};
cx_vdd_cdev {
@@ -1008,7 +1008,7 @@
cooling-device = <&CPU6 9 9>;
};
gpu_vdd_cdev {
- trip = <&aoss0_trip>;
+ trip = <&gpu0_trip_l>;
cooling-device = <&msm_gpu 1 1>;
};
cx_vdd_cdev {
@@ -1057,7 +1057,7 @@
cooling-device = <&CPU6 9 9>;
};
gpu_vdd_cdev {
- trip = <&aoss0_trip>;
+ trip = <&gpu1_trip_l>;
cooling-device = <&msm_gpu 1 1>;
};
cx_vdd_cdev {
@@ -1106,7 +1106,7 @@
cooling-device = <&CPU6 9 9>;
};
gpu_vdd_cdev {
- trip = <&aoss0_trip>;
+ trip = <&aoss1_trip>;
cooling-device = <&msm_gpu 1 1>;
};
cx_vdd_cdev {
@@ -1155,7 +1155,7 @@
cooling-device = <&CPU6 9 9>;
};
gpu_vdd_cdev {
- trip = <&aoss0_trip>;
+ trip = <&dsp_trip>;
cooling-device = <&msm_gpu 1 1>;
};
cx_vdd_cdev {
@@ -1204,7 +1204,7 @@
cooling-device = <&CPU6 9 9>;
};
gpu_vdd_cdev {
- trip = <&aoss0_trip>;
+ trip = <&ddr_trip>;
cooling-device = <&msm_gpu 1 1>;
};
cx_vdd_cdev {
@@ -1253,7 +1253,7 @@
cooling-device = <&CPU6 9 9>;
};
gpu_vdd_cdev {
- trip = <&aoss0_trip>;
+ trip = <&wlan_trip>;
cooling-device = <&msm_gpu 1 1>;
};
cx_vdd_cdev {
@@ -1302,7 +1302,7 @@
cooling-device = <&CPU6 9 9>;
};
gpu_vdd_cdev {
- trip = <&aoss0_trip>;
+ trip = <&hvx_trip>;
cooling-device = <&msm_gpu 1 1>;
};
cx_vdd_cdev {
@@ -1351,7 +1351,7 @@
cooling-device = <&CPU6 9 9>;
};
gpu_vdd_cdev {
- trip = <&aoss0_trip>;
+ trip = <&camera_trip>;
cooling-device = <&msm_gpu 1 1>;
};
cx_vdd_cdev {
@@ -1400,7 +1400,7 @@
cooling-device = <&CPU6 9 9>;
};
gpu_vdd_cdev {
- trip = <&aoss0_trip>;
+ trip = <&mmss_trip>;
cooling-device = <&msm_gpu 1 1>;
};
cx_vdd_cdev {
@@ -1449,7 +1449,7 @@
cooling-device = <&CPU6 9 9>;
};
gpu_vdd_cdev {
- trip = <&aoss0_trip>;
+ trip = <&mdm_trip>;
cooling-device = <&msm_gpu 1 1>;
};
cx_vdd_cdev {
diff --git a/arch/arm64/boot/dts/qcom/sdm670.dtsi b/arch/arm64/boot/dts/qcom/sdm670.dtsi
index b527f3d..a743149 100644
--- a/arch/arm64/boot/dts/qcom/sdm670.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670.dtsi
@@ -974,7 +974,7 @@
compatible = "qcom,msm-watchdog";
reg = <0x17980000 0x1000>;
reg-names = "wdt-base";
- interrupts = <0 3 0>, <0 4 0>;
+ interrupts = <0 0 0>, <0 1 0>;
qcom,bark-time = <11000>;
qcom,pet-time = <10000>;
qcom,ipi-ping;
@@ -1642,6 +1642,7 @@
<0 0>,
<0 0>;
+ non-removable;
qcom,msm-bus,name = "ufshc_mem";
qcom,msm-bus,num-cases = <12>;
qcom,msm-bus,num-paths = <2>;
@@ -1725,6 +1726,10 @@
qcom,client-id = <0x00000001>;
};
+ qcom,msm_gsi {
+ compatible = "qcom,msm_gsi";
+ };
+
qcom,rmnet-ipa {
compatible = "qcom,rmnet-ipa3";
qcom,rmnet-ipa-ssr;
@@ -2222,6 +2227,21 @@
};
};
+ bluetooth: bt_wcn3990 {
+ compatible = "qca,wcn3990";
+ qca,bt-vdd-core-supply = <&pm660_l9>;
+ qca,bt-vdd-pa-supply = <&pm660_l6>;
+ qca,bt-vdd-ldo-supply = <&pm660_l19>;
+
+ qca,bt-vdd-core-voltage-level = <1800000 1900000>;
+ qca,bt-vdd-pa-voltage-level = <1304000 1370000>;
+ qca,bt-vdd-ldo-voltage-level = <3312000 3400000>;
+
+ qca,bt-vdd-core-current-level = <1>; /* LPM/PFM */
+ qca,bt-vdd-pa-current-level = <1>; /* LPM/PFM */
+ qca,bt-vdd-ldo-current-level = <1>; /* LPM/PFM */
+ };
+
qcom,icnss@18800000 {
status = "disabled";
compatible = "qcom,icnss";
diff --git a/arch/arm64/boot/dts/qcom/sdm845-gpu.dtsi b/arch/arm64/boot/dts/qcom/sdm845-gpu.dtsi
index 11b6a4d..4fd1a67 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-gpu.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-gpu.dtsi
@@ -58,6 +58,7 @@
qcom,initial-pwrlevel = <5>;
qcom,gpu-quirk-hfi-use-reg;
+ qcom,gpu-quirk-secvid-set-once;
qcom,idle-timeout = <80>; //msecs
qcom,no-nap;
diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
index 3868665..9701cc2 100644
--- a/drivers/block/zram/zram_drv.c
+++ b/drivers/block/zram/zram_drv.c
@@ -41,6 +41,12 @@
static int zram_major;
static const char *default_compressor = "lzo";
+/*
+ * We don't need to see memory allocation errors more than once every 1
+ * second to know that a problem is occurring.
+ */
+#define ALLOC_ERROR_LOG_RATE_MS 1000
+
/* Module params (documentation at end) */
static unsigned int num_devices = 1;
@@ -668,6 +674,7 @@
struct zram_meta *meta = zram->meta;
struct zcomp_strm *zstrm = NULL;
unsigned long alloced_pages;
+ static unsigned long zram_rs_time;
page = bvec->bv_page;
if (is_partial_io(bvec)) {
@@ -761,8 +768,10 @@
if (handle)
goto compress_again;
- pr_err("Error allocating memory for compressed page: %u, size=%u\n",
- index, clen);
+ if (printk_timed_ratelimit(&zram_rs_time,
+ ALLOC_ERROR_LOG_RATE_MS))
+ pr_err("Error allocating memory for compressed page: %u, size=%u\n",
+ index, clen);
ret = -ENOMEM;
goto out;
}
diff --git a/drivers/cpuidle/lpm-levels.c b/drivers/cpuidle/lpm-levels.c
index 67f2d0c..dc5ec96 100644
--- a/drivers/cpuidle/lpm-levels.c
+++ b/drivers/cpuidle/lpm-levels.c
@@ -1464,7 +1464,8 @@
struct lpm_cpu_level *cpu_level = &lpm_cpu->levels[i];
snprintf(st->name, CPUIDLE_NAME_LEN, "C%u\n", i);
- snprintf(st->desc, CPUIDLE_DESC_LEN, cpu_level->name);
+ snprintf(st->desc, CPUIDLE_DESC_LEN, "%s",
+ cpu_level->name);
st->flags = 0;
st->exit_latency = cpu_level->pwr.latency_us;
st->power_usage = cpu_level->pwr.ss_power;
diff --git a/drivers/devfreq/arm-memlat-mon.c b/drivers/devfreq/arm-memlat-mon.c
index f4f503e..9943c8c 100644
--- a/drivers/devfreq/arm-memlat-mon.c
+++ b/drivers/devfreq/arm-memlat-mon.c
@@ -36,6 +36,7 @@
INST_IDX,
CM_IDX,
CYC_IDX,
+ STALL_CYC_IDX,
NUM_EVENTS
};
#define INST_EV 0x08
@@ -105,12 +106,19 @@
{
struct cpu_pmu_stats *cpustats = to_cpustats(cpu_grp, cpu);
struct dev_stats *devstats = to_devstats(cpu_grp, cpu);
- unsigned long cyc_cnt;
+ unsigned long cyc_cnt, stall_cnt;
devstats->inst_count = read_event(&cpustats->events[INST_IDX]);
devstats->mem_count = read_event(&cpustats->events[CM_IDX]);
cyc_cnt = read_event(&cpustats->events[CYC_IDX]);
devstats->freq = compute_freq(cpustats, cyc_cnt);
+ if (cpustats->events[STALL_CYC_IDX].pevent) {
+ stall_cnt = read_event(&cpustats->events[STALL_CYC_IDX]);
+ stall_cnt = min(stall_cnt, cyc_cnt);
+ devstats->stall_pct = mult_frac(100, stall_cnt, cyc_cnt);
+ } else {
+ devstats->stall_pct = 100;
+ }
}
static unsigned long get_cnt(struct memlat_hwmon *hw)
@@ -130,7 +138,10 @@
for (i = 0; i < ARRAY_SIZE(cpustats->events); i++) {
cpustats->events[i].prev_count = 0;
- perf_event_release_kernel(cpustats->events[i].pevent);
+ if (cpustats->events[i].pevent) {
+ perf_event_release_kernel(cpustats->events[i].pevent);
+ cpustats->events[i].pevent = NULL;
+ }
}
}
@@ -149,6 +160,7 @@
devstats->inst_count = 0;
devstats->mem_count = 0;
devstats->freq = 0;
+ devstats->stall_pct = 0;
}
mutex_lock(&list_lock);
if (!cpumask_equal(&cpu_grp->cpus, &cpu_grp->inited_cpus))
@@ -182,6 +194,7 @@
struct perf_event *pevent;
struct perf_event_attr *attr;
int err, i;
+ unsigned int event_id;
struct cpu_pmu_stats *cpustats = to_cpustats(cpu_grp, cpu);
/* Allocate an attribute for event initialization */
@@ -190,7 +203,11 @@
return -ENOMEM;
for (i = 0; i < ARRAY_SIZE(cpustats->events); i++) {
- attr->config = cpu_grp->event_ids[i];
+ event_id = cpu_grp->event_ids[i];
+ if (!event_id)
+ continue;
+
+ attr->config = event_id;
pevent = perf_event_create_kernel_counter(attr, cpu, NULL,
NULL, NULL);
if (IS_ERR(pevent))
@@ -348,6 +365,13 @@
}
cpu_grp->event_ids[INST_IDX] = event_id;
+ ret = of_property_read_u32(dev->of_node, "qcom,stall-cycle-ev",
+ &event_id);
+ if (ret)
+ dev_dbg(dev, "Stall cycle event not specified. Event ignored.\n");
+ else
+ cpu_grp->event_ids[STALL_CYC_IDX] = event_id;
+
for_each_cpu(cpu, &cpu_grp->cpus)
to_devstats(cpu_grp, cpu)->id = cpu;
diff --git a/drivers/devfreq/governor_bw_hwmon.c b/drivers/devfreq/governor_bw_hwmon.c
index 53c0f8a..a1d9b50 100644
--- a/drivers/devfreq/governor_bw_hwmon.c
+++ b/drivers/devfreq/governor_bw_hwmon.c
@@ -820,11 +820,13 @@
static int devfreq_bw_hwmon_ev_handler(struct devfreq *df,
unsigned int event, void *data)
{
- int ret;
+ int ret = 0;
unsigned int sample_ms;
struct hwmon_node *node;
struct bw_hwmon *hw;
+ mutex_lock(&state_lock);
+
switch (event) {
case DEVFREQ_GOV_START:
sample_ms = df->profile->polling_ms;
@@ -834,7 +836,7 @@
ret = gov_start(df);
if (ret)
- return ret;
+ goto out;
dev_dbg(df->dev.parent,
"Enabled dev BW HW monitor governor\n");
@@ -864,7 +866,7 @@
if (ret) {
dev_err(df->dev.parent,
"Unable to resume HW monitor (%d)\n", ret);
- return ret;
+ goto out;
}
break;
@@ -874,7 +876,7 @@
dev_err(df->dev.parent,
"Unable to suspend BW HW mon governor (%d)\n",
ret);
- return ret;
+ goto out;
}
dev_dbg(df->dev.parent, "Suspended BW HW mon governor\n");
@@ -886,14 +888,17 @@
dev_err(df->dev.parent,
"Unable to resume BW HW mon governor (%d)\n",
ret);
- return ret;
+ goto out;
}
dev_dbg(df->dev.parent, "Resumed BW HW mon governor\n");
break;
}
- return 0;
+out:
+ mutex_unlock(&state_lock);
+
+ return ret;
}
static struct devfreq_governor devfreq_gov_bw_hwmon = {
diff --git a/drivers/devfreq/governor_memlat.c b/drivers/devfreq/governor_memlat.c
index 1a8ef1f..9688502 100644
--- a/drivers/devfreq/governor_memlat.c
+++ b/drivers/devfreq/governor_memlat.c
@@ -35,6 +35,7 @@
struct memlat_node {
unsigned int ratio_ceil;
+ unsigned int stall_floor;
bool mon_started;
bool already_zero;
struct list_head list;
@@ -247,9 +248,11 @@
hw->core_stats[i].id,
hw->core_stats[i].inst_count,
hw->core_stats[i].mem_count,
- hw->core_stats[i].freq, ratio);
+ hw->core_stats[i].freq,
+ hw->core_stats[i].stall_pct, ratio);
if (ratio <= node->ratio_ceil
+ && hw->core_stats[i].stall_pct >= node->stall_floor
&& hw->core_stats[i].freq > max_freq) {
lat_dev = i;
max_freq = hw->core_stats[i].freq;
@@ -275,9 +278,11 @@
}
gov_attr(ratio_ceil, 1U, 10000U);
+gov_attr(stall_floor, 0U, 100U);
static struct attribute *dev_attr[] = {
&dev_attr_ratio_ceil.attr,
+ &dev_attr_stall_floor.attr,
&dev_attr_freq_map.attr,
NULL,
};
diff --git a/drivers/devfreq/governor_memlat.h b/drivers/devfreq/governor_memlat.h
index 8c533ee..f2ba534 100644
--- a/drivers/devfreq/governor_memlat.h
+++ b/drivers/devfreq/governor_memlat.h
@@ -29,6 +29,7 @@
unsigned long inst_count;
unsigned long mem_count;
unsigned long freq;
+ unsigned long stall_pct;
};
struct core_dev_map {
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index 8e5683f..1a73237 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -898,6 +898,7 @@
{ ADRENO_QUIRK_DISABLE_LMLOADKILL,
"qcom,gpu-quirk-lmloadkill-disable" },
{ ADRENO_QUIRK_HFI_USE_REG, "qcom,gpu-quirk-hfi-use-reg" },
+ { ADRENO_QUIRK_SECVID_SET_ONCE, "qcom,gpu-quirk-secvid-set-once" },
};
static int adreno_of_get_power(struct adreno_device *adreno_dev,
@@ -1389,9 +1390,10 @@
static void _set_secvid(struct kgsl_device *device)
{
struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
+ static bool set;
/* Program GPU contect protection init values */
- if (device->mmu.secured) {
+ if (device->mmu.secured && !set) {
if (adreno_is_a4xx(adreno_dev))
adreno_writereg(adreno_dev,
ADRENO_REG_RBBM_SECVID_TRUST_CONFIG, 0x2);
@@ -1405,6 +1407,8 @@
adreno_writereg(adreno_dev,
ADRENO_REG_RBBM_SECVID_TSB_TRUSTED_SIZE,
KGSL_IOMMU_SECURE_SIZE);
+ if (ADRENO_QUIRK(adreno_dev, ADRENO_QUIRK_SECVID_SET_ONCE))
+ set = true;
}
}
diff --git a/drivers/gpu/msm/adreno.h b/drivers/gpu/msm/adreno.h
index 3118375..629e128 100644
--- a/drivers/gpu/msm/adreno.h
+++ b/drivers/gpu/msm/adreno.h
@@ -140,6 +140,8 @@
#define ADRENO_QUIRK_DISABLE_LMLOADKILL BIT(5)
/* Allow HFI to use registers to send message to GMU */
#define ADRENO_QUIRK_HFI_USE_REG BIT(6)
+/* Only set protected SECVID registers once */
+#define ADRENO_QUIRK_SECVID_SET_ONCE BIT(7)
/* Flags to control command packet settings */
#define KGSL_CMD_FLAGS_NONE 0
diff --git a/drivers/gpu/msm/adreno_a6xx.c b/drivers/gpu/msm/adreno_a6xx.c
index cc3cfdd..453ef4f 100644
--- a/drivers/gpu/msm/adreno_a6xx.c
+++ b/drivers/gpu/msm/adreno_a6xx.c
@@ -65,10 +65,10 @@
unsigned int val;
};
static const struct kgsl_hwcg_reg a630_hwcg_regs[] = {
- {A6XX_RBBM_CLOCK_CNTL_SP0, 0x22222222},
- {A6XX_RBBM_CLOCK_CNTL_SP1, 0x22222222},
- {A6XX_RBBM_CLOCK_CNTL_SP2, 0x22222222},
- {A6XX_RBBM_CLOCK_CNTL_SP3, 0x22222222},
+ {A6XX_RBBM_CLOCK_CNTL_SP0, 0x02222222},
+ {A6XX_RBBM_CLOCK_CNTL_SP1, 0x02222222},
+ {A6XX_RBBM_CLOCK_CNTL_SP2, 0x02222222},
+ {A6XX_RBBM_CLOCK_CNTL_SP3, 0x02222222},
{A6XX_RBBM_CLOCK_CNTL2_SP0, 0x02022220},
{A6XX_RBBM_CLOCK_CNTL2_SP1, 0x02022220},
{A6XX_RBBM_CLOCK_CNTL2_SP2, 0x02022220},
@@ -143,20 +143,20 @@
{A6XX_RBBM_CLOCK_CNTL2_RB1, 0x00002222},
{A6XX_RBBM_CLOCK_CNTL2_RB2, 0x00002222},
{A6XX_RBBM_CLOCK_CNTL2_RB3, 0x00002222},
- {A6XX_RBBM_CLOCK_CNTL_CCU0, 0x00002220},
- {A6XX_RBBM_CLOCK_CNTL_CCU1, 0x00002220},
- {A6XX_RBBM_CLOCK_CNTL_CCU2, 0x00002220},
- {A6XX_RBBM_CLOCK_CNTL_CCU3, 0x00002220},
+ {A6XX_RBBM_CLOCK_CNTL_CCU0, 0x00000000},
+ {A6XX_RBBM_CLOCK_CNTL_CCU1, 0x00000000},
+ {A6XX_RBBM_CLOCK_CNTL_CCU2, 0x00000000},
+ {A6XX_RBBM_CLOCK_CNTL_CCU3, 0x00000000},
{A6XX_RBBM_CLOCK_HYST_RB_CCU0, 0x00040F00},
{A6XX_RBBM_CLOCK_HYST_RB_CCU1, 0x00040F00},
{A6XX_RBBM_CLOCK_HYST_RB_CCU2, 0x00040F00},
{A6XX_RBBM_CLOCK_HYST_RB_CCU3, 0x00040F00},
- {A6XX_RBBM_CLOCK_CNTL_RAC, 0x05022022},
- {A6XX_RBBM_CLOCK_CNTL2_RAC, 0x00005555},
+ {A6XX_RBBM_CLOCK_CNTL_RAC, 0x00022022},
+ {A6XX_RBBM_CLOCK_CNTL2_RAC, 0x00005550},
{A6XX_RBBM_CLOCK_DELAY_RAC, 0x00010011},
{A6XX_RBBM_CLOCK_HYST_RAC, 0x00445044},
- {A6XX_RBBM_CLOCK_CNTL_TSE_RAS_RBBM, 0x04222222},
- {A6XX_RBBM_CLOCK_MODE_GPC, 0x02222222},
+ {A6XX_RBBM_CLOCK_CNTL_TSE_RAS_RBBM, 0x04222220},
+ {A6XX_RBBM_CLOCK_MODE_GPC, 0x00202222},
{A6XX_RBBM_CLOCK_MODE_VFD, 0x00002222},
{A6XX_RBBM_CLOCK_HYST_TSE_RAS_RBBM, 0x00000000},
{A6XX_RBBM_CLOCK_HYST_GPC, 0x04104004},
diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c
index b202b42..7da90c6 100644
--- a/drivers/gpu/msm/kgsl.c
+++ b/drivers/gpu/msm/kgsl.c
@@ -3465,6 +3465,7 @@
return 0;
}
+/* entry->bind_lock must be held by the caller */
static int _sparse_add_to_bind_tree(struct kgsl_mem_entry *entry,
uint64_t v_offset,
struct kgsl_memdesc *memdesc,
@@ -3493,10 +3494,16 @@
parent = *node;
this = rb_entry(parent, struct sparse_bind_object, node);
- if (new->v_off < this->v_off)
+ if ((new->v_off < this->v_off) &&
+ ((new->v_off + new->size) <= this->v_off))
node = &parent->rb_left;
- else if (new->v_off > this->v_off)
+ else if ((new->v_off > this->v_off) &&
+ (new->v_off >= (this->v_off + this->size)))
node = &parent->rb_right;
+ else {
+ kfree(new);
+ return -EADDRINUSE;
+ }
}
rb_link_node(&new->node, parent, node);
@@ -3717,8 +3724,11 @@
return ret;
}
+ spin_lock(&virt_entry->bind_lock);
ret = _sparse_add_to_bind_tree(virt_entry, v_offset, memdesc,
p_offset, size, flags);
+ spin_unlock(&virt_entry->bind_lock);
+
if (ret == 0)
memdesc->cur_bindings += size / PAGE_SIZE;
diff --git a/drivers/gpu/msm/kgsl_pwrctrl.c b/drivers/gpu/msm/kgsl_pwrctrl.c
index cd26ca6..a3fe34e 100644
--- a/drivers/gpu/msm/kgsl_pwrctrl.c
+++ b/drivers/gpu/msm/kgsl_pwrctrl.c
@@ -2485,9 +2485,6 @@
static void kgsl_pwrctrl_disable(struct kgsl_device *device)
{
if (kgsl_gmu_isenabled(device)) {
- struct kgsl_pwrctrl *pwr = &device->pwrctrl;
-
- pwr->active_pwrlevel = pwr->num_pwrlevels - 1;
kgsl_pwrctrl_axi(device, KGSL_PWRFLAGS_OFF);
return gmu_stop(device);
}
diff --git a/drivers/pinctrl/qcom/pinctrl-msm.c b/drivers/pinctrl/qcom/pinctrl-msm.c
index 13e9a0d..e63f1a0 100644
--- a/drivers/pinctrl/qcom/pinctrl-msm.c
+++ b/drivers/pinctrl/qcom/pinctrl-msm.c
@@ -15,6 +15,7 @@
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/io.h>
+#include <linux/irq.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_irq.h>
@@ -747,11 +748,46 @@
.irq_set_wake = msm_gpio_irq_set_wake,
};
+static bool is_gpio_dual_edge(struct irq_data *d, irq_hw_number_t *dir_conn_irq)
+{
+ struct irq_desc *desc = irq_data_to_desc(d);
+ struct irq_data *parent_data = irq_get_irq_data(desc->parent_irq);
+ struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+ struct msm_pinctrl *pctrl = gpiochip_get_data(gc);
+ int i;
+
+ if (!parent_data)
+ return false;
+
+ for (i = 0; i < pctrl->soc->n_dir_conns; i++) {
+ const struct msm_dir_conn *dir_conn = &pctrl->soc->dir_conn[i];
+
+ if (dir_conn->gpio == d->hwirq && (dir_conn->hwirq + 32)
+ != parent_data->hwirq) {
+ *dir_conn_irq = dir_conn->hwirq + 32;
+ return true;
+ }
+ }
+ return false;
+}
+
static void msm_dirconn_irq_mask(struct irq_data *d)
{
struct irq_desc *desc = irq_data_to_desc(d);
struct irq_data *parent_data = irq_get_irq_data(desc->parent_irq);
+ irq_hw_number_t dir_conn_irq = 0;
+ if (!parent_data)
+ return;
+
+ if (is_gpio_dual_edge(d, &dir_conn_irq)) {
+ struct irq_data *dir_conn_data =
+ irq_get_irq_data(irq_find_mapping(parent_data->domain,
+ dir_conn_irq));
+
+ if (dir_conn_data && dir_conn_data->chip->irq_mask)
+ dir_conn_data->chip->irq_mask(dir_conn_data);
+ }
if (parent_data->chip->irq_mask)
parent_data->chip->irq_mask(parent_data);
}
@@ -760,7 +796,19 @@
{
struct irq_desc *desc = irq_data_to_desc(d);
struct irq_data *parent_data = irq_get_irq_data(desc->parent_irq);
+ irq_hw_number_t dir_conn_irq = 0;
+ if (!parent_data)
+ return;
+
+ if (is_gpio_dual_edge(d, &dir_conn_irq)) {
+ struct irq_data *dir_conn_data =
+ irq_get_irq_data(irq_find_mapping(parent_data->domain,
+ dir_conn_irq));
+
+ if (dir_conn_data && dir_conn_data->chip->irq_unmask)
+ dir_conn_data->chip->irq_unmask(dir_conn_data);
+ }
if (parent_data->chip->irq_unmask)
parent_data->chip->irq_unmask(parent_data);
}
@@ -789,6 +837,9 @@
struct irq_desc *desc = irq_data_to_desc(d);
struct irq_data *parent_data = irq_get_irq_data(desc->parent_irq);
+ if (!parent_data)
+ return 0;
+
if (parent_data->chip->irq_set_affinity)
return parent_data->chip->irq_set_affinity(parent_data,
maskval, force);
@@ -807,10 +858,158 @@
return 0;
}
+static void msm_dirconn_cfg_reg(struct irq_data *d, u32 offset)
+{
+ u32 val = 0;
+ const struct msm_pingroup *g;
+ unsigned long flags;
+ struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+ struct msm_pinctrl *pctrl = gpiochip_get_data(gc);
+
+ spin_lock_irqsave(&pctrl->lock, flags);
+ g = &pctrl->soc->groups[d->hwirq];
+
+ val = readl_relaxed(pctrl->regs + g->dir_conn_reg + (offset * 4));
+ val = (d->hwirq) & 0xFF;
+
+ writel_relaxed(val, pctrl->regs + g->dir_conn_reg + (offset * 4));
+
+ //write the dir_conn_en bit
+ val = readl_relaxed(pctrl->regs + g->intr_cfg_reg);
+ val |= BIT(g->dir_conn_en_bit);
+ writel_relaxed(val, pctrl->regs + g->intr_cfg_reg);
+ spin_unlock_irqrestore(&pctrl->lock, flags);
+}
+
+static void msm_dirconn_uncfg_reg(struct irq_data *d, u32 offset)
+{
+ const struct msm_pingroup *g;
+ unsigned long flags;
+ struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+ struct msm_pinctrl *pctrl = gpiochip_get_data(gc);
+
+ spin_lock_irqsave(&pctrl->lock, flags);
+ g = &pctrl->soc->groups[d->hwirq];
+
+ writel_relaxed(BIT(8), pctrl->regs + g->dir_conn_reg + (offset * 4));
+ spin_unlock_irqrestore(&pctrl->lock, flags);
+}
+
+static int select_dir_conn_mux(struct irq_data *d, irq_hw_number_t *irq)
+{
+ struct msm_dir_conn *dc = NULL;
+ struct irq_desc *desc = irq_data_to_desc(d);
+ struct irq_data *parent_data = irq_get_irq_data(desc->parent_irq);
+ struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+ struct msm_pinctrl *pctrl = gpiochip_get_data(gc);
+ int i;
+
+ if (!parent_data)
+ return -EINVAL;
+
+ for (i = 0; i < pctrl->soc->n_dir_conns; i++) {
+ struct msm_dir_conn *dir_conn =
+ (struct msm_dir_conn *)&pctrl->soc->dir_conn[i];
+
+ /* Check if there is already mux assigned for this gpio */
+ if (dir_conn->gpio == d->hwirq && (dir_conn->hwirq + 32) !=
+ parent_data->hwirq) {
+ *irq = dir_conn->hwirq + 32;
+ return pctrl->soc->dir_conn_irq_base - dir_conn->hwirq;
+ }
+
+ if (dir_conn->gpio)
+ continue;
+
+ /* Use the first unused direct connect available */
+ dc = dir_conn;
+ break;
+ }
+
+ if (dc) {
+ *irq = dc->hwirq + 32;
+ dc->gpio = (u32)d->hwirq;
+ return pctrl->soc->dir_conn_irq_base - (u32)dc->hwirq;
+ }
+
+ pr_err("%s: No direct connects available for interrupt %lu\n",
+ __func__, d->hwirq);
+ return -EINVAL;
+}
+
+static void add_dirconn_tlmm(struct irq_data *d, irq_hw_number_t irq)
+{
+ struct irq_desc *desc = irq_data_to_desc(d);
+ struct irq_data *parent_data = irq_get_irq_data(desc->parent_irq);
+ struct irq_data *dir_conn_data = NULL;
+ int offset = 0;
+ unsigned int virt = 0;
+
+ offset = select_dir_conn_mux(d, &irq);
+ if (offset < 0 || !parent_data)
+ return;
+
+ virt = irq_find_mapping(parent_data->domain, irq);
+ msm_dirconn_cfg_reg(d, offset);
+ irq_set_handler_data(virt, d);
+ desc = irq_to_desc(virt);
+ if (!desc)
+ return;
+
+ dir_conn_data = &(desc->irq_data);
+
+ if (dir_conn_data) {
+ if (dir_conn_data->chip && dir_conn_data->chip->irq_set_type)
+ dir_conn_data->chip->irq_set_type(dir_conn_data,
+ IRQ_TYPE_EDGE_RISING);
+ if (dir_conn_data->chip && dir_conn_data->chip->irq_unmask)
+ dir_conn_data->chip->irq_unmask(dir_conn_data);
+ }
+}
+
+static void remove_dirconn_tlmm(struct irq_data *d, irq_hw_number_t irq)
+{
+ struct irq_desc *desc = irq_data_to_desc(d);
+ struct irq_data *parent_data = irq_get_irq_data(desc->parent_irq);
+ struct irq_data *dir_conn_data = NULL;
+ int offset = 0;
+ unsigned int virt = 0;
+
+ virt = irq_find_mapping(parent_data->domain, irq);
+ msm_dirconn_uncfg_reg(d, offset);
+ irq_set_handler_data(virt, NULL);
+ desc = irq_to_desc(virt);
+ if (!desc)
+ return;
+
+ dir_conn_data = &(desc->irq_data);
+
+ if (dir_conn_data) {
+ if (dir_conn_data->chip && dir_conn_data->chip->irq_mask)
+ dir_conn_data->chip->irq_mask(dir_conn_data);
+ }
+}
+
static int msm_dirconn_irq_set_type(struct irq_data *d, unsigned int type)
{
struct irq_desc *desc = irq_data_to_desc(d);
struct irq_data *parent_data = irq_get_irq_data(desc->parent_irq);
+ irq_hw_number_t irq = 0;
+
+ if (!parent_data)
+ return 0;
+
+ if (type == IRQ_TYPE_EDGE_BOTH) {
+ add_dirconn_tlmm(d, irq);
+ } else {
+ if (is_gpio_dual_edge(d, &irq))
+ remove_dirconn_tlmm(d, irq);
+ }
+
+ if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH))
+ irq_set_handler_locked(d, handle_level_irq);
+ else if (type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING))
+ irq_set_handler_locked(d, handle_edge_irq);
if (parent_data->chip->irq_set_type)
return parent_data->chip->irq_set_type(parent_data, type);
@@ -904,14 +1103,19 @@
fwspec.param_count = 3;
parent_irq = irq_create_fwspec_mapping(&fwspec);
- irq = irq_find_mapping(pctrl->chip.irqdomain, dirconn->gpio);
+ if (dirconn->gpio != 0) {
+ irq = irq_find_mapping(pctrl->chip.irqdomain,
+ dirconn->gpio);
- irq_set_parent(irq, parent_irq);
- irq_set_chip(irq, &msm_dirconn_irq_chip);
- irq_set_chip_data(irq, irq_get_irq_data(parent_irq));
- __irq_set_handler(parent_irq, msm_gpio_dirconn_handler,
+ irq_set_parent(irq, parent_irq);
+ irq_set_chip(irq, &msm_dirconn_irq_chip);
+ __irq_set_handler(parent_irq, msm_gpio_dirconn_handler,
false, NULL);
- irq_set_handler_data(parent_irq, irq_get_irq_data(irq));
+ irq_set_handler_data(parent_irq, irq_get_irq_data(irq));
+ } else {
+ __irq_set_handler(parent_irq, msm_gpio_dirconn_handler,
+ false, NULL);
+ }
}
}
diff --git a/drivers/pinctrl/qcom/pinctrl-msm.h b/drivers/pinctrl/qcom/pinctrl-msm.h
index 988b7ca..1c6df2f 100644
--- a/drivers/pinctrl/qcom/pinctrl-msm.h
+++ b/drivers/pinctrl/qcom/pinctrl-msm.h
@@ -43,6 +43,8 @@
* @intr_status_reg: Offset of the register holding the status bits for this group.
* @intr_target_reg: Offset of the register specifying routing of the interrupts
* from this group.
+ * @dir_conn_reg: Offset of the register specifying direct connect
+ * setup of this group.
* @mux_bit: Offset in @ctl_reg for the pinmux function selection.
* @pull_bit: Offset in @ctl_reg for the bias configuration.
* @drv_bit: Offset in @ctl_reg for the drive strength configuration.
@@ -75,6 +77,7 @@
u32 intr_cfg_reg;
u32 intr_status_reg;
u32 intr_target_reg;
+ u32 dir_conn_reg;
unsigned mux_bit:5;
@@ -95,6 +98,7 @@
unsigned intr_polarity_bit:5;
unsigned intr_detection_bit:5;
unsigned intr_detection_width:5;
+ unsigned dir_conn_en_bit:8;
}
/**
@@ -118,6 +122,8 @@
* @ngpio: The number of pingroups the driver should expose as GPIOs.
* @dir_conn: An array describing all the pins directly connected to GIC.
* @ndirconns: The number of pins directly connected to GIC
+ * @dir_conn_offsets: Direct connect register offsets for each tile.
+ * @dir_conn_irq_base: Direct connect interrupt base register for kpss.
*/
struct msm_pinctrl_soc_data {
const struct pinctrl_pin_desc *pins;
@@ -129,6 +135,7 @@
unsigned ngpios;
const struct msm_dir_conn *dir_conn;
unsigned int n_dir_conns;
+ unsigned int dir_conn_irq_base;
};
int msm_pinctrl_probe(struct platform_device *pdev,
diff --git a/drivers/pinctrl/qcom/pinctrl-sdm845-v2.c b/drivers/pinctrl/qcom/pinctrl-sdm845-v2.c
index f7d551e..ed47e11 100644
--- a/drivers/pinctrl/qcom/pinctrl-sdm845-v2.c
+++ b/drivers/pinctrl/qcom/pinctrl-sdm845-v2.c
@@ -53,6 +53,8 @@
.intr_cfg_reg = base + 0x8 + REG_SIZE * id, \
.intr_status_reg = base + 0xc + REG_SIZE * id, \
.intr_target_reg = base + 0x8 + REG_SIZE * id, \
+ .dir_conn_reg = (base == NORTH) ? base + 0xa4000 : \
+ ((base == SOUTH) ? base + 0xa8000 : base + 0x9e000), \
.mux_bit = 2, \
.pull_bit = 0, \
.drv_bit = 6, \
@@ -67,6 +69,7 @@
.intr_polarity_bit = 1, \
.intr_detection_bit = 2, \
.intr_detection_width = 2, \
+ .dir_conn_en_bit = 8, \
}
#define SDC_QDSD_PINGROUP(pg_name, ctl, pull, drv) \
@@ -1747,6 +1750,7 @@
{123, 613},
{124, 614},
{125, 615},
+ {126, 616},
{127, 617},
{128, 618},
{129, 619},
@@ -1754,6 +1758,14 @@
{132, 621},
{133, 622},
{145, 623},
+ {0, 216},
+ {0, 215},
+ {0, 214},
+ {0, 213},
+ {0, 212},
+ {0, 211},
+ {0, 210},
+ {0, 209},
};
static const struct msm_pinctrl_soc_data sdm845_pinctrl = {
@@ -1766,6 +1778,7 @@
.ngpios = 150,
.dir_conn = sdm845_dir_conn,
.n_dir_conns = ARRAY_SIZE(sdm845_dir_conn),
+ .dir_conn_irq_base = 216,
};
static int sdm845_pinctrl_probe(struct platform_device *pdev)
diff --git a/drivers/pinctrl/qcom/pinctrl-sdm845.c b/drivers/pinctrl/qcom/pinctrl-sdm845.c
index b7e06b6..7855531 100644
--- a/drivers/pinctrl/qcom/pinctrl-sdm845.c
+++ b/drivers/pinctrl/qcom/pinctrl-sdm845.c
@@ -52,6 +52,8 @@
.intr_cfg_reg = base + 0x8 + REG_SIZE * id, \
.intr_status_reg = base + 0xc + REG_SIZE * id, \
.intr_target_reg = base + 0x8 + REG_SIZE * id, \
+ .dir_conn_reg = (base == NORTH) ? base + 0xa5000 :\
+ base + 0xa8000, \
.mux_bit = 2, \
.pull_bit = 0, \
.drv_bit = 6, \
@@ -66,6 +68,7 @@
.intr_polarity_bit = 1, \
.intr_detection_bit = 2, \
.intr_detection_width = 2, \
+ .dir_conn_en_bit = 8, \
}
#define SDC_QDSD_PINGROUP(pg_name, ctl, pull, drv) \
@@ -117,6 +120,7 @@
.intr_detection_bit = -1, \
.intr_detection_width = -1, \
}
+
static const struct pinctrl_pin_desc sdm845_pins[] = {
PINCTRL_PIN(0, "GPIO_0"),
PINCTRL_PIN(1, "GPIO_1"),
@@ -1648,7 +1652,7 @@
[153] = UFS_RESET(ufs_reset, 0x99f000),
};
-static const struct msm_dir_conn sdm845_dir_conn[] = {
+static struct msm_dir_conn sdm845_dir_conn[] = {
{1, 510},
{3, 511},
{5, 512},
@@ -1717,6 +1721,7 @@
{123, 613},
{124, 614},
{125, 615},
+ {126, 616},
{127, 617},
{128, 618},
{129, 619},
@@ -1724,6 +1729,14 @@
{132, 621},
{133, 622},
{145, 623},
+ {0, 216},
+ {0, 215},
+ {0, 214},
+ {0, 213},
+ {0, 212},
+ {0, 211},
+ {0, 210},
+ {0, 209},
};
static const struct msm_pinctrl_soc_data sdm845_pinctrl = {
@@ -1736,6 +1749,7 @@
.ngpios = 150,
.dir_conn = sdm845_dir_conn,
.n_dir_conns = ARRAY_SIZE(sdm845_dir_conn),
+ .dir_conn_irq_base = 216,
};
static int sdm845_pinctrl_probe(struct platform_device *pdev)
diff --git a/drivers/scsi/ufs/ufs-qcom.c b/drivers/scsi/ufs/ufs-qcom.c
index ee23fc7..afda4c9 100644
--- a/drivers/scsi/ufs/ufs-qcom.c
+++ b/drivers/scsi/ufs/ufs-qcom.c
@@ -1987,6 +1987,18 @@
}
#endif /* CONFIG_SMP */
+#define ANDROID_BOOT_DEV_MAX 30
+static char android_boot_dev[ANDROID_BOOT_DEV_MAX];
+
+#ifndef MODULE
+static int __init get_android_boot_dev(char *str)
+{
+ strlcpy(android_boot_dev, str, ANDROID_BOOT_DEV_MAX);
+ return 1;
+}
+__setup("androidboot.bootdevice=", get_android_boot_dev);
+#endif
+
/*
* ufs_qcom_parse_lpm - read from DTS whether LPM modes should be disabled.
*/
@@ -2676,6 +2688,24 @@
{
int err;
struct device *dev = &pdev->dev;
+ struct device_node *np = dev->of_node;
+
+ /*
+ * On qcom platforms, bootdevice is the primary storage
+ * device. This device can either be eMMC or UFS.
+ * The type of device connected is detected at runtime.
+ * So, if an eMMC device is connected, and this function
+ * is invoked, it would turn-off the regulator if it detects
+ * that the storage device is not ufs.
+ * These regulators are turned ON by the bootloaders & turning
+ * them off without sending PON may damage the connected device.
+ * Hence, check for the connected device early-on & don't turn-off
+ * the regulators.
+ */
+ if (of_property_read_bool(np, "non-removable") &&
+ strlen(android_boot_dev) &&
+ strcmp(android_boot_dev, dev_name(dev)))
+ return -ENODEV;
/* Perform generic probe */
err = ufshcd_pltfrm_init(pdev, &ufs_hba_qcom_variant);
diff --git a/drivers/soc/qcom/rpm_stats.c b/drivers/soc/qcom/rpm_stats.c
index a3fe7b3..e60a7ad 100644
--- a/drivers/soc/qcom/rpm_stats.c
+++ b/drivers/soc/qcom/rpm_stats.c
@@ -173,7 +173,7 @@
if (prvdata.read_idx < prvdata.num_records)
prvdata.len = msm_rpmstats_copy_stats(&prvdata);
- return snprintf(buf, prvdata.len, prvdata.buf);
+ return snprintf(buf, prvdata.len, "%s", prvdata.buf);
}
static int msm_rpmstats_create_sysfs(struct msm_rpmstats_platform_data *pd)
diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c
index ccdf543..351f9a2 100644
--- a/drivers/usb/dwc3/dwc3-msm.c
+++ b/drivers/usb/dwc3/dwc3-msm.c
@@ -3956,20 +3956,20 @@
union power_supply_propval pval = {0};
int ret, psy_type;
- if (mdwc->max_power == mA)
- return 0;
-
psy_type = get_psy_type(mdwc);
- if (psy_type == POWER_SUPPLY_TYPE_USB) {
- dev_info(mdwc->dev, "Avail curr from USB = %u\n", mA);
- /* Set max current limit in uA */
- pval.intval = 1000 * mA;
- } else if (psy_type == POWER_SUPPLY_TYPE_USB_FLOAT) {
+ if (psy_type == POWER_SUPPLY_TYPE_USB_FLOAT) {
pval.intval = -ETIMEDOUT;
- } else {
- return 0;
+ goto set_prop;
}
+ if (mdwc->max_power == mA || psy_type != POWER_SUPPLY_TYPE_USB)
+ return 0;
+
+ dev_info(mdwc->dev, "Avail curr from USB = %u\n", mA);
+ /* Set max current limit in uA */
+ pval.intval = 1000 * mA;
+
+set_prop:
ret = power_supply_set_property(mdwc->usb_psy,
POWER_SUPPLY_PROP_SDP_CURRENT_MAX, &pval);
if (ret) {
diff --git a/drivers/usb/gadget/function/f_gsi.c b/drivers/usb/gadget/function/f_gsi.c
index c11629d..76e0a32 100644
--- a/drivers/usb/gadget/function/f_gsi.c
+++ b/drivers/usb/gadget/function/f_gsi.c
@@ -19,7 +19,14 @@
MODULE_PARM_DESC(qti_packet_debug, "Print QTI Packet's Raw Data");
static struct workqueue_struct *ipa_usb_wq;
+static struct gsi_inst_status {
+ struct mutex gsi_lock;
+ bool inst_exist;
+ struct gsi_opts *opts;
+} inst_status[IPA_USB_MAX_TETH_PROT_SIZE];
+/* Deregister misc device and free instance structures */
+static void gsi_inst_clean(struct gsi_opts *opts);
static void gsi_rndis_ipa_reset_trigger(struct gsi_data_port *d_port);
static void ipa_disconnect_handler(struct gsi_data_port *d_port);
static int gsi_ctrl_send_notification(struct f_gsi *gsi);
@@ -919,40 +926,69 @@
struct gsi_ctrl_port *c_port = container_of(fp->private_data,
struct gsi_ctrl_port,
ctrl_device);
- struct f_gsi *gsi = c_port_to_gsi(c_port);
+ struct f_gsi *gsi;
+ struct gsi_inst_status *inst_cur;
if (!c_port) {
- log_event_err("%s: gsi ctrl port %p", __func__, c_port);
+ pr_err_ratelimited("%s: gsi ctrl port %p", __func__, c_port);
return -ENODEV;
}
+ gsi = container_of(c_port, struct f_gsi, c_port);
+ inst_cur = &inst_status[gsi->prot_id];
log_event_dbg("%s: open ctrl dev %s", __func__, c_port->name);
+ mutex_lock(&inst_cur->gsi_lock);
+
+ fp->private_data = &gsi->prot_id;
+
+ if (!inst_cur->inst_exist) {
+ mutex_unlock(&inst_cur->gsi_lock);
+ log_event_err("%s: [prot_id = %d], GSI instance freed already\n",
+ __func__, gsi->prot_id);
+ return -ENODEV;
+ }
+
if (c_port->is_open) {
- log_event_err("%s: Already opened", __func__);
+ mutex_unlock(&inst_cur->gsi_lock);
+ log_event_err("%s: Already opened\n", __func__);
return -EBUSY;
}
c_port->is_open = true;
+ mutex_unlock(&inst_cur->gsi_lock);
+
return 0;
}
static int gsi_ctrl_dev_release(struct inode *ip, struct file *fp)
{
- struct gsi_ctrl_port *c_port = container_of(fp->private_data,
- struct gsi_ctrl_port,
- ctrl_device);
- struct f_gsi *gsi = c_port_to_gsi(c_port);
+ enum ipa_usb_teth_prot prot_id =
+ *(enum ipa_usb_teth_prot *)(fp->private_data);
+ struct gsi_inst_status *inst_cur = &inst_status[prot_id];
+ struct f_gsi *gsi;
- if (!c_port) {
- log_event_err("%s: gsi ctrl port %p", __func__, c_port);
+ mutex_lock(&inst_cur->gsi_lock);
+
+ if (unlikely(inst_cur->inst_exist == false)) {
+ if (inst_cur->opts) {
+ /* GSI instance clean up */
+ gsi_inst_clean(inst_cur->opts);
+ inst_cur->opts = NULL;
+ }
+ mutex_unlock(&inst_cur->gsi_lock);
+ pr_err_ratelimited("%s: prot_id:%d: delayed free memory\n",
+ __func__, prot_id);
return -ENODEV;
}
- log_event_dbg("close ctrl dev %s", c_port->name);
+ inst_cur->opts->gsi->c_port.is_open = false;
+ gsi = inst_cur->opts->gsi;
+ mutex_unlock(&inst_cur->gsi_lock);
- c_port->is_open = false;
+ log_event_dbg("close ctrl dev %s\n",
+ inst_cur->opts->gsi->c_port.name);
return 0;
}
@@ -960,16 +996,28 @@
static ssize_t
gsi_ctrl_dev_read(struct file *fp, char __user *buf, size_t count, loff_t *pos)
{
- struct gsi_ctrl_port *c_port = container_of(fp->private_data,
- struct gsi_ctrl_port,
- ctrl_device);
- struct f_gsi *gsi = c_port_to_gsi(c_port);
+ struct gsi_ctrl_port *c_port;
struct gsi_ctrl_pkt *cpkt = NULL;
+ enum ipa_usb_teth_prot prot_id =
+ *(enum ipa_usb_teth_prot *)(fp->private_data);
+ struct gsi_inst_status *inst_cur = &inst_status[prot_id];
+ struct f_gsi *gsi;
unsigned long flags;
int ret = 0;
- log_event_dbg("%s: Enter %zu", __func__, count);
+ pr_debug("%s: Enter %zu", __func__, count);
+ mutex_lock(&inst_cur->gsi_lock);
+ if (unlikely(inst_cur->inst_exist == false)) {
+ mutex_unlock(&inst_cur->gsi_lock);
+ pr_err_ratelimited("%s: free_inst is called and being freed\n",
+ __func__);
+ return -ENODEV;
+ }
+ mutex_unlock(&inst_cur->gsi_lock);
+
+ gsi = inst_cur->opts->gsi;
+ c_port = &inst_cur->opts->gsi->c_port;
if (!c_port) {
log_event_err("%s: gsi ctrl port %p", __func__, c_port);
return -ENODEV;
@@ -1037,13 +1085,27 @@
int ret = 0;
unsigned long flags;
struct gsi_ctrl_pkt *cpkt;
- struct gsi_ctrl_port *c_port = container_of(fp->private_data,
- struct gsi_ctrl_port,
- ctrl_device);
- struct f_gsi *gsi = c_port_to_gsi(c_port);
- struct usb_request *req = c_port->notify_req;
+ struct gsi_ctrl_port *c_port;
+ struct usb_request *req;
+ enum ipa_usb_teth_prot prot_id =
+ *(enum ipa_usb_teth_prot *)(fp->private_data);
+ struct gsi_inst_status *inst_cur = &inst_status[prot_id];
+ struct f_gsi *gsi;
- log_event_dbg("Enter %zu", count);
+ pr_debug("Enter %zu", count);
+
+ mutex_lock(&inst_cur->gsi_lock);
+ if (unlikely(inst_cur->inst_exist == false)) {
+ mutex_unlock(&inst_cur->gsi_lock);
+ pr_err_ratelimited("%s: free_inst is called and being freed\n",
+ __func__);
+ return -ENODEV;
+ }
+ mutex_unlock(&inst_cur->gsi_lock);
+
+ gsi = inst_cur->opts->gsi;
+ c_port = &gsi->c_port;
+ req = c_port->notify_req;
if (!c_port || !req || !req->buf) {
log_event_err("%s: c_port %p req %p req->buf %p",
@@ -1101,15 +1163,28 @@
static long gsi_ctrl_dev_ioctl(struct file *fp, unsigned int cmd,
unsigned long arg)
{
- struct gsi_ctrl_port *c_port = container_of(fp->private_data,
- struct gsi_ctrl_port,
- ctrl_device);
- struct f_gsi *gsi = c_port_to_gsi(c_port);
+ struct gsi_ctrl_port *c_port;
+ struct f_gsi *gsi;
struct gsi_ctrl_pkt *cpkt;
struct ep_info info;
+ enum ipa_usb_teth_prot prot_id =
+ *(enum ipa_usb_teth_prot *)(fp->private_data);
+ struct gsi_inst_status *inst_cur = &inst_status[prot_id];
int val, ret = 0;
unsigned long flags;
+ mutex_lock(&inst_cur->gsi_lock);
+ if (unlikely(inst_cur->inst_exist == false)) {
+ mutex_unlock(&inst_cur->gsi_lock);
+ pr_err_ratelimited("%s: free_inst is called and being freed\n",
+ __func__);
+ return -ENODEV;
+ }
+ mutex_unlock(&inst_cur->gsi_lock);
+
+ gsi = inst_cur->opts->gsi;
+ c_port = &gsi->c_port;
+
if (!c_port) {
log_event_err("%s: gsi ctrl port %p", __func__, c_port);
return -ENODEV;
@@ -1230,13 +1305,25 @@
static unsigned int gsi_ctrl_dev_poll(struct file *fp, poll_table *wait)
{
- struct gsi_ctrl_port *c_port = container_of(fp->private_data,
- struct gsi_ctrl_port,
- ctrl_device);
- struct f_gsi *gsi = c_port_to_gsi(c_port);
+ struct gsi_ctrl_port *c_port;
+ enum ipa_usb_teth_prot prot_id =
+ *(enum ipa_usb_teth_prot *)(fp->private_data);
+ struct gsi_inst_status *inst_cur = &inst_status[prot_id];
+ struct f_gsi *gsi;
unsigned long flags;
unsigned int mask = 0;
+ mutex_lock(&inst_cur->gsi_lock);
+ if (unlikely(inst_cur->inst_exist == false)) {
+ mutex_unlock(&inst_cur->gsi_lock);
+ pr_err_ratelimited("%s: free_inst is called and being freed\n",
+ __func__);
+ return -ENODEV;
+ }
+ mutex_unlock(&inst_cur->gsi_lock);
+
+ gsi = inst_cur->opts->gsi;
+ c_port = &inst_cur->opts->gsi->c_port;
if (!c_port) {
log_event_err("%s: gsi ctrl port %p", __func__, c_port);
return -ENODEV;
@@ -2827,7 +2914,11 @@
static void gsi_opts_release(struct config_item *item)
{
struct gsi_opts *opts = to_gsi_opts(item);
+ struct f_gsi *gsi;
+ gsi = opts->gsi;
+ log_event_dbg("%s: releasing %s instance\n",
+ __func__, gsi->function.name);
usb_put_function_instance(&opts->func_inst);
}
@@ -2991,26 +3082,52 @@
.ct_owner = THIS_MODULE,
};
+static void gsi_inst_clean(struct gsi_opts *opts)
+{
+ if (opts->gsi->c_port.ctrl_device.fops)
+ misc_deregister(&opts->gsi->c_port.ctrl_device);
+
+ kfree(opts->gsi);
+ kfree(opts);
+}
+
static int gsi_set_inst_name(struct usb_function_instance *fi,
const char *name)
{
- int ret, name_len;
+ int prot_id, name_len;
struct f_gsi *gsi;
char gsi_inst_name[MAX_INST_NAME_LEN + sizeof("gsi.") + 1];
- struct gsi_opts *opts = container_of(fi, struct gsi_opts, func_inst);
void *ipc_log_ctxt;
+ struct gsi_opts *opts, *opts_prev;
+
+ opts = container_of(fi, struct gsi_opts, func_inst);
name_len = strlen(name) + 1;
if (name_len > MAX_INST_NAME_LEN)
return -ENAMETOOLONG;
- ret = name_to_prot_id(name);
- if (ret < 0) {
+ prot_id = name_to_prot_id(name);
+ if (prot_id < 0) {
pr_err("%s: failed to find prot id for %s instance\n",
- __func__, name);
+ __func__, name);
return -EINVAL;
}
+ mutex_lock(&inst_status[prot_id].gsi_lock);
+ opts_prev = inst_status[prot_id].opts;
+ if (opts_prev) {
+ mutex_unlock(&inst_status[prot_id].gsi_lock);
+ pr_err("%s: prot_id = %d, prev inst do not freed yet\n",
+ __func__, prot_id);
+ return -EBUSY;
+ }
+ mutex_unlock(&inst_status[prot_id].gsi_lock);
+
+ gsi = gsi_function_init(prot_id);
+ if (IS_ERR(gsi))
+ return PTR_ERR(gsi);
+
+ opts->gsi = gsi;
/*
* create instance name with prefixing "gsi." to differentiate
* ipc log debugfs entry
@@ -3020,31 +3137,45 @@
if (!ipc_log_ctxt)
pr_err("%s: Err allocating ipc_log_ctxt for prot:%s\n",
__func__, gsi_inst_name);
-
- gsi = gsi_function_init(ret);
- if (IS_ERR(gsi)) {
- ipc_log_context_destroy(ipc_log_ctxt);
- return PTR_ERR(gsi);
- }
-
- opts->gsi = gsi;
opts->gsi->ipc_log_ctxt = ipc_log_ctxt;
+
+ /* Set instance status */
+ mutex_lock(&inst_status[prot_id].gsi_lock);
+ inst_status[prot_id].inst_exist = true;
+ inst_status[prot_id].opts = opts;
+ mutex_unlock(&inst_status[prot_id].gsi_lock);
+
return 0;
}
static void gsi_free_inst(struct usb_function_instance *f)
{
struct gsi_opts *opts = container_of(f, struct gsi_opts, func_inst);
+ enum ipa_usb_teth_prot prot_id;
+ struct f_gsi *gsi;
if (!opts->gsi)
return;
- if (opts->gsi->c_port.ctrl_device.fops)
- misc_deregister(&opts->gsi->c_port.ctrl_device);
+ prot_id = opts->gsi->prot_id;
+ gsi = opts->gsi;
+ mutex_lock(&inst_status[prot_id].gsi_lock);
+ if (opts->gsi->c_port.is_open) {
+ /* Mark instance exist as false */
+ inst_status[prot_id].inst_exist = false;
+ mutex_unlock(&inst_status[prot_id].gsi_lock);
+ log_event_err(
+ "%s: [prot_id = %d] Dev is open, free mem when dev close\n",
+ __func__, prot_id);
+ return;
+ }
ipc_log_context_destroy(opts->gsi->ipc_log_ctxt);
- kfree(opts->gsi);
- kfree(opts);
+ /* Clear instance status */
+ gsi_inst_clean(opts);
+ inst_status[prot_id].inst_exist = false;
+ inst_status[prot_id].opts = NULL;
+ mutex_unlock(&inst_status[prot_id].gsi_lock);
}
static struct usb_function_instance *gsi_alloc_inst(void)
@@ -3058,7 +3189,7 @@
opts->func_inst.set_inst_name = gsi_set_inst_name;
opts->func_inst.free_func_inst = gsi_free_inst;
config_group_init_type_name(&opts->func_inst.group, "",
- &gsi_func_type);
+ &gsi_func_type);
return &opts->func_inst;
}
@@ -3083,6 +3214,8 @@
static int fgsi_init(void)
{
+ int i;
+
ipa_usb_wq = alloc_workqueue("k_ipa_usb",
WQ_UNBOUND | WQ_MEM_RECLAIM | WQ_FREEZABLE, 1);
if (!ipa_usb_wq) {
@@ -3090,6 +3223,9 @@
return -ENOMEM;
}
+ for (i = 0; i < IPA_USB_MAX_TETH_PROT_SIZE; i++)
+ mutex_init(&inst_status[i].gsi_lock);
+
return usb_function_register(&gsiusb_func);
}
module_init(fgsi_init);
diff --git a/include/linux/cpu.h b/include/linux/cpu.h
index 40b66f9..e0aa720 100644
--- a/include/linux/cpu.h
+++ b/include/linux/cpu.h
@@ -194,6 +194,7 @@
extern void cpu_hotplug_begin(void);
extern void cpu_hotplug_done(void);
extern void get_online_cpus(void);
+extern void cpu_hotplug_mutex_held(void);
extern void put_online_cpus(void);
extern void cpu_hotplug_disable(void);
extern void cpu_hotplug_enable(void);
@@ -216,6 +217,7 @@
#define cpu_hotplug_enable() do { } while (0)
#define hotcpu_notifier(fn, pri) do { (void)(fn); } while (0)
#define __hotcpu_notifier(fn, pri) do { (void)(fn); } while (0)
+#define cpu_hotplug_mutex_held() do { } while (0)
/* These aren't inline functions due to a GCC bug. */
#define register_hotcpu_notifier(nb) ({ (void)(nb); 0; })
#define __register_hotcpu_notifier(nb) ({ (void)(nb); 0; })
diff --git a/include/trace/events/power.h b/include/trace/events/power.h
index cecfb8f..b94e493 100644
--- a/include/trace/events/power.h
+++ b/include/trace/events/power.h
@@ -702,9 +702,10 @@
TRACE_EVENT(memlat_dev_meas,
TP_PROTO(const char *name, unsigned int dev_id, unsigned long inst,
- unsigned long mem, unsigned long freq, unsigned int ratio),
+ unsigned long mem, unsigned long freq, unsigned int stall,
+ unsigned int ratio),
- TP_ARGS(name, dev_id, inst, mem, freq, ratio),
+ TP_ARGS(name, dev_id, inst, mem, freq, stall, ratio),
TP_STRUCT__entry(
__string(name, name)
@@ -712,6 +713,7 @@
__field(unsigned long, inst)
__field(unsigned long, mem)
__field(unsigned long, freq)
+ __field(unsigned int, stall)
__field(unsigned int, ratio)
),
@@ -721,15 +723,17 @@
__entry->inst = inst;
__entry->mem = mem;
__entry->freq = freq;
+ __entry->stall = stall;
__entry->ratio = ratio;
),
- TP_printk("dev: %s, id=%u, inst=%lu, mem=%lu, freq=%lu, ratio=%u",
+ TP_printk("dev: %s, id=%u, inst=%lu, mem=%lu, freq=%lu, stall=%u, ratio=%u",
__get_str(name),
__entry->dev_id,
__entry->inst,
__entry->mem,
__entry->freq,
+ __entry->stall,
__entry->ratio)
);
diff --git a/kernel/cpu.c b/kernel/cpu.c
index 69dc428..d2df1ce 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -239,6 +239,11 @@
#define cpuhp_lock_acquire() lock_map_acquire(&cpu_hotplug.dep_map)
#define cpuhp_lock_release() lock_map_release(&cpu_hotplug.dep_map)
+void cpu_hotplug_mutex_held(void)
+{
+ lockdep_assert_held(&cpu_hotplug.lock);
+}
+EXPORT_SYMBOL(cpu_hotplug_mutex_held);
void get_online_cpus(void)
{
diff --git a/kernel/cpuset.c b/kernel/cpuset.c
index d3a7411..cbf240d 100644
--- a/kernel/cpuset.c
+++ b/kernel/cpuset.c
@@ -808,16 +808,15 @@
* 'cpus' is removed, then call this routine to rebuild the
* scheduler's dynamic sched domains.
*
- * Call with cpuset_mutex held. Takes get_online_cpus().
*/
-static void rebuild_sched_domains_locked(void)
+static void rebuild_sched_domains_unlocked(void)
{
struct sched_domain_attr *attr;
cpumask_var_t *doms;
int ndoms;
+ cpu_hotplug_mutex_held();
lockdep_assert_held(&cpuset_mutex);
- get_online_cpus();
/*
* We have raced with CPU hotplug. Don't do anything to avoid
@@ -825,27 +824,27 @@
* Anyways, hotplug work item will rebuild sched domains.
*/
if (!cpumask_equal(top_cpuset.effective_cpus, cpu_active_mask))
- goto out;
+ return;
/* Generate domain masks and attrs */
ndoms = generate_sched_domains(&doms, &attr);
/* Have scheduler rebuild the domains */
partition_sched_domains(ndoms, doms, attr);
-out:
- put_online_cpus();
}
#else /* !CONFIG_SMP */
-static void rebuild_sched_domains_locked(void)
+static void rebuild_sched_domains_unlocked(void)
{
}
#endif /* CONFIG_SMP */
void rebuild_sched_domains(void)
{
+ get_online_cpus();
mutex_lock(&cpuset_mutex);
- rebuild_sched_domains_locked();
+ rebuild_sched_domains_unlocked();
mutex_unlock(&cpuset_mutex);
+ put_online_cpus();
}
/**
@@ -877,7 +876,6 @@
*
* On legacy hierachy, effective_cpus will be the same with cpu_allowed.
*
- * Called with cpuset_mutex held
*/
static void update_cpumasks_hier(struct cpuset *cs, struct cpumask *new_cpus)
{
@@ -932,7 +930,7 @@
rcu_read_unlock();
if (need_rebuild_sched_domains)
- rebuild_sched_domains_locked();
+ rebuild_sched_domains_unlocked();
}
/**
@@ -1282,7 +1280,7 @@
cs->relax_domain_level = val;
if (!cpumask_empty(cs->cpus_allowed) &&
is_sched_load_balance(cs))
- rebuild_sched_domains_locked();
+ rebuild_sched_domains_unlocked();
}
return 0;
@@ -1313,7 +1311,6 @@
* cs: the cpuset to update
* turning_on: whether the flag is being set or cleared
*
- * Call with cpuset_mutex held.
*/
static int update_flag(cpuset_flagbits_t bit, struct cpuset *cs,
@@ -1348,7 +1345,7 @@
spin_unlock_irq(&callback_lock);
if (!cpumask_empty(trialcs->cpus_allowed) && balance_flag_changed)
- rebuild_sched_domains_locked();
+ rebuild_sched_domains_unlocked();
if (spread_flag_changed)
update_tasks_flags(cs);
@@ -1616,6 +1613,7 @@
cpuset_filetype_t type = cft->private;
int retval = 0;
+ get_online_cpus();
mutex_lock(&cpuset_mutex);
if (!is_cpuset_online(cs)) {
retval = -ENODEV;
@@ -1653,6 +1651,7 @@
}
out_unlock:
mutex_unlock(&cpuset_mutex);
+ put_online_cpus();
return retval;
}
@@ -1663,6 +1662,7 @@
cpuset_filetype_t type = cft->private;
int retval = -ENODEV;
+ get_online_cpus();
mutex_lock(&cpuset_mutex);
if (!is_cpuset_online(cs))
goto out_unlock;
@@ -1677,6 +1677,7 @@
}
out_unlock:
mutex_unlock(&cpuset_mutex);
+ put_online_cpus();
return retval;
}
@@ -1715,6 +1716,7 @@
kernfs_break_active_protection(of->kn);
flush_work(&cpuset_hotplug_work);
+ get_online_cpus();
mutex_lock(&cpuset_mutex);
if (!is_cpuset_online(cs))
goto out_unlock;
@@ -1740,6 +1742,7 @@
free_trial_cpuset(trialcs);
out_unlock:
mutex_unlock(&cpuset_mutex);
+ put_online_cpus();
kernfs_unbreak_active_protection(of->kn);
css_put(&cs->css);
flush_workqueue(cpuset_migrate_mm_wq);
@@ -2046,13 +2049,14 @@
/*
* If the cpuset being removed has its flag 'sched_load_balance'
* enabled, then simulate turning sched_load_balance off, which
- * will call rebuild_sched_domains_locked().
+ * will call rebuild_sched_domains_unlocked().
*/
static void cpuset_css_offline(struct cgroup_subsys_state *css)
{
struct cpuset *cs = css_cs(css);
+ get_online_cpus();
mutex_lock(&cpuset_mutex);
if (is_sched_load_balance(cs))
@@ -2062,6 +2066,7 @@
clear_bit(CS_ONLINE, &cs->flags);
mutex_unlock(&cpuset_mutex);
+ put_online_cpus();
}
static void cpuset_css_free(struct cgroup_subsys_state *css)
diff --git a/kernel/locking/osq_lock.c b/kernel/locking/osq_lock.c
index 05a3785..99b8d99 100644
--- a/kernel/locking/osq_lock.c
+++ b/kernel/locking/osq_lock.c
@@ -1,6 +1,7 @@
#include <linux/percpu.h>
#include <linux/sched.h>
#include <linux/osq_lock.h>
+#include <linux/sched/rt.h>
/*
* An MCS like lock especially tailored for optimistic spinning for sleeping
@@ -85,6 +86,7 @@
{
struct optimistic_spin_node *node = this_cpu_ptr(&osq_node);
struct optimistic_spin_node *prev, *next;
+ struct task_struct *task = current;
int curr = encode_cpu(smp_processor_id());
int old;
@@ -118,8 +120,13 @@
while (!READ_ONCE(node->locked)) {
/*
* If we need to reschedule bail... so we can block.
+ * If a task spins on owner on a CPU after acquiring
+ * osq_lock while a RT task spins on another CPU to
+ * acquire osq_lock, it will starve the owner from
+ * completing if owner is to be scheduled on the same CPU.
+ * It will be a live lock.
*/
- if (need_resched())
+ if (need_resched() || rt_task(task))
goto unqueue;
cpu_relax_lowlatency();
diff --git a/kernel/sched/cpufreq_schedutil.c b/kernel/sched/cpufreq_schedutil.c
index 2eb966c..f27d47f 100644
--- a/kernel/sched/cpufreq_schedutil.c
+++ b/kernel/sched/cpufreq_schedutil.c
@@ -86,6 +86,7 @@
static DEFINE_PER_CPU(struct sugov_cpu, sugov_cpu);
static unsigned int stale_ns;
+static DEFINE_PER_CPU(struct sugov_tunables *, cached_tunables);
/************************ Governor internals ***********************/
@@ -681,6 +682,31 @@
return tunables;
}
+static void sugov_tunables_save(struct cpufreq_policy *policy,
+ struct sugov_tunables *tunables)
+{
+ int cpu;
+ struct sugov_tunables *cached = per_cpu(cached_tunables, policy->cpu);
+
+ if (!have_governor_per_policy())
+ return;
+
+ if (!cached) {
+ cached = kzalloc(sizeof(*tunables), GFP_KERNEL);
+ if (!cached) {
+ pr_warn("Couldn't allocate tunables for caching\n");
+ return;
+ }
+ for_each_cpu(cpu, policy->related_cpus)
+ per_cpu(cached_tunables, cpu) = cached;
+ }
+
+ cached->pl = tunables->pl;
+ cached->hispeed_load = tunables->hispeed_load;
+ cached->hispeed_freq = tunables->hispeed_freq;
+ cached->rate_limit_us = tunables->rate_limit_us;
+}
+
static void sugov_tunables_free(struct sugov_tunables *tunables)
{
if (!have_governor_per_policy())
@@ -689,6 +715,23 @@
kfree(tunables);
}
+static void sugov_tunables_restore(struct cpufreq_policy *policy)
+{
+ struct sugov_policy *sg_policy = policy->governor_data;
+ struct sugov_tunables *tunables = sg_policy->tunables;
+ struct sugov_tunables *cached = per_cpu(cached_tunables, policy->cpu);
+
+ if (!cached)
+ return;
+
+ tunables->pl = cached->pl;
+ tunables->hispeed_load = cached->hispeed_load;
+ tunables->hispeed_freq = cached->hispeed_freq;
+ tunables->rate_limit_us = cached->rate_limit_us;
+ sg_policy->freq_update_delay_ns =
+ tunables->rate_limit_us * NSEC_PER_USEC;
+}
+
static int sugov_init(struct cpufreq_policy *policy)
{
struct sugov_policy *sg_policy;
@@ -743,6 +786,8 @@
sg_policy->tunables = tunables;
stale_ns = sched_ravg_window + (sched_ravg_window >> 3);
+ sugov_tunables_restore(policy);
+
ret = kobject_init_and_add(&tunables->attr_set.kobj, &sugov_tunables_ktype,
get_governor_parent_kobj(policy), "%s",
schedutil_gov.name);
@@ -782,8 +827,10 @@
count = gov_attr_set_put(&tunables->attr_set, &sg_policy->tunables_hook);
policy->governor_data = NULL;
- if (!count)
+ if (!count) {
+ sugov_tunables_save(policy, tunables);
sugov_tunables_free(tunables);
+ }
mutex_unlock(&global_tunables_lock);