Merge "ARM: dts: msm: Increase QSEECOM heap size to 13 MB"
diff --git a/Documentation/devicetree/bindings/power/qpnp-charger.txt b/Documentation/devicetree/bindings/power/qpnp-charger.txt
index 5425c92..584a76d 100644
--- a/Documentation/devicetree/bindings/power/qpnp-charger.txt
+++ b/Documentation/devicetree/bindings/power/qpnp-charger.txt
@@ -93,6 +93,10 @@
set, the charger ovp status is monitored in software.
- qcom,ext-ovp-present Indicates if an external OVP exists which reduces the
overall input resistance of the charge path.
+- qcom,power-stage-reduced Indicates if power stage workaround is enabled. This work
+ around reduces the power stage segments while charging
+ under high load during low battery voltages. It's for
+ improving IADC accuracy while board has a bad layout.
Sub node required structure:
- A qcom,chg node must be a child of an SPMI node that has specified
diff --git a/arch/arm/boot/dts/apq8026-v1-cdp.dts b/arch/arm/boot/dts/apq8026-v1-cdp.dts
index d7e283b..b9ec6f9 100644
--- a/arch/arm/boot/dts/apq8026-v1-cdp.dts
+++ b/arch/arm/boot/dts/apq8026-v1-cdp.dts
@@ -13,7 +13,7 @@
/dts-v1/;
/include/ "apq8026-v1.dtsi"
-/include/ "msm8226-cdp.dtsi"
+/include/ "msm8226-720p-cdp.dtsi"
/ {
model = "Qualcomm APQ 8026 CDP";
diff --git a/arch/arm/boot/dts/apq8026-v1-mtp.dts b/arch/arm/boot/dts/apq8026-v1-mtp.dts
index d24875c..c2fc72c 100644
--- a/arch/arm/boot/dts/apq8026-v1-mtp.dts
+++ b/arch/arm/boot/dts/apq8026-v1-mtp.dts
@@ -13,7 +13,7 @@
/dts-v1/;
/include/ "apq8026-v1.dtsi"
-/include/ "msm8226-mtp.dtsi"
+/include/ "msm8226-720p-mtp.dtsi"
/ {
model = "Qualcomm APQ 8026 MTP";
diff --git a/arch/arm/boot/dts/apq8026-v1-xpm.dts b/arch/arm/boot/dts/apq8026-v1-xpm.dts
index f69511b..b435018 100644
--- a/arch/arm/boot/dts/apq8026-v1-xpm.dts
+++ b/arch/arm/boot/dts/apq8026-v1-xpm.dts
@@ -13,7 +13,7 @@
/dts-v1/;
/include/ "apq8026-v1.dtsi"
-/include/ "msm8226-cdp.dtsi"
+/include/ "msm8226-720p-cdp.dtsi"
/ {
model = "Qualcomm APQ 8026 XPM";
diff --git a/arch/arm/boot/dts/apq8026-v2-cdp.dts b/arch/arm/boot/dts/apq8026-v2-1080p-cdp.dts
similarity index 91%
copy from arch/arm/boot/dts/apq8026-v2-cdp.dts
copy to arch/arm/boot/dts/apq8026-v2-1080p-cdp.dts
index cb68779..5294628 100644
--- a/arch/arm/boot/dts/apq8026-v2-cdp.dts
+++ b/arch/arm/boot/dts/apq8026-v2-1080p-cdp.dts
@@ -13,10 +13,10 @@
/dts-v1/;
/include/ "apq8026-v2.dtsi"
-/include/ "msm8226-cdp.dtsi"
+/include/ "msm8226-1080p-cdp.dtsi"
/ {
model = "Qualcomm APQ 8026v2 CDP";
compatible = "qcom,apq8026-cdp", "qcom,apq8026", "qcom,cdp";
- qcom,board-id = <1 0>;
+ qcom,board-id = <1 2>;
};
diff --git a/arch/arm/boot/dts/apq8026-v2-mtp.dts b/arch/arm/boot/dts/apq8026-v2-1080p-mtp.dts
similarity index 91%
copy from arch/arm/boot/dts/apq8026-v2-mtp.dts
copy to arch/arm/boot/dts/apq8026-v2-1080p-mtp.dts
index 40856c8..0ea98f5 100644
--- a/arch/arm/boot/dts/apq8026-v2-mtp.dts
+++ b/arch/arm/boot/dts/apq8026-v2-1080p-mtp.dts
@@ -13,10 +13,10 @@
/dts-v1/;
/include/ "apq8026-v2.dtsi"
-/include/ "msm8226-mtp.dtsi"
+/include/ "msm8226-1080p-mtp.dtsi"
/ {
model = "Qualcomm APQ 8026v2 MTP";
compatible = "qcom,apq8026-mtp", "qcom,apq8026", "qcom,mtp";
- qcom,board-id = <8 0>;
+ qcom,board-id = <8 2>;
};
diff --git a/arch/arm/boot/dts/apq8026-v2-cdp.dts b/arch/arm/boot/dts/apq8026-v2-720p-cdp.dts
similarity index 95%
rename from arch/arm/boot/dts/apq8026-v2-cdp.dts
rename to arch/arm/boot/dts/apq8026-v2-720p-cdp.dts
index cb68779..cb2226a 100644
--- a/arch/arm/boot/dts/apq8026-v2-cdp.dts
+++ b/arch/arm/boot/dts/apq8026-v2-720p-cdp.dts
@@ -13,7 +13,7 @@
/dts-v1/;
/include/ "apq8026-v2.dtsi"
-/include/ "msm8226-cdp.dtsi"
+/include/ "msm8226-720p-cdp.dtsi"
/ {
model = "Qualcomm APQ 8026v2 CDP";
diff --git a/arch/arm/boot/dts/apq8026-v2-mtp.dts b/arch/arm/boot/dts/apq8026-v2-720p-mtp.dts
similarity index 95%
rename from arch/arm/boot/dts/apq8026-v2-mtp.dts
rename to arch/arm/boot/dts/apq8026-v2-720p-mtp.dts
index 40856c8..439b3d7 100644
--- a/arch/arm/boot/dts/apq8026-v2-mtp.dts
+++ b/arch/arm/boot/dts/apq8026-v2-720p-mtp.dts
@@ -13,7 +13,7 @@
/dts-v1/;
/include/ "apq8026-v2.dtsi"
-/include/ "msm8226-mtp.dtsi"
+/include/ "msm8226-720p-mtp.dtsi"
/ {
model = "Qualcomm APQ 8026v2 MTP";
diff --git a/arch/arm/boot/dts/apq8026-v2-xpm.dts b/arch/arm/boot/dts/apq8026-v2-xpm.dts
index 324516d..3133424 100644
--- a/arch/arm/boot/dts/apq8026-v2-xpm.dts
+++ b/arch/arm/boot/dts/apq8026-v2-xpm.dts
@@ -13,7 +13,7 @@
/dts-v1/;
/include/ "apq8026-v2.dtsi"
-/include/ "msm8226-cdp.dtsi"
+/include/ "msm8226-720p-cdp.dtsi"
/ {
model = "Qualcomm APQ 8026v2 XPM";
diff --git a/arch/arm/boot/dts/dsi-panel-hx8389b-qhd-video.dtsi b/arch/arm/boot/dts/dsi-panel-hx8389b-qhd-video.dtsi
index 7e63014..8f94502 100755
--- a/arch/arm/boot/dts/dsi-panel-hx8389b-qhd-video.dtsi
+++ b/arch/arm/boot/dts/dsi-panel-hx8389b-qhd-video.dtsi
@@ -124,7 +124,7 @@
qcom,mdss-dsi-panel-timings = [97 23 17 00 4B 53 1C 27 27 03 04 00];
qcom,mdss-dsi-t-clk-post = <0x04>;
qcom,mdss-dsi-t-clk-pre = <0x1b>;
- qcom,mdss-dsi-bl-min-level = <1>;
+ qcom,mdss-dsi-bl-min-level = <26>;
qcom,mdss-dsi-bl-max-level = <255>;
qcom,mdss-dsi-dma-trigger = <4>;
qcom,mdss-dsi-mdp-trigger = <0>;
diff --git a/arch/arm/boot/dts/dsi-panel-otm8018b-fwvga-video.dtsi b/arch/arm/boot/dts/dsi-panel-otm8018b-fwvga-video.dtsi
index 9477c56..393419b 100644
--- a/arch/arm/boot/dts/dsi-panel-otm8018b-fwvga-video.dtsi
+++ b/arch/arm/boot/dts/dsi-panel-otm8018b-fwvga-video.dtsi
@@ -256,7 +256,7 @@
qcom,mdss-dsi-panel-timings = [8B 1F 14 00 45 4A 19 23 23 03 04 00];
qcom,mdss-dsi-t-clk-post = <0x04>;
qcom,mdss-dsi-t-clk-pre = <0x1b>;
- qcom,mdss-dsi-bl-min-level = <1>;
+ qcom,mdss-dsi-bl-min-level = <26>;
qcom,mdss-dsi-bl-max-level = <255>;
qcom,mdss-dsi-dma-trigger = <4>;
qcom,mdss-dsi-mdp-trigger = <0>;
diff --git a/arch/arm/boot/dts/msm8226-1080p-cdp.dtsi b/arch/arm/boot/dts/msm8226-1080p-cdp.dtsi
new file mode 100644
index 0000000..e310c17
--- /dev/null
+++ b/arch/arm/boot/dts/msm8226-1080p-cdp.dtsi
@@ -0,0 +1,492 @@
+/* Copyright (c) 2013, 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/ "msm8226-camera-sensor-cdp.dtsi"
+
+&soc {
+ serial@f991f000 {
+ status = "ok";
+ };
+
+ i2c@f9927000 { /* BLSP1 QUP5 */
+ synaptics@20 {
+ compatible = "synaptics,rmi4";
+ reg = <0x20>;
+ interrupt-parent = <&msmgpio>;
+ interrupts = <17 0x2008>;
+ vdd-supply = <&pm8226_l19>;
+ vcc_i2c-supply = <&pm8226_lvs1>;
+ synaptics,reset-gpio = <&msmgpio 16 0x00>;
+ synaptics,irq-gpio = <&msmgpio 17 0x2008>;
+ synaptics,button-map = <139 102 158>;
+ synaptics,i2c-pull-up;
+ synaptics,power-down;
+ synaptics,disable-gpios;
+ };
+ };
+
+ i2c@f9925000 { /* BLSP1 QUP3 */
+ nfc-nci@0e {
+ compatible = "qcom,nfc-nci";
+ reg = <0x0e>;
+ qcom,irq-gpio = <&msmgpio 21 0x00>;
+ qcom,dis-gpio = <&msmgpio 20 0x00>;
+ qcom,clk-src = "BBCLK2";
+ qcom,clk-en-gpio = <&msmgpio 0 0x00>;
+ interrupt-parent = <&msmgpio>;
+ interrupts = <21 0>;
+ qcom,clk-gpio = <&pm8226_gpios 3 0>;
+ };
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+ input-name = "gpio-keys";
+
+ camera_focus {
+ label = "camera_focus";
+ gpios = <&msmgpio 108 0x1>;
+ linux,input-type = <1>;
+ linux,code = <0x210>;
+ gpio-key,wakeup;
+ debounce-interval = <15>;
+ };
+
+ camera_snapshot {
+ label = "camera_snapshot";
+ gpios = <&msmgpio 107 0x1>;
+ linux,input-type = <1>;
+ linux,code = <0x2fe>;
+ gpio-key,wakeup;
+ debounce-interval = <15>;
+ };
+
+ vol_up {
+ label = "volume_up";
+ gpios = <&msmgpio 106 0x1>;
+ linux,input-type = <1>;
+ linux,code = <115>;
+ gpio-key,wakeup;
+ debounce-interval = <15>;
+ };
+ };
+
+ spi@f9923000 {
+ ethernet-switch@3 {
+ compatible = "micrel,ks8851";
+ reg = <3>;
+ interrupt-parent = <&msmgpio>;
+ interrupts = <115 0x8>;
+ spi-max-frequency = <4800000>;
+ rst-gpio = <&msmgpio 114 0>;
+ vdd-io-supply = <&pm8226_lvs1>;
+ vdd-phy-supply = <&pm8226_lvs1>;
+ };
+ };
+
+ sound {
+ qcom,audio-routing =
+ "RX_BIAS", "MCLK",
+ "LDO_H", "MCLK",
+ "SPK_OUT", "MCLK",
+ "SPK_OUT", "EXT_VDD_SPKR",
+ "AMIC1", "MIC BIAS1 Internal1",
+ "MIC BIAS1 Internal1", "Handset Mic",
+ "AMIC2", "MIC BIAS2 External",
+ "MIC BIAS2 External", "Headset Mic",
+ "AMIC4", "MIC BIAS2 External",
+ "MIC BIAS2 External", "ANCRight Headset Mic",
+ "AMIC5", "MIC BIAS2 External",
+ "MIC BIAS2 External", "ANCLeft Headset Mic",
+ "DMIC1", "MIC BIAS1 External",
+ "MIC BIAS1 External", "Digital Mic1",
+ "DMIC2", "MIC BIAS1 External",
+ "MIC BIAS1 External", "Digital Mic2",
+ "DMIC3", "MIC BIAS3 External",
+ "MIC BIAS3 External", "Digital Mic3",
+ "DMIC4", "MIC BIAS3 External",
+ "MIC BIAS3 External", "Digital Mic4";
+
+ qcom,cdc-mclk-gpios = <&pm8226_gpios 1 0>;
+ qcom,cdc-vdd-spkr-gpios = <&pm8226_gpios 2 0>;
+ qcom,headset-jack-type-NC;
+ };
+
+ sound-9302 {
+ qcom,audio-routing =
+ "RX_BIAS", "MCLK",
+ "LDO_H", "MCLK",
+ "SPK_OUT", "MCLK",
+ "SPK_OUT", "EXT_VDD_SPKR",
+ "AMIC1", "MIC BIAS1 External",
+ "MIC BIAS1 External", "Handset Mic",
+ "AMIC2", "MIC BIAS2 External",
+ "MIC BIAS2 External", "Headset Mic",
+ "AMIC3", "MIC BIAS1 External",
+ "MIC BIAS1 External", "Handset Mic";
+
+ qcom,cdc-mclk-gpios = <&pm8226_gpios 1 0>;
+ qcom,cdc-vdd-spkr-gpios = <&pm8226_gpios 2 0>;
+ qcom,headset-jack-type-NC;
+ };
+};
+
+&sdcc1 {
+ vdd-supply = <&pm8226_l17>;
+ qcom,vdd-voltage-level = <2950000 2950000>;
+ qcom,vdd-current-level = <800 500000>;
+
+ vdd-io-supply = <&pm8226_l6>;
+ qcom,vdd-io-always-on;
+ qcom,vdd-io-voltage-level = <1800000 1800000>;
+ qcom,vdd-io-current-level = <250 154000>;
+
+ qcom,pad-pull-on = <0x0 0x3 0x3>; /* no-pull, pull-up, pull-up */
+ qcom,pad-pull-off = <0x0 0x3 0x3>; /* no-pull, pull-up, pull-up */
+ qcom,pad-drv-on = <0x4 0x4 0x4>; /* 10mA, 10mA, 10mA */
+ qcom,pad-drv-off = <0x0 0x0 0x0>; /* 2mA, 2mA, 2mA */
+
+ qcom,clk-rates = <400000 25000000 50000000 100000000 200000000>;
+ qcom,sup-voltages = <2950 2950>;
+
+ qcom,bus-speed-mode = "HS200_1p8v", "DDR_1p8v";
+ qcom,nonremovable;
+
+ status = "disabled";
+};
+
+&sdhc_1 {
+ vdd-supply = <&pm8226_l17>;
+ qcom,vdd-voltage-level = <2950000 2950000>;
+ qcom,vdd-current-level = <800 500000>;
+
+ vdd-io-supply = <&pm8226_l6>;
+ qcom,vdd-io-always-on;
+ qcom,vdd-io-voltage-level = <1800000 1800000>;
+ qcom,vdd-io-current-level = <250 154000>;
+
+ qcom,pad-pull-on = <0x0 0x3 0x3>; /* no-pull, pull-up, pull-up */
+ qcom,pad-pull-off = <0x0 0x3 0x3>; /* no-pull, pull-up, pull-up */
+ qcom,pad-drv-on = <0x4 0x4 0x4>; /* 10mA, 10mA, 10mA */
+ qcom,pad-drv-off = <0x0 0x0 0x0>; /* 2mA, 2mA, 2mA */
+
+ qcom,clk-rates = <400000 25000000 50000000 100000000 200000000>;
+ qcom,bus-speed-mode = "HS200_1p8v", "DDR_1p8v";
+ qcom,nonremovable;
+
+ status = "ok";
+};
+
+&sdcc2 {
+ vdd-supply = <&pm8226_l18>;
+ qcom,vdd-voltage-level = <2950000 2950000>;
+ qcom,vdd-current-level = <9000 800000>;
+
+ vdd-io-supply = <&pm8226_l21>;
+ qcom,vdd-io-voltage-level = <1800000 2950000>;
+ qcom,vdd-io-current-level = <6 22000>;
+
+ qcom,pad-pull-on = <0x0 0x3 0x3>; /* no-pull, pull-up, pull-up */
+ qcom,pad-pull-off = <0x0 0x3 0x3>; /* no-pull, pull-up, pull-up */
+ qcom,pad-drv-on = <0x4 0x4 0x4>; /* 10mA, 10mA, 10mA */
+ qcom,pad-drv-off = <0x0 0x0 0x0>; /* 2mA, 2mA, 2mA */
+
+ qcom,clk-rates = <400000 25000000 50000000 100000000 200000000>;
+ qcom,sup-voltages = <2950 2950>;
+
+ qcom,xpc;
+ qcom,bus-speed-mode = "SDR12", "SDR25", "SDR50", "DDR50", "SDR104";
+ qcom,current-limit = <600>;
+
+ #address-cells = <0>;
+ interrupt-parent = <&sdcc2>;
+ interrupts = <0 1 2>;
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0xffffffff>;
+ interrupt-map = <0 &intc 0 125 0
+ 1 &intc 0 220 0
+ 2 &msmgpio 38 0x3>;
+ interrupt-names = "core_irq", "bam_irq", "status_irq";
+ cd-gpios = <&msmgpio 38 0x1>;
+
+ status = "disabled";
+};
+
+&sdhc_2 {
+ vdd-supply = <&pm8226_l18>;
+ qcom,vdd-voltage-level = <2950000 2950000>;
+ qcom,vdd-current-level = <9000 800000>;
+
+ vdd-io-supply = <&pm8226_l21>;
+ qcom,vdd-io-voltage-level = <1800000 2950000>;
+ qcom,vdd-io-current-level = <6 22000>;
+
+ qcom,pad-pull-on = <0x0 0x3 0x3>; /* no-pull, pull-up, pull-up */
+ qcom,pad-pull-off = <0x0 0x3 0x3>; /* no-pull, pull-up, pull-up */
+ qcom,pad-drv-on = <0x4 0x4 0x4>; /* 10mA, 10mA, 10mA */
+ qcom,pad-drv-off = <0x0 0x0 0x0>; /* 2mA, 2mA, 2mA */
+
+ qcom,clk-rates = <400000 25000000 50000000 100000000 200000000>;
+
+ #address-cells = <0>;
+ interrupt-parent = <&sdhc_2>;
+ interrupts = <0 1 2>;
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0xffffffff>;
+ interrupt-map = <0 &intc 0 125 0
+ 1 &intc 0 221 0
+ 2 &msmgpio 38 0x3>;
+ interrupt-names = "hc_irq", "pwr_irq", "status_irq";
+ cd-gpios = <&msmgpio 38 0x1>;
+
+ status = "ok";
+};
+
+&sdcc3 {
+ qcom,sup-voltages = <1800 1800>;
+ status = "disabled";
+};
+
+&sdhc_3 {
+ qcom,sup-voltages = <1800 1800>;
+ status = "disabled";
+};
+
+&spmi_bus {
+ qcom,pm8226@0 {
+ qcom,leds@a100 {
+ status = "okay";
+ qcom,led_mpp_2 {
+ label = "mpp";
+ linux,name = "button-backlight";
+ linux,default-trigger = "none";
+ qcom,default-state = "off";
+ qcom,max-current = <40>;
+ qcom,current-setting = <5>;
+ qcom,id = <6>;
+ qcom,mode = "manual";
+ qcom,source-sel = <1>;
+ qcom,mode-ctrl = <0x60>;
+ };
+ };
+
+ qcom,leds@a300 {
+ status = "okay";
+ qcom,led_mpp_4 {
+ label = "mpp";
+ linux,name = "green";
+ linux,default-trigger = "battery-full";
+ qcom,default-state = "off";
+ qcom,max-current = <40>;
+ qcom,current-setting = <5>;
+ qcom,id = <6>;
+ qcom,mode = "pwm";
+ qcom,pwm-us = <1000>;
+ qcom,source-sel = <8>;
+ qcom,mode-ctrl = <0x60>;
+ qcom,pwm-channel = <0>;
+ qcom,start-idx = <1>;
+ qcom,ramp-step-ms = <120>;
+ qcom,duty-pcts = [00 00 00 00 00
+ 00 00 00 00 00
+ 50 00 00 00 00
+ 00 00 00 00 00
+ 00];
+ qcom,use-blink;
+ };
+ };
+
+ qcom,leds@a500 {
+ status = "okay";
+ qcom,led_mpp_6 {
+ label = "mpp";
+ linux,name = "red";
+ linux,default-trigger = "battery-charging";
+ qcom,default-state = "off";
+ qcom,max-current = <40>;
+ qcom,current-setting = <5>;
+ qcom,id = <6>;
+ qcom,mode = "pwm";
+ qcom,pwm-us = <1000>;
+ qcom,mode-ctrl = <0x60>;
+ qcom,source-sel = <10>;
+ qcom,pwm-channel = <5>;
+ qcom,start-idx = <1>;
+ qcom,ramp-step-ms = <120>;
+ qcom,duty-pcts = [00 00 00 00 00
+ 00 00 00 00 00
+ 50 00 00 00 00
+ 00 00 00 00 00
+ 00];
+ qcom,use-blink;
+ };
+ };
+ };
+
+ qcom,pm8226@1 {
+ qcom,leds@d800 {
+ status = "okay";
+ qcom,wled_0 {
+ label = "wled";
+ linux,name = "wled:backlight";
+ linux,default-trigger = "bkl-trigger";
+ qcom,cs-out-en;
+ qcom,op-fdbck = <1>;
+ qcom,default-state = "on";
+ qcom,max-current = <20>;
+ qcom,ctrl-delay-us = <0>;
+ qcom,boost-curr-lim = <3>;
+ qcom,cp-sel = <0>;
+ qcom,switch-freq = <11>;
+ qcom,ovp-val = <0>;
+ qcom,num-strings = <1>;
+ qcom,id = <0>;
+ };
+ };
+
+ qcom,vibrator@c000 {
+ status = "okay";
+ qcom,vib-timeout-ms = <15000>;
+ qcom,vib-vtg-level-mV = <3100>;
+ };
+ };
+};
+
+&pm8226_gpios {
+ gpio@c000 { /* GPIO 1 */
+ /* XO_PMIC_CDC_MCLK enable for tapan codec */
+ qcom,mode = <1>; /* Digital output */
+ qcom,output-type = <0>; /* CMOS logic */
+ qcom,pull = <5>; /* QPNP_PIN_PULL_NO*/
+ qcom,vin-sel = <3>; /* QPNP_PIN_VIN3 */
+ qcom,out-strength = <3>;/* QPNP_PIN_OUT_STRENGTH_HIGH */
+ qcom,src-sel = <2>; /* QPNP_PIN_SEL_FUNC_1 */
+ qcom,master-en = <1>; /* Enable GPIO */
+ };
+
+ gpio@c100 { /* GPIO 2 */
+ qcom,mode = <1>;
+ qcom,output-type = <0>;
+ qcom,pull = <5>;
+ qcom,vin-sel = <3>;
+ qcom,out-strength = <3>;
+ qcom,src-sel = <2>;
+ qcom,master-en = <1>;
+ };
+
+ gpio@c200 { /* GPIO 3 */
+ qcom,mode = <0>; /* QPNP_PIN_MODE_DIG_IN */
+ qcom,pull = <5>; /* QPNP_PIN_PULL_NO */
+ qcom,vin-sel = <2>; /* QPNP_PIN_VIN2 */
+ qcom,src-sel = <2>; /* QPNP_PIN_SEL_FUNC_1 */
+ qcom,master-en = <1>;
+ };
+
+ gpio@c300 { /* GPIO 4 */
+ };
+
+ gpio@c400 { /* GPIO 5 */
+ };
+
+ gpio@c500 { /* GPIO 6 */
+ };
+
+ gpio@c600 { /* GPIO 7 */
+ };
+
+ gpio@c700 { /* GPIO 8 */
+ };
+};
+
+&pm8226_mpps {
+ mpp@a000 { /* MPP 1 */
+ };
+
+ mpp@a100 { /* MPP 2 */
+ };
+
+ mpp@a200 { /* MPP 3 */
+ };
+
+ mpp@a300 { /* MPP 4 */
+ };
+
+ mpp@a400 { /* MPP 5 */
+ /* PA_THERM0 config */
+ qcom,mode = <4>; /* AIN input */
+ qcom,invert = <1>; /* Enable MPP */
+ qcom,ain-route = <0>; /* AMUX 5 */
+ qcom,master-en = <1>;
+ qcom,src-sel = <0>; /* Function constant */
+ };
+
+ mpp@a500 { /* MPP 6 */
+ };
+
+ mpp@a600 { /* MPP 7 */
+ };
+
+ mpp@a700 { /* MPP 8 */
+ /* PA_THERM1 config */
+ qcom,mode = <4>; /* AIN input */
+ qcom,invert = <1>; /* Enable MPP */
+ qcom,ain-route = <3>; /* AMUX 8 */
+ qcom,master-en = <1>;
+ qcom,src-sel = <0>; /* Function constant */
+ };
+};
+
+&pm8226_chg {
+ qcom,charging-disabled;
+ qcom,use-default-batt-values;
+
+ qcom,bat-if@1200 {
+ status = "disabled";
+ };
+};
+
+&pm8226_vadc {
+ chan@14 {
+ label = "pa_therm0";
+ reg = <0x14>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <2>;
+ qcom,hw-settle-time = <2>;
+ qcom,fast-avg-setup = <0>;
+ };
+
+ chan@17 {
+ label = "pa_therm1";
+ reg = <0x17>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <2>;
+ qcom,hw-settle-time = <2>;
+ qcom,fast-avg-setup = <0>;
+ };
+};
+
+&mdss_mdp {
+ qcom,mdss-pref-prim-intf = "dsi";
+};
+
+&mdss_dsi0 {
+ qcom,dsi-pref-prim-pan = <&dsi_jdi_1080_vid>;
+ qcom,platform-enable-gpio = <&msmgpio 109 0>;
+};
+
+&dsi_jdi_1080_vid {
+ qcom,cont-splash-enabled;
+};
diff --git a/arch/arm/boot/dts/msm8226-1080p-mtp.dtsi b/arch/arm/boot/dts/msm8226-1080p-mtp.dtsi
new file mode 100644
index 0000000..e58c321
--- /dev/null
+++ b/arch/arm/boot/dts/msm8226-1080p-mtp.dtsi
@@ -0,0 +1,509 @@
+/* Copyright (c) 2013, 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/ "msm8226-camera-sensor-mtp.dtsi"
+
+&soc {
+ serial@f991f000 {
+ status = "ok";
+ };
+
+ i2c@f9927000 { /* BLSP1 QUP5 */
+ synaptics@20 {
+ compatible = "synaptics,rmi4";
+ reg = <0x20>;
+ interrupt-parent = <&msmgpio>;
+ interrupts = <17 0x2008>;
+ vdd-supply = <&pm8226_l19>;
+ vcc_i2c-supply = <&pm8226_lvs1>;
+ synaptics,reset-gpio = <&msmgpio 16 0x00>;
+ synaptics,irq-gpio = <&msmgpio 17 0x2008>;
+ synaptics,button-map = <139 102 158>;
+ synaptics,i2c-pull-up;
+ synaptics,power-down;
+ synaptics,disable-gpios;
+ };
+ };
+
+ i2c@f9925000 { /* BLSP1 QUP3 */
+ nfc-nci@0e {
+ compatible = "qcom,nfc-nci";
+ reg = <0x0e>;
+ qcom,irq-gpio = <&msmgpio 21 0x00>;
+ qcom,dis-gpio = <&msmgpio 20 0x00>;
+ qcom,clk-src = "BBCLK2";
+ qcom,clk-en-gpio = <&msmgpio 0 0x00>;
+ interrupt-parent = <&msmgpio>;
+ interrupts = <21 0>;
+ qcom,clk-gpio = <&pm8226_gpios 3 0>;
+ };
+ };
+ gpio_keys {
+ compatible = "gpio-keys";
+ input-name = "gpio-keys";
+
+ camera_focus {
+ label = "camera_focus";
+ gpios = <&msmgpio 108 0x1>;
+ linux,input-type = <1>;
+ linux,code = <0x210>;
+ gpio-key,wakeup;
+ debounce-interval = <15>;
+ };
+
+ camera_snapshot {
+ label = "camera_snapshot";
+ gpios = <&msmgpio 107 0x1>;
+ linux,input-type = <1>;
+ linux,code = <0x2fe>;
+ gpio-key,wakeup;
+ debounce-interval = <15>;
+ };
+
+ vol_up {
+ label = "volume_up";
+ gpios = <&msmgpio 106 0x1>;
+ linux,input-type = <1>;
+ linux,code = <115>;
+ gpio-key,wakeup;
+ debounce-interval = <15>;
+ };
+ };
+
+ spi@f9923000 {
+ ethernet-switch@3 {
+ compatible = "micrel,ks8851";
+ reg = <3>;
+ interrupt-parent = <&msmgpio>;
+ interrupts = <115 0x8>;
+ spi-max-frequency = <4800000>;
+ rst-gpio = <&msmgpio 114 0>;
+ vdd-io-supply = <&pm8226_lvs1>;
+ vdd-phy-supply = <&pm8226_lvs1>;
+ };
+ };
+
+ sound {
+ qcom,audio-routing =
+ "RX_BIAS", "MCLK",
+ "LDO_H", "MCLK",
+ "SPK_OUT", "MCLK",
+ "SPK_OUT", "EXT_VDD_SPKR",
+ "AMIC1", "MIC BIAS1 External",
+ "MIC BIAS1 External", "Handset Mic",
+ "AMIC2", "MIC BIAS2 External",
+ "MIC BIAS2 External", "Headset Mic",
+ "AMIC4", "MIC BIAS2 External",
+ "MIC BIAS2 External", "ANCRight Headset Mic",
+ "AMIC5", "MIC BIAS2 External",
+ "MIC BIAS2 External", "ANCLeft Headset Mic";
+
+ qcom,cdc-mclk-gpios = <&pm8226_gpios 1 0>;
+ qcom,cdc-vdd-spkr-gpios = <&pm8226_gpios 2 0>;
+ };
+
+ sound-9302 {
+ qcom,audio-routing =
+ "RX_BIAS", "MCLK",
+ "LDO_H", "MCLK",
+ "SPK_OUT", "MCLK",
+ "SPK_OUT", "EXT_VDD_SPKR",
+ "AMIC1", "MIC BIAS1 Internal1",
+ "MIC BIAS1 Internal1", "Handset Mic",
+ "AMIC2", "MIC BIAS2 External",
+ "MIC BIAS2 External", "Headset Mic",
+ "AMIC3", "MIC BIAS1 External",
+ "MIC BIAS1 External", "Handset Mic";
+
+ qcom,cdc-mclk-gpios = <&pm8226_gpios 1 0>;
+ qcom,cdc-vdd-spkr-gpios = <&pm8226_gpios 2 0>;
+ };
+};
+
+&usb_otg {
+ #address-cells = <0>;
+ interrupt-parent = <&usb_otg>;
+ interrupts = <0 1 2>;
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0xffffffff>;
+ interrupt-map = <0 &intc 0 134 0
+ 1 &intc 0 140 0
+ 2 &spmi_bus 0x0 0x0 0x9 0x0>;
+ interrupt-names = "core_irq", "async_irq", "pmic_id_irq";
+
+ qcom,hsusb-otg-mode = <3>;
+ vbus_otg-supply = <&pm8226_chg_otg>;
+};
+
+&sdcc1 {
+ vdd-supply = <&pm8226_l17>;
+ qcom,vdd-voltage-level = <2950000 2950000>;
+ qcom,vdd-current-level = <800 500000>;
+
+ vdd-io-supply = <&pm8226_l6>;
+ qcom,vdd-io-always-on;
+ qcom,vdd-io-voltage-level = <1800000 1800000>;
+ qcom,vdd-io-current-level = <250 154000>;
+
+ qcom,pad-pull-on = <0x0 0x3 0x3>; /* no-pull, pull-up, pull-up */
+ qcom,pad-pull-off = <0x0 0x3 0x3>; /* no-pull, pull-up, pull-up */
+ qcom,pad-drv-on = <0x4 0x4 0x4>; /* 10mA, 10mA, 10mA */
+ qcom,pad-drv-off = <0x0 0x0 0x0>; /* 2mA, 2mA, 2mA */
+
+ qcom,clk-rates = <400000 25000000 50000000 100000000 200000000>;
+ qcom,sup-voltages = <2950 2950>;
+
+ qcom,bus-speed-mode = "HS200_1p8v", "DDR_1p8v";
+ qcom,nonremovable;
+
+ status = "disabled";
+};
+
+&sdhc_1 {
+ vdd-supply = <&pm8226_l17>;
+ qcom,vdd-voltage-level = <2950000 2950000>;
+ qcom,vdd-current-level = <800 500000>;
+
+ vdd-io-supply = <&pm8226_l6>;
+ qcom,vdd-io-always-on;
+ qcom,vdd-io-voltage-level = <1800000 1800000>;
+ qcom,vdd-io-current-level = <250 154000>;
+
+ qcom,pad-pull-on = <0x0 0x3 0x3>; /* no-pull, pull-up, pull-up */
+ qcom,pad-pull-off = <0x0 0x3 0x3>; /* no-pull, pull-up, pull-up */
+ qcom,pad-drv-on = <0x4 0x4 0x4>; /* 10mA, 10mA, 10mA */
+ qcom,pad-drv-off = <0x0 0x0 0x0>; /* 2mA, 2mA, 2mA */
+
+ qcom,clk-rates = <400000 25000000 50000000 100000000 200000000>;
+ qcom,bus-speed-mode = "HS200_1p8v", "DDR_1p8v";
+ qcom,nonremovable;
+
+ status = "ok";
+};
+
+&sdcc2 {
+ vdd-supply = <&pm8226_l18>;
+ qcom,vdd-voltage-level = <2950000 2950000>;
+ qcom,vdd-current-level = <9000 800000>;
+
+ vdd-io-supply = <&pm8226_l21>;
+ qcom,vdd-io-voltage-level = <1800000 2950000>;
+ qcom,vdd-io-current-level = <6 22000>;
+
+ qcom,pad-pull-on = <0x0 0x3 0x3>; /* no-pull, pull-up, pull-up */
+ qcom,pad-pull-off = <0x0 0x3 0x3>; /* no-pull, pull-up, pull-up */
+ qcom,pad-drv-on = <0x4 0x4 0x4>; /* 10mA, 10mA, 10mA */
+ qcom,pad-drv-off = <0x0 0x0 0x0>; /* 2mA, 2mA, 2mA */
+
+ qcom,clk-rates = <400000 25000000 50000000 100000000 200000000>;
+ qcom,sup-voltages = <2950 2950>;
+
+ qcom,xpc;
+ qcom,bus-speed-mode = "SDR12", "SDR25", "SDR50", "DDR50", "SDR104";
+ qcom,current-limit = <600>; #address-cells = <0>; interrupt-parent = <&sdcc2>;
+ interrupts = <0 1 2>;
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0xffffffff>;
+ interrupt-map = <0 &intc 0 125 0
+ 1 &intc 0 220 0
+ 2 &msmgpio 38 0x3>;
+ interrupt-names = "core_irq", "bam_irq", "status_irq";
+ cd-gpios = <&msmgpio 38 0x1>;
+
+ status = "disabled";
+};
+
+&sdhc_2 {
+ vdd-supply = <&pm8226_l18>;
+ qcom,vdd-voltage-level = <2950000 2950000>;
+ qcom,vdd-current-level = <9000 800000>;
+
+ vdd-io-supply = <&pm8226_l21>;
+ qcom,vdd-io-voltage-level = <1800000 2950000>;
+ qcom,vdd-io-current-level = <6 22000>;
+
+ qcom,pad-pull-on = <0x0 0x3 0x3>; /* no-pull, pull-up, pull-up */
+ qcom,pad-pull-off = <0x0 0x3 0x3>; /* no-pull, pull-up, pull-up */
+ qcom,pad-drv-on = <0x4 0x4 0x4>; /* 10mA, 10mA, 10mA */
+ qcom,pad-drv-off = <0x0 0x0 0x0>; /* 2mA, 2mA, 2mA */
+
+ qcom,clk-rates = <400000 25000000 50000000 100000000 200000000>;
+
+ #address-cells = <0>;
+ interrupt-parent = <&sdhc_2>;
+ interrupts = <0 1 2>;
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0xffffffff>;
+ interrupt-map = <0 &intc 0 125 0
+ 1 &intc 0 221 0
+ 2 &msmgpio 38 0x3>;
+ interrupt-names = "hc_irq", "pwr_irq", "status_irq";
+ cd-gpios = <&msmgpio 38 0x1>;
+
+ status = "ok";
+};
+
+&spmi_bus {
+ qcom,pm8226@0 {
+ qcom,leds@a100 {
+ status = "okay";
+ qcom,led_mpp_2 {
+ label = "mpp";
+ linux,name = "button-backlight";
+ linux,default-trigger = "none";
+ qcom,default-state = "off";
+ qcom,max-current = <40>;
+ qcom,current-setting = <5>;
+ qcom,id = <6>;
+ qcom,mode = "manual";
+ qcom,source-sel = <1>;
+ qcom,mode-ctrl = <0x60>;
+ };
+ };
+
+ qcom,leds@a300 {
+ status = "okay";
+ qcom,led_mpp_4 {
+ label = "mpp";
+ linux,name = "green";
+ linux,default-trigger = "battery-full";
+ qcom,default-state = "off";
+ qcom,max-current = <40>;
+ qcom,current-setting = <5>;
+ qcom,id = <6>;
+ qcom,mode = "pwm";
+ qcom,pwm-us = <1000>;
+ qcom,source-sel = <8>;
+ qcom,mode-ctrl = <0x60>;
+ qcom,pwm-channel = <0>;
+ qcom,start-idx = <1>;
+ qcom,ramp-step-ms = <120>;
+ qcom,duty-pcts = [00 00 00 00 00
+ 00 00 00 00 00
+ 50 00 00 00 00
+ 00 00 00 00 00
+ 00];
+ qcom,use-blink;
+ };
+ };
+
+ qcom,leds@a500 {
+ status = "okay";
+ qcom,led_mpp_6 {
+ label = "mpp";
+ linux,name = "red";
+ linux,default-trigger = "battery-charging";
+ qcom,default-state = "off";
+ qcom,max-current = <40>;
+ qcom,current-setting = <5>;
+ qcom,id = <6>;
+ qcom,mode = "pwm";
+ qcom,pwm-us = <1000>;
+ qcom,mode-ctrl = <0x60>;
+ qcom,source-sel = <10>;
+ qcom,pwm-channel = <5>;
+ qcom,start-idx = <1>;
+ qcom,ramp-step-ms = <120>;
+ qcom,duty-pcts = [00 00 00 00 00
+ 00 00 00 00 00
+ 50 00 00 00 00
+ 00 00 00 00 00
+ 00];
+ qcom,use-blink;
+ };
+ };
+ };
+
+ qcom,pm8226@1 {
+ qcom,leds@d300 {
+ status = "okay";
+ };
+
+ qcom,leds@d800 {
+ status = "okay";
+ qcom,wled_0 {
+ label = "wled";
+ linux,name = "wled:backlight";
+ linux,default-trigger = "bkl-trigger";
+ qcom,cs-out-en;
+ qcom,op-fdbck = <1>;
+ qcom,default-state = "on";
+ qcom,max-current = <20>;
+ qcom,ctrl-delay-us = <0>;
+ qcom,boost-curr-lim = <3>;
+ qcom,cp-sel = <0>;
+ qcom,switch-freq = <11>;
+ qcom,ovp-val = <0>;
+ qcom,num-strings = <1>;
+ qcom,id = <0>;
+ };
+ };
+
+ qcom,vibrator@c000 {
+ status = "okay";
+ qcom,vib-timeout-ms = <15000>;
+ qcom,vib-vtg-level-mV = <3100>;
+ };
+ };
+};
+
+&pm8226_gpios {
+ gpio@c000 { /* GPIO 1 */
+ /* XO_PMIC_CDC_MCLK enable for tapan codec */
+ qcom,mode = <1>; /* Digital output */
+ qcom,output-type = <0>; /* CMOS logic */
+ qcom,pull = <5>; /* QPNP_PIN_PULL_NO*/
+ qcom,vin-sel = <3>; /* QPNP_PIN_VIN3 */
+ qcom,out-strength = <3>;/* QPNP_PIN_OUT_STRENGTH_HIGH */
+ qcom,src-sel = <2>; /* QPNP_PIN_SEL_FUNC_1 */
+ qcom,master-en = <1>; /* Enable GPIO */
+ };
+
+ gpio@c100 { /* GPIO 2 */
+ qcom,mode = <1>;
+ qcom,output-type = <0>;
+ qcom,pull = <5>;
+ qcom,vin-sel = <3>;
+ qcom,out-strength = <3>;
+ qcom,src-sel = <2>;
+ qcom,master-en = <1>;
+ };
+
+ gpio@c200 { /* GPIO 3 */
+ qcom,mode = <0>; /* QPNP_PIN_MODE_DIG_IN */
+ qcom,pull = <5>; /* QPNP_PIN_PULL_NO */
+ qcom,vin-sel = <2>; /* QPNP_PIN_VIN2 */
+ qcom,src-sel = <2>; /* QPNP_PIN_SEL_FUNC_1 */
+ qcom,master-en = <1>;
+ };
+
+ gpio@c300 { /* GPIO 4 */
+ };
+
+ gpio@c400 { /* GPIO 5 */
+ };
+
+ gpio@c500 { /* GPIO 6 */
+ };
+
+ gpio@c600 { /* GPIO 7 */
+ };
+
+ gpio@c700 { /* GPIO 8 */
+ };
+};
+
+&pm8226_mpps {
+ mpp@a000 { /* MPP 1 */
+ };
+
+ mpp@a100 { /* MPP 2 */
+ };
+
+ mpp@a200 { /* MPP 3 */
+ };
+
+ mpp@a300 { /* MPP 4 */
+ };
+
+ mpp@a400 { /* MPP 5 */
+ /* PA_THERM0 config */
+ qcom,mode = <4>; /* AIN input */
+ qcom,invert = <1>; /* Enable MPP */
+ qcom,ain-route = <0>; /* AMUX 5 */
+ qcom,master-en = <1>;
+ qcom,src-sel = <0>; /* Function constant */
+ };
+
+ mpp@a500 { /* MPP 6 */
+ };
+
+ mpp@a600 { /* MPP 7 */
+ };
+
+ mpp@a700 { /* MPP 8 */
+ /* PA_THERM1 config */
+ qcom,mode = <4>; /* AIN input */
+ qcom,invert = <1>; /* Enable MPP */
+ qcom,ain-route = <3>; /* AMUX 8 */
+ qcom,master-en = <1>;
+ qcom,src-sel = <0>; /* Function constant */
+ };
+};
+
+&pm8226_vadc {
+ chan@14 {
+ label = "pa_therm0";
+ reg = <0x14>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <2>;
+ qcom,hw-settle-time = <2>;
+ qcom,fast-avg-setup = <0>;
+ };
+
+ chan@17 {
+ label = "pa_therm1";
+ reg = <0x17>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <2>;
+ qcom,hw-settle-time = <2>;
+ qcom,fast-avg-setup = <0>;
+ };
+};
+
+/ {
+ mtp_batterydata: qcom,battery-data {
+ qcom,rpull-up-kohm = <100>;
+ qcom,vref-batt-therm = <1800000>;
+
+ /include/ "batterydata-palladium.dtsi"
+ /include/ "batterydata-mtp-3000mah.dtsi"
+ };
+};
+
+&pm8226_bms {
+ status = "ok";
+ qcom,battery-data = <&mtp_batterydata>;
+ qcom,enable-fcc-learning;
+ qcom,min-fcc-learning-soc = <20>;
+ qcom,min-fcc-ocv-pc = <30>;
+ qcom,min-fcc-learning-samples = <5>;
+ qcom,fcc-resolution = <10>;
+};
+
+&pm8226_chg {
+ qcom,charging-disabled;
+ qcom,battery-data = <&mtp_batterydata>;
+};
+
+&slim_msm {
+ tapan_codec {
+ qcom,cdc-micbias1-ext-cap;
+ };
+};
+
+&mdss_mdp {
+ qcom,mdss-pref-prim-intf = "dsi";
+};
+
+&mdss_dsi0 {
+ qcom,dsi-pref-prim-pan = <&dsi_jdi_1080_vid>;
+ qcom,platform-enable-gpio = <&msmgpio 109 0>;
+};
+
+&dsi_jdi_1080_vid {
+ qcom,cont-splash-enabled;
+};
diff --git a/arch/arm/boot/dts/msm8226-cdp.dtsi b/arch/arm/boot/dts/msm8226-720p-cdp.dtsi
similarity index 100%
rename from arch/arm/boot/dts/msm8226-cdp.dtsi
rename to arch/arm/boot/dts/msm8226-720p-cdp.dtsi
diff --git a/arch/arm/boot/dts/msm8226-mtp.dtsi b/arch/arm/boot/dts/msm8226-720p-mtp.dtsi
similarity index 100%
rename from arch/arm/boot/dts/msm8226-mtp.dtsi
rename to arch/arm/boot/dts/msm8226-720p-mtp.dtsi
diff --git a/arch/arm/boot/dts/msm8226-mdss-panels.dtsi b/arch/arm/boot/dts/msm8226-mdss-panels.dtsi
index eeec175..0731a9a 100644
--- a/arch/arm/boot/dts/msm8226-mdss-panels.dtsi
+++ b/arch/arm/boot/dts/msm8226-mdss-panels.dtsi
@@ -16,3 +16,4 @@
/include/ "dsi-panel-nt35596-1080p-video.dtsi"
/include/ "dsi-panel-nt35590-720p-cmd.dtsi"
/include/ "dsi-panel-ssd2080m-720p-video.dtsi"
+/include/ "dsi-panel-jdi-1080p-video.dtsi"
diff --git a/arch/arm/boot/dts/msm8226-v1-cdp.dts b/arch/arm/boot/dts/msm8226-v1-cdp.dts
index e426a97..4b8cafd 100644
--- a/arch/arm/boot/dts/msm8226-v1-cdp.dts
+++ b/arch/arm/boot/dts/msm8226-v1-cdp.dts
@@ -12,7 +12,7 @@
/dts-v1/;
/include/ "msm8226-v1.dtsi"
-/include/ "msm8226-cdp.dtsi"
+/include/ "msm8226-720p-cdp.dtsi"
/ {
model = "Qualcomm MSM 8226 CDP";
diff --git a/arch/arm/boot/dts/msm8226-v1-mtp.dts b/arch/arm/boot/dts/msm8226-v1-mtp.dts
index 08d7cec..a1e78b7 100644
--- a/arch/arm/boot/dts/msm8226-v1-mtp.dts
+++ b/arch/arm/boot/dts/msm8226-v1-mtp.dts
@@ -12,7 +12,7 @@
/dts-v1/;
/include/ "msm8226-v1.dtsi"
-/include/ "msm8226-mtp.dtsi"
+/include/ "msm8226-720p-mtp.dtsi"
/ {
model = "Qualcomm MSM 8226 MTP";
diff --git a/arch/arm/boot/dts/msm8226-v2-cdp.dts b/arch/arm/boot/dts/msm8226-v2-1080p-cdp.dts
similarity index 92%
copy from arch/arm/boot/dts/msm8226-v2-cdp.dts
copy to arch/arm/boot/dts/msm8226-v2-1080p-cdp.dts
index 3302d26..77cc08c 100644
--- a/arch/arm/boot/dts/msm8226-v2-cdp.dts
+++ b/arch/arm/boot/dts/msm8226-v2-1080p-cdp.dts
@@ -12,13 +12,13 @@
/dts-v1/;
/include/ "msm8226-v2.dtsi"
-/include/ "msm8226-cdp.dtsi"
+/include/ "msm8226-1080p-cdp.dtsi"
/include/ "msm8226-camera-sensor-cdp.dtsi"
/ {
model = "Qualcomm MSM 8226v2 CDP";
compatible = "qcom,msm8226-cdp", "qcom,msm8226", "qcom,cdp";
- qcom,board-id = <1 0>;
+ qcom,board-id = <1 2>;
};
&hsic_host {
diff --git a/arch/arm/boot/dts/msm8226-v2-mtp.dts b/arch/arm/boot/dts/msm8226-v2-1080p-mtp.dts
similarity index 92%
copy from arch/arm/boot/dts/msm8226-v2-mtp.dts
copy to arch/arm/boot/dts/msm8226-v2-1080p-mtp.dts
index 6034107..b12a77d 100644
--- a/arch/arm/boot/dts/msm8226-v2-mtp.dts
+++ b/arch/arm/boot/dts/msm8226-v2-1080p-mtp.dts
@@ -12,11 +12,11 @@
/dts-v1/;
/include/ "msm8226-v2.dtsi"
-/include/ "msm8226-mtp.dtsi"
+/include/ "msm8226-1080p-mtp.dtsi"
/include/ "msm8226-camera-sensor-mtp.dtsi"
/ {
model = "Qualcomm MSM 8226v2 MTP";
compatible = "qcom,msm8226-mtp", "qcom,msm8226", "qcom,mtp";
- qcom,board-id = <8 0>;
+ qcom,board-id = <8 2>;
};
diff --git a/arch/arm/boot/dts/msm8226-v2-cdp.dts b/arch/arm/boot/dts/msm8226-v2-720p-cdp.dts
similarity index 95%
rename from arch/arm/boot/dts/msm8226-v2-cdp.dts
rename to arch/arm/boot/dts/msm8226-v2-720p-cdp.dts
index 3302d26..966ae2b 100644
--- a/arch/arm/boot/dts/msm8226-v2-cdp.dts
+++ b/arch/arm/boot/dts/msm8226-v2-720p-cdp.dts
@@ -12,7 +12,7 @@
/dts-v1/;
/include/ "msm8226-v2.dtsi"
-/include/ "msm8226-cdp.dtsi"
+/include/ "msm8226-720p-cdp.dtsi"
/include/ "msm8226-camera-sensor-cdp.dtsi"
/ {
diff --git a/arch/arm/boot/dts/msm8226-v2-mtp.dts b/arch/arm/boot/dts/msm8226-v2-720p-mtp.dts
similarity index 95%
rename from arch/arm/boot/dts/msm8226-v2-mtp.dts
rename to arch/arm/boot/dts/msm8226-v2-720p-mtp.dts
index 6034107..0768b75 100644
--- a/arch/arm/boot/dts/msm8226-v2-mtp.dts
+++ b/arch/arm/boot/dts/msm8226-v2-720p-mtp.dts
@@ -12,7 +12,7 @@
/dts-v1/;
/include/ "msm8226-v2.dtsi"
-/include/ "msm8226-mtp.dtsi"
+/include/ "msm8226-720p-mtp.dtsi"
/include/ "msm8226-camera-sensor-mtp.dtsi"
/ {
diff --git a/arch/arm/boot/dts/msm8610-qrd.dtsi b/arch/arm/boot/dts/msm8610-qrd.dtsi
index 71748ea..85bd746 100644
--- a/arch/arm/boot/dts/msm8610-qrd.dtsi
+++ b/arch/arm/boot/dts/msm8610-qrd.dtsi
@@ -309,6 +309,7 @@
qcom,chgr@1000 {
status = "ok";
+ qcom,tchg-mins = <250>;
};
qcom,buck@1100 {
diff --git a/arch/arm/boot/dts/msm8610-v1-qrd-skuab-dvt2.dts b/arch/arm/boot/dts/msm8610-v1-qrd-skuab-dvt2.dts
index 4a08f3f..de48f1f 100644
--- a/arch/arm/boot/dts/msm8610-v1-qrd-skuab-dvt2.dts
+++ b/arch/arm/boot/dts/msm8610-v1-qrd-skuab-dvt2.dts
@@ -33,3 +33,10 @@
&dsi_hx8389b_qhd_vid {
qcom,cont-splash-enabled;
};
+&soc {
+ i2c@f9925000 {
+ fsl@1c {
+ fsl,sensors-position = <7>;
+ };
+ };
+};
\ No newline at end of file
diff --git a/arch/arm/boot/dts/msm8610-v2-qrd-skuab-dvt2.dts b/arch/arm/boot/dts/msm8610-v2-qrd-skuab-dvt2.dts
index 4735554..95a5da5 100644
--- a/arch/arm/boot/dts/msm8610-v2-qrd-skuab-dvt2.dts
+++ b/arch/arm/boot/dts/msm8610-v2-qrd-skuab-dvt2.dts
@@ -56,3 +56,10 @@
&dsi_hx8389b_qhd_vid {
qcom,cont-splash-enabled;
};
+&soc {
+ i2c@f9925000 {
+ fsl@1c {
+ fsl,sensors-position = <7>;
+ };
+ };
+};
\ No newline at end of file
diff --git a/arch/arm/boot/dts/msm8926-cdp.dts b/arch/arm/boot/dts/msm8926-1080p-cdp.dts
similarity index 93%
copy from arch/arm/boot/dts/msm8926-cdp.dts
copy to arch/arm/boot/dts/msm8926-1080p-cdp.dts
index d6e70e6..33e484a 100644
--- a/arch/arm/boot/dts/msm8926-cdp.dts
+++ b/arch/arm/boot/dts/msm8926-1080p-cdp.dts
@@ -13,13 +13,13 @@
/dts-v1/;
/include/ "msm8926.dtsi"
-/include/ "msm8226-cdp.dtsi"
+/include/ "msm8226-1080p-cdp.dtsi"
/include/ "msm8226-camera-sensor-cdp.dtsi"
/ {
model = "Qualcomm MSM 8926 CDP";
compatible = "qcom,msm8926-cdp", "qcom,msm8926", "qcom,cdp";
- qcom,board-id = <1 0>;
+ qcom,board-id = <1 2>;
};
&pm8226_chg {
diff --git a/arch/arm/boot/dts/msm8926-mtp.dts b/arch/arm/boot/dts/msm8926-1080p-mtp.dts
similarity index 92%
copy from arch/arm/boot/dts/msm8926-mtp.dts
copy to arch/arm/boot/dts/msm8926-1080p-mtp.dts
index 624781b..c1217a2 100644
--- a/arch/arm/boot/dts/msm8926-mtp.dts
+++ b/arch/arm/boot/dts/msm8926-1080p-mtp.dts
@@ -13,11 +13,11 @@
/dts-v1/;
/include/ "msm8926.dtsi"
-/include/ "msm8226-mtp.dtsi"
+/include/ "msm8226-1080p-mtp.dtsi"
/include/ "msm8226-camera-sensor-mtp.dtsi"
/ {
model = "Qualcomm MSM 8926 MTP";
compatible = "qcom,msm8926-mtp", "qcom,msm8926", "qcom,mtp";
- qcom,board-id = <8 0>;
+ qcom,board-id = <8 2>;
};
diff --git a/arch/arm/boot/dts/msm8926-cdp.dts b/arch/arm/boot/dts/msm8926-720p-cdp.dts
similarity index 96%
rename from arch/arm/boot/dts/msm8926-cdp.dts
rename to arch/arm/boot/dts/msm8926-720p-cdp.dts
index d6e70e6..80bb5e6 100644
--- a/arch/arm/boot/dts/msm8926-cdp.dts
+++ b/arch/arm/boot/dts/msm8926-720p-cdp.dts
@@ -13,7 +13,7 @@
/dts-v1/;
/include/ "msm8926.dtsi"
-/include/ "msm8226-cdp.dtsi"
+/include/ "msm8226-720p-cdp.dtsi"
/include/ "msm8226-camera-sensor-cdp.dtsi"
/ {
diff --git a/arch/arm/boot/dts/msm8926-mtp.dts b/arch/arm/boot/dts/msm8926-720p-mtp.dts
similarity index 95%
rename from arch/arm/boot/dts/msm8926-mtp.dts
rename to arch/arm/boot/dts/msm8926-720p-mtp.dts
index 624781b..32301fd 100644
--- a/arch/arm/boot/dts/msm8926-mtp.dts
+++ b/arch/arm/boot/dts/msm8926-720p-mtp.dts
@@ -13,7 +13,7 @@
/dts-v1/;
/include/ "msm8926.dtsi"
-/include/ "msm8226-mtp.dtsi"
+/include/ "msm8226-720p-mtp.dtsi"
/include/ "msm8226-camera-sensor-mtp.dtsi"
/ {
diff --git a/arch/arm/boot/dts/msm8926-qrd-skug.dts b/arch/arm/boot/dts/msm8926-qrd-skug.dts
index 6d907ef..15a2d58 100644
--- a/arch/arm/boot/dts/msm8926-qrd-skug.dts
+++ b/arch/arm/boot/dts/msm8926-qrd-skug.dts
@@ -61,8 +61,8 @@
focaltech,fw-name = "ft_8926_qrd_fw.bin";
focaltech,fw-delay-aa-ms = <30>;
focaltech,fw-delay-55-ms = <30>;
- focaltech,fw-upgrade-id1 = <0x79>;
- focaltech,fw-upgrade-id2 = <0x08>;
+ focaltech,fw-upgrade-id1 = <0x11>;
+ focaltech,fw-upgrade-id2 = <0x11>;
focaltech,fw-delay-readid-ms = <10>;
focaltech,fw-delay-era-flsh-ms = <2000>;
focaltech,fw-auto-cal;
diff --git a/arch/arm/boot/dts/msm8974-v1-pm.dtsi b/arch/arm/boot/dts/msm8974-v1-pm.dtsi
index 0115d89..e850c55 100644
--- a/arch/arm/boot/dts/msm8974-v1-pm.dtsi
+++ b/arch/arm/boot/dts/msm8974-v1-pm.dtsi
@@ -208,10 +208,26 @@
<50 172>, /* usb1_hs_async_wakeup_irq */
<53 104>, /* mdss_irq */
<62 222>, /* ee0_krait_hlos_spmi_periph_irq */
+ <0xff 34>, /* APCC_qgicL2ErrorIrptReq */
+ <0xff 35>, /* WDT_barkInt */
+ <0xff 40>, /* qtimer_phy_irq */
<0xff 57>, /* mss_to_apps_irq(0) */
<0xff 58>, /* mss_to_apps_irq(1) */
<0xff 59>, /* mss_to_apps_irq(2) */
<0xff 60>, /* mss_to_apps_irq(3) */
+ <0xff 74>, /* osmmu_CIrpt[1] */
+ <0xff 75>, /* osmmu_CIrpt[0] */
+ <0xff 77>, /* osmmu_CIrpt[0] */
+ <0xff 78>, /* osmmu_CIrpt[0] */
+ <0xff 79>, /* osmmu_CIrpt[0] */
+ <0xff 94>, /* osmmu_CIrpt[0] */
+ <0xff 99>, /* msm_iommu_pmon_nonsecure_irq */
+ <0xff 102>, /* osmmu_CIrpt[1] */
+ <0xff 109>, /* ocmem_dm_nonsec_irq */
+ <0xff 126>, /* bam_irq[0] */
+ <0xff 155>, /* sdcc_irq[0] */
+ <0xff 163>, /* usb30_ee1_irq */
+ <0xff 170>, /* sdcc_pwr_cmd_irq */
<0xff 173>, /* o_wcss_apss_smd_hi */
<0xff 174>, /* o_wcss_apss_smd_med */
<0xff 175>, /* o_wcss_apss_smd_low */
@@ -230,6 +246,7 @@
<0xff 195>, /* lpass_irq_out_apcs(7) */
<0xff 196>, /* lpass_irq_out_apcs(8) */
<0xff 197>, /* lpass_irq_out_apcs(9) */
+ <0xff 198>, /* coresight-tmc-etr interrupt */
<0xff 200>, /* rpm_ipc(4) */
<0xff 201>, /* rpm_ipc(5) */
<0xff 202>, /* rpm_ipc(6) */
@@ -238,7 +255,10 @@
<0xff 205>, /* rpm_ipc(25) */
<0xff 206>, /* rpm_ipc(26) */
<0xff 207>, /* rpm_ipc(27) */
- <0xff 240>; /* summary_irq_kpss */
+ <0xff 240>, /* summary_irq_kpss */
+ <0xff 268>, /* bam_irq[1] */
+ <0xff 270>, /* bam_irq[0] */
+ <0xff 271>; /* bam_irq[0] */
qcom,gpio-parent = <&msmgpio>;
qcom,gpio-map = <3 102>,
diff --git a/arch/arm/boot/dts/msm8974-v2-pm.dtsi b/arch/arm/boot/dts/msm8974-v2-pm.dtsi
index 8836975..eb3a48f 100644
--- a/arch/arm/boot/dts/msm8974-v2-pm.dtsi
+++ b/arch/arm/boot/dts/msm8974-v2-pm.dtsi
@@ -215,6 +215,9 @@
<50 172>, /* usb1_hs_async_wakeup_irq */
<53 104>, /* mdss_irq */
<62 222>, /* ee0_krait_hlos_spmi_periph_irq */
+ <0xff 34>, /* APCC_qgicL2ErrorIrptReq */
+ <0xff 35>, /* WDT_barkInt */
+ <0xff 40>, /* qtimer_phy_irq */
<0xff 56>, /* modem_watchdog */
<0xff 57>, /* mss_to_apps_irq(0) */
<0xff 58>, /* mss_to_apps_irq(1) */
@@ -222,8 +225,21 @@
<0xff 60>, /* mss_to_apps_irq(3) */
<0xff 61>, /* mss_a2_bam_irq */
<0xff 70>, /* iommu_pmon_nonsecure_irq */
+ <0xff 74>, /* osmmu_CIrpt[1] */
+ <0xff 75>, /* osmmu_CIrpt[0] */
+ <0xff 77>, /* osmmu_CIrpt[0] */
+ <0xff 78>, /* osmmu_CIrpt[0] */
+ <0xff 79>, /* osmmu_CIrpt[0] */
+ <0xff 94>, /* osmmu_CIrpt[0] */
<0xff 97>, /* iommu_nonsecure_irq */
+ <0xff 99>, /* msm_iommu_pmon_nonsecure_irq */
+ <0xff 102>, /* osmmu_CIrpt[1] */
<0xff 105>, /* iommu_pmon_nonsecure_irq */
+ <0xff 109>, /* ocmem_dm_nonsec_irq */
+ <0xff 126>, /* bam_irq[0] */
+ <0xff 155>, /* sdcc_irq[0] */
+ <0xff 163>, /* usb30_ee1_irq */
+ <0xff 170>, /* sdcc_pwr_cmd_irq */
<0xff 173>, /* o_wcss_apss_smd_hi */
<0xff 174>, /* o_wcss_apss_smd_med */
<0xff 175>, /* o_wcss_apss_smd_low */
@@ -231,7 +247,6 @@
<0xff 177>, /* o_wcss_apss_wlan_data_xfer_done */
<0xff 178>, /* o_wcss_apss_wlan_rx_data_avail */
<0xff 179>, /* o_wcss_apss_asic_intr */
-
<0xff 181>, /* wcnss watchdog */
<0xff 188>, /* lpass_irq_out_apcs(0) */
<0xff 189>, /* lpass_irq_out_apcs(1) */
@@ -243,6 +258,7 @@
<0xff 195>, /* lpass_irq_out_apcs(7) */
<0xff 196>, /* lpass_irq_out_apcs(8) */
<0xff 197>, /* lpass_irq_out_apcs(9) */
+ <0xff 198>, /* coresight-tmc-etr interrupt */
<0xff 200>, /* rpm_ipc(4) */
<0xff 201>, /* rpm_ipc(5) */
<0xff 202>, /* rpm_ipc(6) */
@@ -252,7 +268,10 @@
<0xff 206>, /* rpm_ipc(26) */
<0xff 207>, /* rpm_ipc(27) */
<0xff 211>, /* usb_dwc3_otg */
- <0xff 240>; /* summary_irq_kpss */
+ <0xff 240>, /* summary_irq_kpss */
+ <0xff 268>, /* bam_irq[1] */
+ <0xff 270>, /* bam_irq[0] */
+ <0xff 271>; /* bam_irq[0] */
qcom,gpio-parent = <&msmgpio>;
qcom,gpio-map = <3 102>,
diff --git a/arch/arm/boot/dts/msm8974pro-pm.dtsi b/arch/arm/boot/dts/msm8974pro-pm.dtsi
index 9e1f83f..5769446 100644
--- a/arch/arm/boot/dts/msm8974pro-pm.dtsi
+++ b/arch/arm/boot/dts/msm8974pro-pm.dtsi
@@ -205,6 +205,9 @@
<50 172>, /* usb1_hs_async_wakeup_irq */
<53 104>, /* mdss_irq */
<62 222>, /* ee0_krait_hlos_spmi_periph_irq */
+ <0xff 34>, /* APCC_qgicL2ErrorIrptReq */
+ <0xff 35>, /* WDT_barkInt */
+ <0xff 40>, /* qtimer_phy_irq */
<0xff 56>, /* modem_watchdog */
<0xff 57>, /* mss_to_apps_irq(0) */
<0xff 58>, /* mss_to_apps_irq(1) */
@@ -212,8 +215,21 @@
<0xff 60>, /* mss_to_apps_irq(3) */
<0xff 61>, /* mss_a2_bam_irq */
<0xff 70>, /* iommu_pmon_nonsecure_irq */
+ <0xff 74>, /* osmmu_CIrpt[1] */
+ <0xff 75>, /* osmmu_CIrpt[0] */
+ <0xff 77>, /* osmmu_CIrpt[0] */
+ <0xff 78>, /* osmmu_CIrpt[0] */
+ <0xff 79>, /* osmmu_CIrpt[0] */
+ <0xff 94>, /* osmmu_CIrpt[0] */
<0xff 97>, /* iommu_nonsecure_irq */
+ <0xff 99>, /* msm_iommu_pmon_nonsecure_irq */
+ <0xff 102>, /* osmmu_CIrpt[1] */
<0xff 105>, /* iommu_pmon_nonsecure_irq */
+ <0xff 109>, /* ocmem_dm_nonsec_irq */
+ <0xff 126>, /* bam_irq[0] */
+ <0xff 155>, /* sdcc_irq[0] */
+ <0xff 163>, /* usb30_ee1_irq */
+ <0xff 170>, /* sdcc_pwr_cmd_irq */
<0xff 173>, /* o_wcss_apss_smd_hi */
<0xff 174>, /* o_wcss_apss_smd_med */
<0xff 175>, /* o_wcss_apss_smd_low */
@@ -233,6 +249,7 @@
<0xff 195>, /* lpass_irq_out_apcs(7) */
<0xff 196>, /* lpass_irq_out_apcs(8) */
<0xff 197>, /* lpass_irq_out_apcs(9) */
+ <0xff 198>, /* coresight-tmc-etr interrupt */
<0xff 200>, /* rpm_ipc(4) */
<0xff 201>, /* rpm_ipc(5) */
<0xff 202>, /* rpm_ipc(6) */
@@ -242,7 +259,10 @@
<0xff 206>, /* rpm_ipc(26) */
<0xff 207>, /* rpm_ipc(27) */
<0xff 211>, /* usb_dwc3_otg */
- <0xff 240>; /* summary_irq_kpss */
+ <0xff 240>, /* summary_irq_kpss */
+ <0xff 268>, /* bam_irq[1] */
+ <0xff 270>, /* bam_irq[0] */
+ <0xff 271>; /* bam_irq[0] */
qcom,gpio-parent = <&msmgpio>;
qcom,gpio-map = <3 102>,
diff --git a/arch/arm/boot/dts/msm8974pro-pm8941.dtsi b/arch/arm/boot/dts/msm8974pro-pm8941.dtsi
index 0f37584..2c06c3c 100644
--- a/arch/arm/boot/dts/msm8974pro-pm8941.dtsi
+++ b/arch/arm/boot/dts/msm8974pro-pm8941.dtsi
@@ -38,18 +38,22 @@
&krait0_vreg {
regulator-max-microvolt = <1120000>;
+ qcom,ldo-delta-voltage = <25000>;
};
&krait1_vreg {
regulator-max-microvolt = <1120000>;
+ qcom,ldo-delta-voltage = <25000>;
};
&krait2_vreg {
regulator-max-microvolt = <1120000>;
+ qcom,ldo-delta-voltage = <25000>;
};
&krait3_vreg {
regulator-max-microvolt = <1120000>;
+ qcom,ldo-delta-voltage = <25000>;
};
&tspp {
diff --git a/arch/arm/boot/dts/msm8974pro-pma8084-regulator.dtsi b/arch/arm/boot/dts/msm8974pro-pma8084-regulator.dtsi
index df00f8a..00e3b8b 100644
--- a/arch/arm/boot/dts/msm8974pro-pma8084-regulator.dtsi
+++ b/arch/arm/boot/dts/msm8974pro-pma8084-regulator.dtsi
@@ -494,7 +494,7 @@
qcom,retention-voltage = <675000>;
qcom,ldo-default-voltage = <750000>;
qcom,ldo-threshold-voltage = <850000>;
- qcom,ldo-delta-voltage = <50000>;
+ qcom,ldo-delta-voltage = <25000>;
qcom,cpu-num = <0>;
};
@@ -510,7 +510,7 @@
qcom,retention-voltage = <675000>;
qcom,ldo-default-voltage = <750000>;
qcom,ldo-threshold-voltage = <850000>;
- qcom,ldo-delta-voltage = <50000>;
+ qcom,ldo-delta-voltage = <25000>;
qcom,cpu-num = <1>;
};
@@ -526,7 +526,7 @@
qcom,retention-voltage = <675000>;
qcom,ldo-default-voltage = <750000>;
qcom,ldo-threshold-voltage = <850000>;
- qcom,ldo-delta-voltage = <50000>;
+ qcom,ldo-delta-voltage = <25000>;
qcom,cpu-num = <2>;
};
@@ -542,7 +542,7 @@
qcom,retention-voltage = <675000>;
qcom,ldo-default-voltage = <750000>;
qcom,ldo-threshold-voltage = <850000>;
- qcom,ldo-delta-voltage = <50000>;
+ qcom,ldo-delta-voltage = <25000>;
qcom,cpu-num = <3>;
};
};
diff --git a/arch/arm/configs/msm8226-perf_defconfig b/arch/arm/configs/msm8226-perf_defconfig
index 7d7bf46..818e052 100644
--- a/arch/arm/configs/msm8226-perf_defconfig
+++ b/arch/arm/configs/msm8226-perf_defconfig
@@ -25,6 +25,7 @@
CONFIG_PANIC_TIMEOUT=5
CONFIG_KALLSYMS_ALL=y
CONFIG_EMBEDDED=y
+# CONFIG_SLUB_DEBUG is not set
CONFIG_PROFILING=y
CONFIG_OPROFILE=m
CONFIG_KPROBES=y
diff --git a/arch/arm/mach-msm/Makefile.boot b/arch/arm/mach-msm/Makefile.boot
index 552ed16..83c1d4c 100644
--- a/arch/arm/mach-msm/Makefile.boot
+++ b/arch/arm/mach-msm/Makefile.boot
@@ -99,28 +99,34 @@
# MSM8226
zreladdr-$(CONFIG_ARCH_MSM8226) := 0x00008000
- dtb-$(CONFIG_ARCH_MSM8226) += msm8226-sim.dtb
- dtb-$(CONFIG_ARCH_MSM8226) += msm8226-fluid.dtb
- dtb-$(CONFIG_ARCH_MSM8226) += msm8226-v1-cdp.dtb
- dtb-$(CONFIG_ARCH_MSM8226) += msm8226-v1-mtp.dtb
- dtb-$(CONFIG_ARCH_MSM8226) += msm8226-v1-qrd-evt.dtb
- dtb-$(CONFIG_ARCH_MSM8226) += msm8226-v1-qrd-dvt.dtb
- dtb-$(CONFIG_ARCH_MSM8226) += msm8226-v2-cdp.dtb
- dtb-$(CONFIG_ARCH_MSM8226) += msm8226-v2-mtp.dtb
- dtb-$(CONFIG_ARCH_MSM8226) += msm8226-v2-qrd-evt.dtb
- dtb-$(CONFIG_ARCH_MSM8226) += msm8226-v2-qrd-dvt.dtb
- dtb-$(CONFIG_ARCH_MSM8226) += msm8926-cdp.dtb
- dtb-$(CONFIG_ARCH_MSM8226) += msm8926-mtp.dtb
- dtb-$(CONFIG_ARCH_MSM8226) += msm8926-qrd.dtb
- dtb-$(CONFIG_ARCH_MSM8226) += msm8926-qrd-skug.dtb
- dtb-$(CONFIG_ARCH_MSM8226) += msm8226-v1-qrd-skuf.dtb
- dtb-$(CONFIG_ARCH_MSM8226) += msm8226-v2-qrd-skuf.dtb
- dtb-$(CONFIG_ARCH_MSM8226) += apq8026-v1-xpm.dtb
- dtb-$(CONFIG_ARCH_MSM8226) += apq8026-v1-cdp.dtb
- dtb-$(CONFIG_ARCH_MSM8226) += apq8026-v1-mtp.dtb
- dtb-$(CONFIG_ARCH_MSM8226) += apq8026-v2-xpm.dtb
- dtb-$(CONFIG_ARCH_MSM8226) += apq8026-v2-cdp.dtb
- dtb-$(CONFIG_ARCH_MSM8226) += apq8026-v2-mtp.dtb
+ dtb-$(CONFIG_ARCH_MSM8226) += msm8226-sim.dtb
+ dtb-$(CONFIG_ARCH_MSM8226) += msm8226-fluid.dtb
+ dtb-$(CONFIG_ARCH_MSM8226) += msm8226-v1-cdp.dtb
+ dtb-$(CONFIG_ARCH_MSM8226) += msm8226-v1-mtp.dtb
+ dtb-$(CONFIG_ARCH_MSM8226) += msm8226-v1-qrd-evt.dtb
+ dtb-$(CONFIG_ARCH_MSM8226) += msm8226-v1-qrd-dvt.dtb
+ dtb-$(CONFIG_ARCH_MSM8226) += msm8226-v2-720p-cdp.dtb
+ dtb-$(CONFIG_ARCH_MSM8226) += msm8226-v2-1080p-cdp.dtb
+ dtb-$(CONFIG_ARCH_MSM8226) += msm8226-v2-720p-mtp.dtb
+ dtb-$(CONFIG_ARCH_MSM8226) += msm8226-v2-1080p-mtp.dtb
+ dtb-$(CONFIG_ARCH_MSM8226) += msm8226-v2-qrd-evt.dtb
+ dtb-$(CONFIG_ARCH_MSM8226) += msm8226-v2-qrd-dvt.dtb
+ dtb-$(CONFIG_ARCH_MSM8226) += msm8926-720p-cdp.dtb
+ dtb-$(CONFIG_ARCH_MSM8226) += msm8926-1080p-cdp.dtb
+ dtb-$(CONFIG_ARCH_MSM8226) += msm8926-720p-mtp.dtb
+ dtb-$(CONFIG_ARCH_MSM8226) += msm8926-1080p-mtp.dtb
+ dtb-$(CONFIG_ARCH_MSM8226) += msm8926-qrd.dtb
+ dtb-$(CONFIG_ARCH_MSM8226) += msm8926-qrd-skug.dtb
+ dtb-$(CONFIG_ARCH_MSM8226) += msm8226-v1-qrd-skuf.dtb
+ dtb-$(CONFIG_ARCH_MSM8226) += msm8226-v2-qrd-skuf.dtb
+ dtb-$(CONFIG_ARCH_MSM8226) += apq8026-v1-xpm.dtb
+ dtb-$(CONFIG_ARCH_MSM8226) += apq8026-v1-cdp.dtb
+ dtb-$(CONFIG_ARCH_MSM8226) += apq8026-v1-mtp.dtb
+ dtb-$(CONFIG_ARCH_MSM8226) += apq8026-v2-xpm.dtb
+ dtb-$(CONFIG_ARCH_MSM8226) += apq8026-v2-720p-cdp.dtb
+ dtb-$(CONFIG_ARCH_MSM8226) += apq8026-v2-1080p-cdp.dtb
+ dtb-$(CONFIG_ARCH_MSM8226) += apq8026-v2-720p-mtp.dtb
+ dtb-$(CONFIG_ARCH_MSM8226) += apq8026-v2-1080p-mtp.dtb
# FSM9XXX
zreladdr-$(CONFIG_ARCH_FSM9XXX) := 0x10008000
diff --git a/arch/arm/mach-msm/board-8226-gpiomux.c b/arch/arm/mach-msm/board-8226-gpiomux.c
index 34e23d1..9767746 100644
--- a/arch/arm/mach-msm/board-8226-gpiomux.c
+++ b/arch/arm/mach-msm/board-8226-gpiomux.c
@@ -185,7 +185,14 @@
static struct msm_gpiomux_config msm_lcd_configs[] __initdata = {
{
- .gpio = 25,
+ .gpio = 25, /* LCD Reset */
+ .settings = {
+ [GPIOMUX_ACTIVE] = &lcd_rst_act_cfg,
+ [GPIOMUX_SUSPENDED] = &lcd_rst_sus_cfg,
+ },
+ },
+ {
+ .gpio = 109, /* LCD Enable */
.settings = {
[GPIOMUX_ACTIVE] = &lcd_rst_act_cfg,
[GPIOMUX_SUSPENDED] = &lcd_rst_sus_cfg,
diff --git a/arch/arm/mach-msm/clock-8610.c b/arch/arm/mach-msm/clock-8610.c
index 45a6b89..89d462c 100644
--- a/arch/arm/mach-msm/clock-8610.c
+++ b/arch/arm/mach-msm/clock-8610.c
@@ -3040,10 +3040,12 @@
"fda00c00.qcom,csiphy"),
CLK_LOOKUP("csiphy_timer_clk", csi0phytimer_clk.c,
"fda00c00.qcom,csiphy"),
+ CLK_LOOKUP("csi_ahb_clk", csi_ahb_clk.c, "fda00c00.qcom,csiphy"),
CLK_LOOKUP("csiphy_timer_src_clk", csi1phytimer_clk_src.c,
"fda01000.qcom,csiphy"),
CLK_LOOKUP("csiphy_timer_clk", csi1phytimer_clk.c,
"fda01000.qcom,csiphy"),
+ CLK_LOOKUP("csi_ahb_clk", csi_ahb_clk.c, "fda01000.qcom,csiphy"),
/* CSID clocks */
CLK_LOOKUP("csi_clk", csi0_clk.c, "fda00000.qcom,csid"),
diff --git a/arch/arm/mach-msm/idle-v7.S b/arch/arm/mach-msm/idle-v7.S
index f8a32b4..2956bd6 100644
--- a/arch/arm/mach-msm/idle-v7.S
+++ b/arch/arm/mach-msm/idle-v7.S
@@ -180,6 +180,7 @@
mov r2, #1
and r1, r2, r1, ASR #30 /* Check if the cache is write back */
orr r1, r0, r1
+ and r1, r1, #1
cmp r1, #1
bne skip
bl v7_flush_dcache_all
diff --git a/arch/arm/mach-msm/smd.c b/arch/arm/mach-msm/smd.c
index 110ab87..cb9697d 100644
--- a/arch/arm/mach-msm/smd.c
+++ b/arch/arm/mach-msm/smd.c
@@ -3243,7 +3243,7 @@
*/
void smd_set_edge_subsys_name(uint32_t edge, const char *subsys_name)
{
- if (edge <= ARRAY_SIZE(edge_to_pids))
+ if (edge < ARRAY_SIZE(edge_to_pids))
strlcpy(edge_to_pids[edge].subsys_name,
subsys_name, SMD_MAX_CH_NAME_LEN);
else
@@ -3258,7 +3258,7 @@
*/
void smd_set_edge_initialized(uint32_t edge)
{
- if (edge <= ARRAY_SIZE(edge_to_pids))
+ if (edge < ARRAY_SIZE(edge_to_pids))
edge_to_pids[edge].initialized = true;
else
pr_err("%s: Invalid edge type[%d]\n", __func__, edge);
diff --git a/arch/arm/mach-msm/socinfo.c b/arch/arm/mach-msm/socinfo.c
index 8af3890..4b68e66 100644
--- a/arch/arm/mach-msm/socinfo.c
+++ b/arch/arm/mach-msm/socinfo.c
@@ -1080,7 +1080,7 @@
msm_get_image_crm_version, msm_set_image_crm_version);
static struct device_attribute select_image =
- __ATTR(select_image, S_IRUGO | S_IWUGO,
+ __ATTR(select_image, S_IRUGO | S_IWUSR,
msm_get_image_number, msm_select_image);
static struct sysdev_class soc_sysdev_class = {
diff --git a/arch/sparc/mm/init_32.c b/arch/sparc/mm/init_32.c
index c5f9021..fbf4eeb 100644
--- a/arch/sparc/mm/init_32.c
+++ b/arch/sparc/mm/init_32.c
@@ -77,7 +77,7 @@
printk("Mem-info:\n");
show_free_areas(filter);
printk("Free swap: %6ldkB\n",
- nr_swap_pages << (PAGE_SHIFT-10));
+ get_nr_swap_pages() << (PAGE_SHIFT-10));
printk("%ld pages of RAM\n", totalram_pages);
printk("%ld free pages\n", nr_free_pages());
#if 0 /* undefined pgtable_cache_size, pgd_cache_size */
diff --git a/arch/tile/mm/pgtable.c b/arch/tile/mm/pgtable.c
index 2410aa8..ea7dd38 100644
--- a/arch/tile/mm/pgtable.c
+++ b/arch/tile/mm/pgtable.c
@@ -61,7 +61,7 @@
global_page_state(NR_PAGETABLE),
global_page_state(NR_BOUNCE),
global_page_state(NR_FILE_PAGES),
- nr_swap_pages);
+ get_nr_swap_pages());
for_each_zone(zone) {
unsigned long flags, order, total = 0, largest_order = -1;
diff --git a/drivers/char/diag/diag_masks.c b/drivers/char/diag/diag_masks.c
index 69e6250..c28b3bd 100644
--- a/drivers/char/diag/diag_masks.c
+++ b/drivers/char/diag/diag_masks.c
@@ -229,83 +229,90 @@
static void diag_disable_log_mask(void)
{
int i = 0;
- struct mask_info *parse_ptr = (struct mask_info *)(driver->log_masks);
+ struct diag_log_mask_t *log_item = NULL;
- pr_debug("diag: disable log masks\n");
- mutex_lock(&driver->diagchar_mutex);
- for (i = 0; i < MAX_EQUIP_ID; i++) {
- pr_debug("diag: equip id %d\n", parse_ptr->equip_id);
- if (!(parse_ptr->equip_id)) /* Reached a null entry */
- break;
- memset(driver->log_masks + parse_ptr->index, 0,
- (parse_ptr->num_items + 7)/8);
- parse_ptr++;
- }
+ mutex_lock(&driver->log_mask_mutex);
+ log_item = (struct diag_log_mask_t *)driver->log_masks;
+ for (i = 0; i < MAX_EQUIP_ID; i++, log_item++)
+ memset(log_item->ptr, 0, MAX_ITEMS_PER_EQUIP_ID);
+
driver->log_status = DIAG_CTRL_MASK_ALL_DISABLED;
- mutex_unlock(&driver->diagchar_mutex);
+ mutex_unlock(&driver->log_mask_mutex);
}
-int chk_equip_id_and_mask(int equip_id, uint8_t *buf)
+static int copy_log_mask_equip(int equip_id, uint8_t *buf)
{
- int i = 0, flag = 0, num_items, offset;
- unsigned char *ptr_data;
- struct mask_info *ptr = (struct mask_info *)(driver->log_masks);
+ int i, ret = 0;
+ uint8_t *temp = buf;
+ struct diag_log_mask_t *log_item = NULL;
+ uint32_t mask_size = 0;
- pr_debug("diag: received equip id = %d\n", equip_id);
- /* Check if this is valid equipment ID */
- for (i = 0; i < MAX_EQUIP_ID; i++) {
- if ((ptr->equip_id == equip_id) && (ptr->index != 0)) {
- offset = ptr->index;
- num_items = ptr->num_items;
- flag = 1;
+ if (!buf)
+ return ret;
+
+ log_item = (struct diag_log_mask_t *)driver->log_masks;
+ for (i = 0; i < MAX_EQUIP_ID; i++, log_item++) {
+ if (log_item->equip_id != equip_id)
+ continue;
+ *(int *)temp = log_item->equip_id;
+ temp += sizeof(int);
+ *(int *)(temp) = log_item->num_items;
+ temp += sizeof(int);
+ mask_size = LOG_ITEMS_TO_SIZE(log_item->num_items);
+ if (mask_size > MAX_ITEMS_PER_EQUIP_ID) {
+ pr_err("diag: Invalid length: %d in %s, perimissible: %d",
+ mask_size, __func__, MAX_ITEMS_PER_EQUIP_ID);
break;
}
- ptr++;
+ if (mask_size > 0) {
+ memcpy(temp, log_item->ptr, mask_size);
+ /*
+ * Return the total number of bytes copied = size of
+ * equip_id (int) + size of num_items (int) + mask_size
+ */
+ ret = (2 * sizeof(int)) + mask_size;
+ }
+ break;
}
- if (!flag)
- return -EPERM;
- ptr_data = driver->log_masks + offset;
- memcpy(buf, ptr_data, (num_items+7)/8);
- return 0;
+
+ return ret;
}
static void diag_update_log_mask(int equip_id, uint8_t *buf, int num_items)
{
- uint8_t *temp = buf;
int i = 0;
- unsigned char *ptr_data;
- int offset = (sizeof(struct mask_info))*MAX_EQUIP_ID;
- struct mask_info *ptr = (struct mask_info *)(driver->log_masks);
+ struct diag_log_mask_t *log_item = NULL;
+ uint32_t mask_size = 0;
- pr_debug("diag: received equip id = %d\n", equip_id);
- mutex_lock(&driver->diagchar_mutex);
- /* Check if we already know index of this equipment ID */
- for (i = 0; i < MAX_EQUIP_ID; i++) {
- if ((ptr->equip_id == equip_id) && (ptr->index != 0)) {
- offset = ptr->index;
- break;
- }
- if ((ptr->equip_id == 0) && (ptr->index == 0)) {
- /* Reached a null entry */
- ptr->equip_id = equip_id;
- ptr->num_items = num_items;
- ptr->index = driver->log_masks_length;
- offset = driver->log_masks_length;
- driver->log_masks_length += ((num_items+7)/8);
- break;
- }
- ptr++;
+ mutex_lock(&driver->log_mask_mutex);
+ driver->log_status = DIAG_CTRL_MASK_INVALID;
+ if (!buf || (equip_id < 0 || equip_id >= MAX_EQUIP_ID) ||
+ num_items < 1) {
+ pr_err("diag: Invalid params in %s, buf: %x equip_id: %d, num_items: %d\n",
+ __func__, (unsigned int)buf, equip_id, num_items);
+ mutex_unlock(&driver->log_mask_mutex);
+ return;
}
- ptr_data = driver->log_masks + offset;
- if (CHK_OVERFLOW(driver->log_masks, ptr_data, driver->log_masks
- + LOG_MASK_SIZE, (num_items+7)/8)) {
- memcpy(ptr_data, temp, (num_items+7)/8);
+ mask_size = LOG_ITEMS_TO_SIZE(num_items);
+ if (mask_size > MAX_ITEMS_PER_EQUIP_ID) {
+ pr_err("diag: In %s, Invalid mask_size %d\n", __func__,
+ mask_size);
+ mutex_unlock(&driver->log_mask_mutex);
+ return;
+ }
+
+ log_item = (struct diag_log_mask_t *)driver->log_masks;
+ for (i = 0; i < MAX_EQUIP_ID; i++, log_item++) {
+ if (log_item->equip_id != equip_id)
+ continue;
+ /* Found the equip id */
+ log_item->num_items = num_items;
+ if (mask_size > 0)
+ memcpy(log_item->ptr, buf, mask_size);
driver->log_status = DIAG_CTRL_MASK_VALID;
- } else {
- pr_err("diag: Not enough buffer space for LOG_MASK\n");
- driver->log_status = DIAG_CTRL_MASK_INVALID;
+ break;
}
- mutex_unlock(&driver->diagchar_mutex);
+ mutex_unlock(&driver->log_mask_mutex);
}
void diag_mask_update_fn(struct work_struct *work)
@@ -335,72 +342,76 @@
void diag_send_log_mask_update(smd_channel_t *ch, int equip_id)
{
void *buf = driver->buf_log_mask_update;
- int header_size = sizeof(struct diag_ctrl_log_mask);
- struct mask_info *ptr = (struct mask_info *)driver->log_masks;
- int i, size, wr_size = -ENOMEM, retry_count = 0;
+ struct diag_log_mask_t *log_item = NULL;
+ struct diag_ctrl_log_mask ctrl_pkt;
+ uint32_t log_mask_size = 0;
+ int wr_size = -ENOMEM, retry_count = 0;
+ int i, header_size, send_once = 0;
+ header_size = sizeof(struct diag_ctrl_log_mask);
+ log_item = (struct diag_log_mask_t *)driver->log_masks;
mutex_lock(&driver->diag_cntl_mutex);
- for (i = 0; i < MAX_EQUIP_ID; i++) {
- size = (ptr->num_items+7)/8;
- /* reached null entry */
- if ((ptr->equip_id == 0) && (ptr->index == 0))
- break;
- driver->log_mask->cmd_type = DIAG_CTRL_MSG_LOG_MASK;
- driver->log_mask->num_items = ptr->num_items;
- driver->log_mask->data_len = 11 + size;
- driver->log_mask->stream_id = 1; /* 2, if dual stream */
- driver->log_mask->equip_id = ptr->equip_id;
- driver->log_mask->status = driver->log_status;
+ for (i = 0; i < MAX_EQUIP_ID; i++, log_item++) {
+ if (equip_id != i && equip_id != ALL_EQUIP_ID)
+ continue;
+ log_mask_size = LOG_ITEMS_TO_SIZE(log_item->num_items);
+ ctrl_pkt.cmd_type = DIAG_CTRL_MSG_LOG_MASK;
+ ctrl_pkt.data_len = 11 + log_mask_size;
+ ctrl_pkt.stream_id = 1;
+ ctrl_pkt.status = driver->log_status;
switch (driver->log_status) {
case DIAG_CTRL_MASK_ALL_DISABLED:
- driver->log_mask->log_mask_size = 0;
+ ctrl_pkt.equip_id = 0;
+ ctrl_pkt.num_items = 0;
+ ctrl_pkt.log_mask_size = 0;
+ send_once = 1;
break;
case DIAG_CTRL_MASK_ALL_ENABLED:
- driver->log_mask->log_mask_size = 0;
+ ctrl_pkt.equip_id = 0;
+ ctrl_pkt.num_items = 0;
+ ctrl_pkt.log_mask_size = 0;
+ send_once = 1;
break;
case DIAG_CTRL_MASK_VALID:
- driver->log_mask->log_mask_size = size;
+ ctrl_pkt.equip_id = i;
+ ctrl_pkt.num_items = log_item->num_items;
+ ctrl_pkt.log_mask_size = log_mask_size;
+ send_once = 0;
break;
default:
- /* Log status is not set or the buffer is corrupted */
pr_err("diag: In %s, invalid status %d", __func__,
- driver->log_status);
- driver->log_mask->status = DIAG_CTRL_MASK_INVALID;
- }
-
- if (driver->log_mask->status == DIAG_CTRL_MASK_INVALID) {
+ driver->log_status);
mutex_unlock(&driver->diag_cntl_mutex);
return;
}
- /* send only desired update, NOT ALL */
- if (equip_id == ALL_EQUIP_ID || equip_id ==
- driver->log_mask->equip_id) {
- memcpy(buf, driver->log_mask, header_size);
- if (driver->log_status == DIAG_CTRL_MASK_VALID)
- memcpy(buf + header_size,
- driver->log_masks+ptr->index, size);
- if (ch) {
- while (retry_count < 3) {
- wr_size = smd_write(ch, buf,
- header_size + size);
- if (wr_size == -ENOMEM) {
- retry_count++;
- usleep_range(10000, 10100);
- } else
- break;
- }
- if (wr_size != header_size + size)
- pr_err("diag: log mask update failed %d, tried %d",
- wr_size, header_size + size);
- else
- pr_debug("diag: updated log equip ID %d,len %d\n",
- driver->log_mask->equip_id,
- driver->log_mask->log_mask_size);
- } else
- pr_err("diag: ch not valid for log update\n");
+ memcpy(buf, &ctrl_pkt, header_size);
+ if (log_mask_size > 0) {
+ memcpy(buf + header_size, log_item->ptr,
+ log_mask_size);
}
- ptr++;
+
+ if (ch) {
+ while (retry_count < 3) {
+ wr_size = smd_write(ch, buf,
+ header_size + log_mask_size);
+ if (wr_size == -ENOMEM) {
+ retry_count++;
+ usleep_range(10000, 10100);
+ } else
+ break;
+ }
+ if (wr_size != header_size + log_mask_size)
+ pr_err("diag: log mask update failed %d, tried %d",
+ wr_size, header_size + log_mask_size);
+ else
+ pr_debug("diag: updated log equip ID %d,len %d\n",
+ i, log_mask_size);
+ } else
+ pr_err("diag: ch not valid for log update\n");
+ if (send_once)
+ break;
}
+
mutex_unlock(&driver->diag_cntl_mutex);
}
@@ -623,7 +634,7 @@
int ssid_first, ssid_last, ssid_range;
int rt_mask, rt_first_ssid, rt_last_ssid, rt_mask_size;
uint8_t *rt_mask_ptr;
- int equip_id, num_items;
+ int equip_id, copy_len;
#if defined(CONFIG_DIAG_OVER_USB)
int payload_length;
#endif
@@ -631,7 +642,6 @@
/* Set log masks */
if (*buf == 0x73 && *(int *)(buf+4) == 3) {
buf += 8;
- /* Read Equip ID and pass as first param below*/
diag_update_log_mask(*(int *)buf, buf+8, *(int *)(buf+4));
diag_update_userspace_clients(LOG_MASKS_TYPE);
#if defined(CONFIG_DIAG_OVER_USB)
@@ -639,7 +649,8 @@
driver->apps_rsp_buf[0] = 0x73;
*(int *)(driver->apps_rsp_buf + 4) = 0x3; /* op. ID */
*(int *)(driver->apps_rsp_buf + 8) = 0x0; /* success */
- payload_length = 8 + ((*(int *)(buf + 4)) + 7)/8;
+ payload_length = 8 +
+ LOG_ITEMS_TO_SIZE(*(int *)(buf + 4));
if (payload_length > APPS_BUF_SIZE - 12) {
pr_err("diag: log masks: buffer overflow\n");
return -EIO;
@@ -663,20 +674,16 @@
if (!(driver->smd_data[MODEM_DATA].ch) &&
chk_apps_only()) {
equip_id = *(int *)(buf + 8);
- num_items = *(int *)(buf + 12);
driver->apps_rsp_buf[0] = 0x73;
driver->apps_rsp_buf[1] = 0x0;
driver->apps_rsp_buf[2] = 0x0;
driver->apps_rsp_buf[3] = 0x0;
*(int *)(driver->apps_rsp_buf + 4) = 0x4;
- if (!chk_equip_id_and_mask(equip_id,
- driver->apps_rsp_buf+20))
- *(int *)(driver->apps_rsp_buf + 8) = 0x0;
- else
- *(int *)(driver->apps_rsp_buf + 8) = 0x1;
- *(int *)(driver->apps_rsp_buf + 12) = equip_id;
- *(int *)(driver->apps_rsp_buf + 16) = num_items;
- encode_rsp_and_send(20+(num_items+7)/8-1);
+ copy_len = copy_log_mask_equip(equip_id,
+ driver->apps_rsp_buf + 12);
+ *(int *)(driver->apps_rsp_buf + 8) =
+ (copy_len == 0) ? 1 : 0;
+ encode_rsp_and_send(12 + copy_len);
return 0;
}
#endif
@@ -858,6 +865,19 @@
return packet_type;
}
+static void diag_log_mask_init(void)
+{
+ struct diag_log_mask_t *log_item = NULL;
+ uint8_t i;
+
+ mutex_init(&driver->log_mask_mutex);
+ log_item = (struct diag_log_mask_t *)driver->log_masks;
+ for (i = 0; i < MAX_EQUIP_ID; i++, log_item++) {
+ log_item->equip_id = i;
+ log_item->num_items = LOG_GET_ITEM_NUM(log_code_last_tbl[i]);
+ }
+}
+
void diag_masks_init(void)
{
driver->event_status = DIAG_CTRL_MASK_INVALID;
@@ -936,7 +956,7 @@
goto err;
kmemleak_not_leak(driver->log_masks);
}
- driver->log_masks_length = (sizeof(struct mask_info))*MAX_EQUIP_ID;
+ diag_log_mask_init();
if (driver->event_masks == NULL) {
driver->event_masks = kzalloc(EVENT_MASK_SIZE, GFP_KERNEL);
if (driver->event_masks == NULL)
diff --git a/drivers/char/diag/diag_masks.h b/drivers/char/diag/diag_masks.h
index c66a4b6..856d4fc 100644
--- a/drivers/char/diag/diag_masks.h
+++ b/drivers/char/diag/diag_masks.h
@@ -15,7 +15,12 @@
#include "diagfwd.h"
-int chk_equip_id_and_mask(int equip_id, uint8_t *buf);
+struct diag_log_mask_t {
+ uint8_t equip_id;
+ uint32_t num_items;
+ uint8_t ptr[MAX_ITEMS_PER_EQUIP_ID];
+} __packed;
+
void diag_send_event_mask_update(smd_channel_t *, int num_bytes);
void diag_send_msg_mask_update(smd_channel_t *, int ssid_first,
int ssid_last, int proc);
diff --git a/drivers/char/diag/diagchar.h b/drivers/char/diag/diagchar.h
index 9d9d89b..5be77c4 100644
--- a/drivers/char/diag/diagchar.h
+++ b/drivers/char/diag/diagchar.h
@@ -82,11 +82,14 @@
* And there are MSG_MASK_TBL_CNT rows.
*/
#define MSG_MASK_SIZE ((MAX_SSID_PER_RANGE+3) * 4 * MSG_MASK_TBL_CNT)
-#define LOG_MASK_SIZE 8000
+#define MAX_EQUIP_ID 16
+#define MAX_ITEMS_PER_EQUIP_ID 512
+#define LOG_MASK_ITEM_SIZE (5 + MAX_ITEMS_PER_EQUIP_ID)
+#define LOG_MASK_SIZE (MAX_EQUIP_ID * LOG_MASK_ITEM_SIZE)
#define EVENT_MASK_SIZE 1000
#define USER_SPACE_DATA 8192
#define PKT_SIZE 4096
-#define MAX_EQUIP_ID 15
+
#define DIAG_CTRL_MSG_LOG_MASK 9
#define DIAG_CTRL_MSG_EVENT_MASK 10
#define DIAG_CTRL_MSG_F3_MASK 11
@@ -334,6 +337,7 @@
struct diag_ctrl_log_mask *log_mask;
struct diag_ctrl_msg_mask *msg_mask;
struct diag_ctrl_feature_mask *feature_mask;
+ struct mutex log_mask_mutex;
/* State for diag forwarding */
struct diag_smd_info smd_data[NUM_SMD_DATA_CHANNELS];
struct diag_smd_info smd_cntl[NUM_SMD_CONTROL_CHANNELS];
@@ -380,7 +384,6 @@
uint8_t msg_status;
uint8_t *log_masks;
uint8_t log_status;
- int log_masks_length;
uint8_t *event_masks;
uint8_t event_status;
uint8_t log_on_demand_support;
diff --git a/drivers/char/diag/diagfwd.c b/drivers/char/diag/diagfwd.c
index 2beb143..ba3ecc2 100644
--- a/drivers/char/diag/diagfwd.c
+++ b/drivers/char/diag/diagfwd.c
@@ -1294,22 +1294,38 @@
driver->apps_rsp_buf[0] = 0x73;
*(int *)(driver->apps_rsp_buf + 4) = 0x1; /* operation ID */
*(int *)(driver->apps_rsp_buf + 8) = 0x0; /* success code */
- *(int *)(driver->apps_rsp_buf + 12) = LOG_GET_ITEM_NUM(LOG_0);
- *(int *)(driver->apps_rsp_buf + 16) = LOG_GET_ITEM_NUM(LOG_1);
- *(int *)(driver->apps_rsp_buf + 20) = LOG_GET_ITEM_NUM(LOG_2);
- *(int *)(driver->apps_rsp_buf + 24) = LOG_GET_ITEM_NUM(LOG_3);
- *(int *)(driver->apps_rsp_buf + 28) = LOG_GET_ITEM_NUM(LOG_4);
- *(int *)(driver->apps_rsp_buf + 32) = LOG_GET_ITEM_NUM(LOG_5);
- *(int *)(driver->apps_rsp_buf + 36) = LOG_GET_ITEM_NUM(LOG_6);
- *(int *)(driver->apps_rsp_buf + 40) = LOG_GET_ITEM_NUM(LOG_7);
- *(int *)(driver->apps_rsp_buf + 44) = LOG_GET_ITEM_NUM(LOG_8);
- *(int *)(driver->apps_rsp_buf + 48) = LOG_GET_ITEM_NUM(LOG_9);
- *(int *)(driver->apps_rsp_buf + 52) = LOG_GET_ITEM_NUM(LOG_10);
- *(int *)(driver->apps_rsp_buf + 56) = LOG_GET_ITEM_NUM(LOG_11);
- *(int *)(driver->apps_rsp_buf + 60) = LOG_GET_ITEM_NUM(LOG_12);
- *(int *)(driver->apps_rsp_buf + 64) = LOG_GET_ITEM_NUM(LOG_13);
- *(int *)(driver->apps_rsp_buf + 68) = LOG_GET_ITEM_NUM(LOG_14);
- *(int *)(driver->apps_rsp_buf + 72) = LOG_GET_ITEM_NUM(LOG_15);
+ *(int *)(driver->apps_rsp_buf + 12) =
+ LOG_GET_ITEM_NUM(log_code_last_tbl[0]);
+ *(int *)(driver->apps_rsp_buf + 16) =
+ LOG_GET_ITEM_NUM(log_code_last_tbl[1]);
+ *(int *)(driver->apps_rsp_buf + 20) =
+ LOG_GET_ITEM_NUM(log_code_last_tbl[2]);
+ *(int *)(driver->apps_rsp_buf + 24) =
+ LOG_GET_ITEM_NUM(log_code_last_tbl[3]);
+ *(int *)(driver->apps_rsp_buf + 28) =
+ LOG_GET_ITEM_NUM(log_code_last_tbl[4]);
+ *(int *)(driver->apps_rsp_buf + 32) =
+ LOG_GET_ITEM_NUM(log_code_last_tbl[5]);
+ *(int *)(driver->apps_rsp_buf + 36) =
+ LOG_GET_ITEM_NUM(log_code_last_tbl[6]);
+ *(int *)(driver->apps_rsp_buf + 40) =
+ LOG_GET_ITEM_NUM(log_code_last_tbl[7]);
+ *(int *)(driver->apps_rsp_buf + 44) =
+ LOG_GET_ITEM_NUM(log_code_last_tbl[8]);
+ *(int *)(driver->apps_rsp_buf + 48) =
+ LOG_GET_ITEM_NUM(log_code_last_tbl[9]);
+ *(int *)(driver->apps_rsp_buf + 52) =
+ LOG_GET_ITEM_NUM(log_code_last_tbl[10]);
+ *(int *)(driver->apps_rsp_buf + 56) =
+ LOG_GET_ITEM_NUM(log_code_last_tbl[11]);
+ *(int *)(driver->apps_rsp_buf + 60) =
+ LOG_GET_ITEM_NUM(log_code_last_tbl[12]);
+ *(int *)(driver->apps_rsp_buf + 64) =
+ LOG_GET_ITEM_NUM(log_code_last_tbl[13]);
+ *(int *)(driver->apps_rsp_buf + 68) =
+ LOG_GET_ITEM_NUM(log_code_last_tbl[14]);
+ *(int *)(driver->apps_rsp_buf + 72) =
+ LOG_GET_ITEM_NUM(log_code_last_tbl[15]);
encode_rsp_and_send(75);
return 0;
}
diff --git a/drivers/input/touchscreen/synaptics_fw_update.c b/drivers/input/touchscreen/synaptics_fw_update.c
index 70c1307..7282c2e 100644
--- a/drivers/input/touchscreen/synaptics_fw_update.c
+++ b/drivers/input/touchscreen/synaptics_fw_update.c
@@ -353,7 +353,7 @@
if (img->is_contain_build_info) {
img->firmware_id = extract_uint(data->firmware_id);
- img->package_id = (data->pkg_id_rev_msb << 8) |
+ img->package_id = (data->pkg_id_msb << 8) |
data->pkg_id_lsb;
img->package_revision_id = (data->pkg_id_rev_msb << 8) |
data->pkg_id_rev_lsb;
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
index fb1caea..ea0195d 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
@@ -623,6 +623,12 @@
goto reg_cfg_failed;
}
+ if (!proc_cmd->cmd_len) {
+ pr_err("%s: Passed cmd_len as 0\n", __func__);
+ rc = -EINVAL;
+ goto cfg_data_failed;
+ }
+
cfg_data = kzalloc(proc_cmd->cmd_len, GFP_KERNEL);
if (!cfg_data) {
pr_err("%s: cfg_data alloc failed\n", __func__);
diff --git a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c
old mode 100644
new mode 100755
index 89016ec..de098c9
--- a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c
+++ b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c
@@ -200,17 +200,17 @@
ispif->base + ISPIF_VFE_m_INTF_CMD_0(i));
msm_camera_io_w(ISPIF_STOP_INTF_IMMEDIATELY,
ispif->base + ISPIF_VFE_m_INTF_CMD_1(i));
-
+ pr_debug("%s: base %x", __func__, (unsigned int)ispif->base);
msm_camera_io_w(0, ispif->base +
ISPIF_VFE_m_PIX_INTF_n_CID_MASK(i, 0));
msm_camera_io_w(0, ispif->base +
ISPIF_VFE_m_PIX_INTF_n_CID_MASK(i, 1));
msm_camera_io_w(0, ispif->base +
- ISPIF_VFE_m_PIX_INTF_n_CID_MASK(i, 0));
+ ISPIF_VFE_m_RDI_INTF_n_CID_MASK(i, 0));
msm_camera_io_w(0, ispif->base +
- ISPIF_VFE_m_PIX_INTF_n_CID_MASK(i, 1));
+ ISPIF_VFE_m_RDI_INTF_n_CID_MASK(i, 1));
msm_camera_io_w(0, ispif->base +
- ISPIF_VFE_m_PIX_INTF_n_CID_MASK(i, 2));
+ ISPIF_VFE_m_RDI_INTF_n_CID_MASK(i, 2));
msm_camera_io_w(0, ispif->base +
ISPIF_VFE_m_PIX_INTF_n_CROP(i, 0));
diff --git a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c
index 8b8d23b..2124b13 100644
--- a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c
+++ b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c
@@ -926,35 +926,35 @@
cpp_dev->cpp_open_cnt--;
if (cpp_dev->cpp_open_cnt == 0) {
- pr_err("%s: irq_status: 0x%x\n", __func__,
+ pr_debug("irq_status: 0x%x\n",
msm_camera_io_r(cpp_dev->cpp_hw_base + 0x4));
- pr_err("%s: DEBUG_SP: 0x%x\n", __func__,
+ pr_debug("DEBUG_SP: 0x%x\n",
msm_camera_io_r(cpp_dev->cpp_hw_base + 0x40));
- pr_err("%s: DEBUG_T: 0x%x\n", __func__,
+ pr_debug("DEBUG_T: 0x%x\n",
msm_camera_io_r(cpp_dev->cpp_hw_base + 0x44));
- pr_err("%s: DEBUG_N: 0x%x\n", __func__,
+ pr_debug("DEBUG_N: 0x%x\n",
msm_camera_io_r(cpp_dev->cpp_hw_base + 0x48));
- pr_err("%s: DEBUG_R: 0x%x\n", __func__,
+ pr_debug("DEBUG_R: 0x%x\n",
msm_camera_io_r(cpp_dev->cpp_hw_base + 0x4C));
- pr_err("%s: DEBUG_OPPC: 0x%x\n", __func__,
+ pr_debug("DEBUG_OPPC: 0x%x\n",
msm_camera_io_r(cpp_dev->cpp_hw_base + 0x50));
- pr_err("%s: DEBUG_MO: 0x%x\n", __func__,
+ pr_debug("DEBUG_MO: 0x%x\n",
msm_camera_io_r(cpp_dev->cpp_hw_base + 0x54));
- pr_err("%s: DEBUG_TIMER0: 0x%x\n", __func__,
+ pr_debug("DEBUG_TIMER0: 0x%x\n",
msm_camera_io_r(cpp_dev->cpp_hw_base + 0x60));
- pr_err("%s: DEBUG_TIMER1: 0x%x\n", __func__,
+ pr_debug("DEBUG_TIMER1: 0x%x\n",
msm_camera_io_r(cpp_dev->cpp_hw_base + 0x64));
- pr_err("%s: DEBUG_GPI: 0x%x\n", __func__,
+ pr_debug("DEBUG_GPI: 0x%x\n",
msm_camera_io_r(cpp_dev->cpp_hw_base + 0x70));
- pr_err("%s: DEBUG_GPO: 0x%x\n", __func__,
+ pr_debug("DEBUG_GPO: 0x%x\n",
msm_camera_io_r(cpp_dev->cpp_hw_base + 0x74));
- pr_err("%s: DEBUG_T0: 0x%x\n", __func__,
+ pr_debug("DEBUG_T0: 0x%x\n",
msm_camera_io_r(cpp_dev->cpp_hw_base + 0x80));
- pr_err("%s: DEBUG_R0: 0x%x\n", __func__,
+ pr_debug("DEBUG_R0: 0x%x\n",
msm_camera_io_r(cpp_dev->cpp_hw_base + 0x84));
- pr_err("%s: DEBUG_T1: 0x%x\n", __func__,
+ pr_debug("DEBUG_T1: 0x%x\n",
msm_camera_io_r(cpp_dev->cpp_hw_base + 0x88));
- pr_err("%s: DEBUG_R1: 0x%x\n", __func__,
+ pr_debug("DEBUG_R1: 0x%x\n",
msm_camera_io_r(cpp_dev->cpp_hw_base + 0x8C));
msm_camera_io_w(0x0, cpp_dev->base + MSM_CPP_MICRO_CLKEN_CTL);
cpp_deinit_mem(cpp_dev);
@@ -1712,6 +1712,7 @@
struct cpp_device *cpp_dev = v4l2_get_subdevdata(sd);
struct msm_camera_v4l2_ioctl_t *ioctl_ptr = arg;
struct msm_cpp_frame_info_t inst_info;
+ memset(&inst_info, 0, sizeof(struct msm_cpp_frame_info_t));
for (i = 0; i < MAX_ACTIVE_CPP_INSTANCE; i++) {
if (cpp_dev->cpp_subscribe_list[i].vfh == vfh) {
inst_info.inst_id = i;
diff --git a/drivers/media/platform/msm/camera_v2/sensor/csiphy/msm_csiphy.c b/drivers/media/platform/msm/camera_v2/sensor/csiphy/msm_csiphy.c
old mode 100644
new mode 100755
index 9384a5b..d8608ae
--- a/drivers/media/platform/msm/camera_v2/sensor/csiphy/msm_csiphy.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/csiphy/msm_csiphy.c
@@ -177,6 +177,7 @@
static struct msm_cam_clk_info csiphy_8610_clk_info[] = {
{"csiphy_timer_src_clk", 200000000},
{"csiphy_timer_clk", -1},
+ {"csi_ahb_clk", -1},
};
static struct msm_cam_clk_info csiphy_8974_clk_info[] = {
diff --git a/drivers/media/platform/msm/vidc/hfi_response_handler.c b/drivers/media/platform/msm/vidc/hfi_response_handler.c
index abdb039..3fd5d3a 100644
--- a/drivers/media/platform/msm/vidc/hfi_response_handler.c
+++ b/drivers/media/platform/msm/vidc/hfi_response_handler.c
@@ -1183,42 +1183,78 @@
callback(SESSION_GET_SEQ_HDR_DONE, &data_done);
}
-void hfi_process_sys_property_info(
- struct hfi_property_sys_image_version_info_type *pkt)
+static void hfi_process_sys_get_prop_image_version(
+ struct hfi_msg_sys_property_info_packet *pkt)
{
int i = 0;
u32 smem_block_size = 0;
u8 *smem_table_ptr;
char version[256];
+ const u32 version_string_size = 128;
const u32 smem_image_index_venus = 14 * 128;
+ u8 *str_image_version;
+ int req_bytes;
- if (!pkt || !pkt->string_size) {
+ req_bytes = pkt->size - sizeof(*pkt);
+ if (req_bytes < version_string_size ||
+ !pkt->rg_property_data[1] ||
+ pkt->num_properties > 1) {
+ dprintk(VIDC_ERR,
+ "hfi_process_sys_get_prop_image_version:bad_pkt: %d",
+ req_bytes);
+ return;
+ }
+ str_image_version = (u8 *)&pkt->rg_property_data[1];
+ /*
+ * The version string returned by firmware includes null
+ * characters at the start and in between. Replace the null
+ * characters with space, to print the version info.
+ */
+ for (i = 0; i < version_string_size; i++) {
+ if (str_image_version[i] != '\0')
+ version[i] = str_image_version[i];
+ else
+ version[i] = ' ';
+ }
+ version[i] = '\0';
+ dprintk(VIDC_DBG, "F/W version: %s\n", version);
+
+ smem_table_ptr = smem_get_entry(SMEM_IMAGE_VERSION_TABLE,
+ &smem_block_size);
+ if (smem_table_ptr &&
+ ((smem_image_index_venus +
+ version_string_size) <= smem_block_size))
+ memcpy(smem_table_ptr + smem_image_index_venus,
+ str_image_version, version_string_size);
+}
+
+static void hfi_process_sys_property_info(
+ struct hfi_msg_sys_property_info_packet *pkt)
+{
+ if (!pkt) {
dprintk(VIDC_ERR, "%s: invalid param\n", __func__);
return;
}
-
- if (pkt->string_size < sizeof(version)) {
- /*
- * The version string returned by firmware includes null
- * characters at the start and in between. Replace the null
- * characters with space, to print the version info.
- */
- for (i = 0; i < pkt->string_size; i++) {
- if (pkt->str_image_version[i] != '\0')
- version[i] = pkt->str_image_version[i];
- else
- version[i] = ' ';
- }
- version[i] = '\0';
- dprintk(VIDC_DBG, "F/W version: %s\n", version);
+ if (pkt->size < sizeof(*pkt)) {
+ dprintk(VIDC_ERR,
+ "hfi_process_sys_property_info: bad_pkt_size\n");
+ return;
+ }
+ if (pkt->num_properties == 0) {
+ dprintk(VIDC_ERR,
+ "hfi_process_sys_property_info: no_properties\n");
+ return;
}
- smem_table_ptr = smem_get_entry(SMEM_IMAGE_VERSION_TABLE,
- &smem_block_size);
- if (smem_table_ptr &&
- ((smem_image_index_venus + 128) <= smem_block_size))
- memcpy(smem_table_ptr + smem_image_index_venus,
- (u8 *)pkt->str_image_version, 128);
+ switch (pkt->rg_property_data[0]) {
+ case HFI_PROPERTY_SYS_IMAGE_VERSION:
+ hfi_process_sys_get_prop_image_version(pkt);
+ break;
+ default:
+ dprintk(VIDC_ERR,
+ "hfi_process_sys_property_info:unknown_prop_id: %d\n",
+ pkt->rg_property_data[0]);
+ }
}
u32 hfi_process_msg_packet(
@@ -1263,7 +1299,7 @@
break;
case HFI_MSG_SYS_PROPERTY_INFO:
hfi_process_sys_property_info(
- (struct hfi_property_sys_image_version_info_type *)
+ (struct hfi_msg_sys_property_info_packet *)
msg_hdr);
break;
case HFI_MSG_SYS_SESSION_END_DONE:
diff --git a/drivers/media/platform/msm/vidc/msm_vdec.c b/drivers/media/platform/msm/vidc/msm_vdec.c
index 502d4bc..efa195e 100644
--- a/drivers/media/platform/msm/vidc/msm_vdec.c
+++ b/drivers/media/platform/msm/vidc/msm_vdec.c
@@ -1820,7 +1820,7 @@
int msm_vdec_ctrl_init(struct msm_vidc_inst *inst)
{
int idx = 0;
- struct v4l2_ctrl_config ctrl_cfg;
+ struct v4l2_ctrl_config ctrl_cfg = {0};
int ret_val = 0;
ret_val = v4l2_ctrl_handler_init(&inst->ctrl_handler, NUM_CTRLS);
diff --git a/drivers/media/platform/msm/vidc/msm_venc.c b/drivers/media/platform/msm/vidc/msm_venc.c
index f9b5519..c0bf32c 100644
--- a/drivers/media/platform/msm/vidc/msm_venc.c
+++ b/drivers/media/platform/msm/vidc/msm_venc.c
@@ -2662,7 +2662,7 @@
{
int idx = 0;
- struct v4l2_ctrl_config ctrl_cfg;
+ struct v4l2_ctrl_config ctrl_cfg = {0};
int ret_val = 0;
ret_val = v4l2_ctrl_handler_init(&inst->ctrl_handler, NUM_CTRLS);
if (ret_val) {
diff --git a/drivers/power/qpnp-charger.c b/drivers/power/qpnp-charger.c
index a65ac5b..a627ec2 100644
--- a/drivers/power/qpnp-charger.c
+++ b/drivers/power/qpnp-charger.c
@@ -369,6 +369,7 @@
struct alarm reduce_power_stage_alarm;
struct work_struct reduce_power_stage_work;
bool power_stage_workaround_running;
+ bool power_stage_workaround_enable;
};
@@ -2151,7 +2152,8 @@
if ((chip->flags & POWER_STAGE_WA)
&& ((ret.intval / 1000) > USB_WALL_THRESHOLD_MA)
- && !chip->power_stage_workaround_running) {
+ && !chip->power_stage_workaround_running
+ && chip->power_stage_workaround_enable) {
chip->power_stage_workaround_running = true;
pr_debug("usb wall chg inserted starting power stage workaround charger_monitor = %d\n",
charger_monitor);
@@ -4124,6 +4126,10 @@
if (chip->use_default_batt_values)
chip->charging_disabled = true;
+ chip->power_stage_workaround_enable =
+ of_property_read_bool(chip->spmi->dev.of_node,
+ "qcom,power-stage-reduced");
+
of_get_property(chip->spmi->dev.of_node, "qcom,thermal-mitigation",
&(chip->thermal_levels));
diff --git a/drivers/usb/gadget/f_qdss.c b/drivers/usb/gadget/f_qdss.c
index dcfa2bc..7e474f3 100644
--- a/drivers/usb/gadget/f_qdss.c
+++ b/drivers/usb/gadget/f_qdss.c
@@ -18,6 +18,7 @@
#include <linux/usb/usb_qdss.h>
#include <linux/usb/msm_hsusb.h>
+#include "gadget_chips.h"
#include "f_qdss.h"
#include "u_qdss.c"
@@ -395,7 +396,9 @@
goto fail;
}
}
- dwc3_tx_fifo_resize_request(qdss->data, true);
+
+ if (gadget_is_dwc3(gadget))
+ dwc3_tx_fifo_resize_request(qdss->data, true);
return 0;
fail:
@@ -408,12 +411,15 @@
static void qdss_unbind(struct usb_configuration *c, struct usb_function *f)
{
struct f_qdss *qdss = func_to_qdss(f);
+ struct usb_gadget *gadget = c->cdev->gadget;
pr_debug("qdss_unbind\n");
- dwc3_tx_fifo_resize_request(qdss->data, false);
+ if (gadget_is_dwc3(gadget))
+ dwc3_tx_fifo_resize_request(qdss->data, false);
+
clear_eps(f);
- clear_desc(c->cdev->gadget, f);
+ clear_desc(gadget, f);
}
static void qdss_eps_disable(struct usb_function *f)
@@ -824,7 +830,8 @@
ch->app_conn = 0;
spin_unlock_irqrestore(&d_lock, flags);
- msm_dwc3_restart_usb_session(gadget);
+ if (gadget_is_dwc3(gadget))
+ msm_dwc3_restart_usb_session(gadget);
}
EXPORT_SYMBOL(usb_qdss_close);
diff --git a/drivers/usb/gadget/f_rndis.c b/drivers/usb/gadget/f_rndis.c
index 7903764..aee7b58 100644
--- a/drivers/usb/gadget/f_rndis.c
+++ b/drivers/usb/gadget/f_rndis.c
@@ -379,13 +379,35 @@
struct sk_buff *skb)
{
struct sk_buff *skb2;
+ struct rndis_packet_msg_type *header = NULL;
+ struct f_rndis *rndis = func_to_rndis(&port->func);
- skb2 = skb_realloc_headroom(skb, sizeof(struct rndis_packet_msg_type));
- if (skb2)
- rndis_add_hdr(skb2);
+ if (rndis->port.multi_pkt_xfer) {
+ if (port->header) {
+ header = port->header;
+ memset(header, 0, sizeof(*header));
+ header->MessageType = cpu_to_le32(REMOTE_NDIS_PACKET_MSG);
+ header->MessageLength = cpu_to_le32(skb->len +
+ sizeof(*header));
+ header->DataOffset = cpu_to_le32(36);
+ header->DataLength = cpu_to_le32(skb->len);
+ pr_debug("MessageLength:%d DataLength:%d\n",
+ header->MessageLength,
+ header->DataLength);
+ return skb;
+ } else {
+ pr_err("RNDIS header is NULL.\n");
+ return NULL;
+ }
+ } else {
+ skb2 = skb_realloc_headroom(skb,
+ sizeof(struct rndis_packet_msg_type));
+ if (skb2)
+ rndis_add_hdr(skb2);
- dev_kfree_skb_any(skb);
- return skb2;
+ dev_kfree_skb_any(skb);
+ return skb2;
+ }
}
static void rndis_response_available(void *_rndis)
diff --git a/drivers/usb/gadget/u_ether.c b/drivers/usb/gadget/u_ether.c
index 9e789c5..734619f 100644
--- a/drivers/usb/gadget/u_ether.c
+++ b/drivers/usb/gadget/u_ether.c
@@ -197,6 +197,7 @@
}
static void rx_complete(struct usb_ep *ep, struct usb_request *req);
+static void tx_complete(struct usb_ep *ep, struct usb_request *req);
static int
rx_submit(struct eth_dev *dev, struct usb_request *req, gfp_t gfp_flags)
@@ -256,7 +257,6 @@
req->buf = skb->data;
req->length = size;
- req->complete = rx_complete;
req->context = skb;
retval = usb_ep_queue(out, req, gfp_flags);
@@ -349,6 +349,7 @@
{
unsigned i;
struct usb_request *req;
+ bool usb_in;
if (!n)
return -ENOMEM;
@@ -359,10 +360,22 @@
if (i-- == 0)
goto extra;
}
+
+ if (ep->desc->bEndpointAddress & USB_DIR_IN)
+ usb_in = true;
+ else
+ usb_in = false;
+
while (i--) {
req = usb_ep_alloc_request(ep, GFP_ATOMIC);
if (!req)
return list_empty(list) ? -ENOMEM : 0;
+ /* update completion handler */
+ if (usb_in)
+ req->complete = tx_complete;
+ else
+ req->complete = rx_complete;
+
list_add(&req->list, list);
}
return 0;
@@ -479,7 +492,7 @@
static void tx_complete(struct usb_ep *ep, struct usb_request *req)
{
- struct sk_buff *skb = req->context;
+ struct sk_buff *skb;
struct eth_dev *dev;
struct net_device *net;
struct usb_request *new_req;
@@ -553,7 +566,6 @@
}
new_req->length = length;
- new_req->complete = tx_complete;
retval = usb_ep_queue(in, new_req, GFP_ATOMIC);
switch (retval) {
default:
@@ -585,6 +597,7 @@
spin_unlock(&dev->req_lock);
}
} else {
+ skb = req->context;
spin_unlock(&dev->req_lock);
dev_kfree_skb_any(skb);
}
@@ -613,7 +626,7 @@
list_for_each(act, &dev->tx_reqs) {
req = container_of(act, struct usb_request, list);
if (!req->buf)
- req->buf = kmalloc(dev->tx_req_bufsize,
+ req->buf = kzalloc(dev->tx_req_bufsize,
GFP_ATOMIC);
if (!req->buf)
goto free_buf;
@@ -626,6 +639,7 @@
list_for_each(act, &dev->tx_reqs) {
req = container_of(act, struct usb_request, list);
kfree(req->buf);
+ req->buf = NULL;
}
return -ENOMEM;
}
@@ -710,28 +724,37 @@
* or the hardware can't use skb buffers.
* or there's not enough space for extra headers we need
*/
+ spin_lock_irqsave(&dev->lock, flags);
if (dev->wrap) {
- unsigned long flags;
-
- spin_lock_irqsave(&dev->lock, flags);
if (dev->port_usb)
skb = dev->wrap(dev->port_usb, skb);
- spin_unlock_irqrestore(&dev->lock, flags);
- if (!skb)
+ if (!skb) {
+ spin_unlock_irqrestore(&dev->lock, flags);
goto drop;
+ }
}
- spin_lock_irqsave(&dev->req_lock, flags);
- dev->tx_skb_hold_count++;
- spin_unlock_irqrestore(&dev->req_lock, flags);
-
if (multi_pkt_xfer) {
+
+ pr_debug("req->length:%d header_len:%u\n"
+ "skb->len:%d skb->data_len:%d\n",
+ req->length, dev->header_len,
+ skb->len, skb->data_len);
+ /* Add RNDIS Header */
+ memcpy(req->buf + req->length, dev->port_usb->header,
+ dev->header_len);
+ /* Increment req length by header size */
+ req->length += dev->header_len;
+ spin_unlock_irqrestore(&dev->lock, flags);
+ /* Copy received IP data from SKB */
memcpy(req->buf + req->length, skb->data, skb->len);
- req->length = req->length + skb->len;
+ /* Increment req length by skb data length */
+ req->length += skb->len;
length = req->length;
dev_kfree_skb_any(skb);
spin_lock_irqsave(&dev->req_lock, flags);
+ dev->tx_skb_hold_count++;
if (dev->tx_skb_hold_count < dev->dl_max_pkts_per_xfer) {
if (dev->no_tx_req_used > TX_REQ_THRESHOLD) {
list_add(&req->list, &dev->tx_reqs);
@@ -741,19 +764,15 @@
}
dev->no_tx_req_used++;
- spin_unlock_irqrestore(&dev->req_lock, flags);
-
- spin_lock_irqsave(&dev->lock, flags);
dev->tx_skb_hold_count = 0;
- spin_unlock_irqrestore(&dev->lock, flags);
+ spin_unlock_irqrestore(&dev->req_lock, flags);
} else {
+ spin_unlock_irqrestore(&dev->lock, flags);
length = skb->len;
req->buf = skb->data;
req->context = skb;
}
- req->complete = tx_complete;
-
/* NCM requires no zlp if transfer is dwNtbInMaxSize */
if (dev->port_usb->is_fixed &&
length == dev->port_usb->fixed_in_len &&
@@ -806,7 +825,7 @@
spin_lock_irqsave(&dev->req_lock, flags);
if (list_empty(&dev->tx_reqs))
netif_start_queue(net);
- list_add(&req->list, &dev->tx_reqs);
+ list_add_tail(&req->list, &dev->tx_reqs);
spin_unlock_irqrestore(&dev->req_lock, flags);
}
success:
@@ -1085,6 +1104,14 @@
if (!dev)
return ERR_PTR(-EINVAL);
+ link->header = kzalloc(sizeof(struct rndis_packet_msg_type),
+ GFP_ATOMIC);
+ if (!link->header) {
+ pr_err("RNDIS header memory allocation failed.\n");
+ result = -ENOMEM;
+ goto fail;
+ }
+
link->in_ep->driver_data = dev;
result = usb_ep_enable(link->in_ep);
if (result != 0) {
@@ -1105,6 +1132,7 @@
result = alloc_requests(dev, link, qlen(dev->gadget));
if (result == 0) {
+
dev->zlp = link->is_zlp_ok;
DBG(dev, "qlen %d\n", qlen(dev->gadget));
@@ -1139,10 +1167,15 @@
fail1:
(void) usb_ep_disable(link->in_ep);
}
-fail0:
+
/* caller is responsible for cleanup on error */
- if (result < 0)
+ if (result < 0) {
+fail0:
+ kfree(link->header);
+fail:
return ERR_PTR(result);
+ }
+
return dev->net;
}
@@ -1184,11 +1217,16 @@
list_del(&req->list);
spin_unlock(&dev->req_lock);
- if (link->multi_pkt_xfer)
+ if (link->multi_pkt_xfer) {
kfree(req->buf);
+ req->buf = NULL;
+ }
usb_ep_free_request(link->in_ep, req);
spin_lock(&dev->req_lock);
}
+ /* Free rndis header buffer memory */
+ kfree(link->header);
+ link->header = NULL;
spin_unlock(&dev->req_lock);
link->in_ep->driver_data = NULL;
link->in_ep->desc = NULL;
diff --git a/drivers/usb/gadget/u_ether.h b/drivers/usb/gadget/u_ether.h
index 05984d8..2c5da77 100644
--- a/drivers/usb/gadget/u_ether.h
+++ b/drivers/usb/gadget/u_ether.h
@@ -66,6 +66,8 @@
/* called on network open/close */
void (*open)(struct gether *);
void (*close)(struct gether *);
+ struct rndis_packet_msg_type *header;
+
};
#define DEFAULT_FILTER (USB_CDC_PACKET_TYPE_BROADCAST \
diff --git a/drivers/usb/gadget/u_qdss.c b/drivers/usb/gadget/u_qdss.c
index e241e29..23d4d06 100644
--- a/drivers/usb/gadget/u_qdss.c
+++ b/drivers/usb/gadget/u_qdss.c
@@ -14,6 +14,7 @@
#include <linux/device.h>
#include <linux/usb/msm_hsusb.h>
#include <mach/usb_bam.h>
+#include "gadget_chips.h"
struct usb_qdss_bam_connect_info {
u32 usb_bam_pipe_idx;
@@ -88,8 +89,11 @@
&bam_info.usb_bam_pipe_idx, &bam_info.peer_pipe_idx,
NULL, bam_info.data_fifo);
- msm_data_fifo_config(data_ep, bam_info.data_fifo->phys_base,
- bam_info.data_fifo->size, bam_info.usb_bam_pipe_idx);
+ if (gadget_is_dwc3(gadget))
+ msm_data_fifo_config(data_ep,
+ bam_info.data_fifo->phys_base,
+ bam_info.data_fifo->size,
+ bam_info.usb_bam_pipe_idx);
} else {
kfree(bam_info.data_fifo);
res = usb_bam_disconnect_pipe(idx);
diff --git a/drivers/video/msm/mdss/Kconfig b/drivers/video/msm/mdss/Kconfig
index 7682a49..b49e08e 100644
--- a/drivers/video/msm/mdss/Kconfig
+++ b/drivers/video/msm/mdss/Kconfig
@@ -20,3 +20,11 @@
Support the HDMI to MHL conversion.
MHL (Mobile High-Definition Link) technology
uses USB connector to output HDMI content
+
+config FB_MSM_MDSS_DSI_CTRL_STATUS
+ tristate "DSI controller status check feature"
+ ---help---
+ Check DSI controller status periodically (default period is 5
+ seconds) by sending Bus-Turn-Around (BTA) command. If DSI controller
+ fails to acknowledge the BTA command, it sends PANEL_ALIVE=0 status
+ to HAL layer to reset the controller.
diff --git a/drivers/video/msm/mdss/Makefile b/drivers/video/msm/mdss/Makefile
index ba14d67..8f5fa26 100644
--- a/drivers/video/msm/mdss/Makefile
+++ b/drivers/video/msm/mdss/Makefile
@@ -41,3 +41,5 @@
obj-$(CONFIG_FB_MSM_QPIC_ILI_QVGA_PANEL) += qpic_panel_ili_qvga.o
obj-$(CONFIG_FB_MSM_MDSS) += mdss_fb.o
+
+obj-$(CONFIG_FB_MSM_MDSS_DSI_CTRL_STATUS) += mdss_dsi_status.o
diff --git a/drivers/video/msm/mdss/mdp3.c b/drivers/video/msm/mdss/mdp3.c
index fe8c528..d642093 100644
--- a/drivers/video/msm/mdss/mdp3.c
+++ b/drivers/video/msm/mdss/mdp3.c
@@ -1726,7 +1726,7 @@
rc = (status == 0x080000);
}
- mdp3_res->splash_mem_addr = MDP3_REG_READ(MDP3_REG_DMA_S_IBUF_ADDR);
+ mdp3_res->splash_mem_addr = MDP3_REG_READ(MDP3_REG_DMA_P_IBUF_ADDR);
mdp3_clk_update(MDP3_CLK_AHB, 0);
mdp3_clk_update(MDP3_CLK_CORE, 0);
diff --git a/drivers/video/msm/mdss/mdp3_ctrl.c b/drivers/video/msm/mdss/mdp3_ctrl.c
index e6ba9e9..994e3e0 100644
--- a/drivers/video/msm/mdss/mdp3_ctrl.c
+++ b/drivers/video/msm/mdss/mdp3_ctrl.c
@@ -1355,7 +1355,7 @@
int rc = -EINVAL;
struct mdp3_session_data *mdp3_session;
struct msmfb_metadata metadata;
- struct mdp_overlay req;
+ struct mdp_overlay *req = NULL;
struct msmfb_overlay_data ov_data;
int val;
@@ -1363,6 +1363,8 @@
if (!mdp3_session)
return -ENODEV;
+ req = &mdp3_session->req_overlay;
+
if (!mdp3_session->status && cmd != MSMFB_METADATA_GET) {
pr_err("mdp3_ctrl_ioctl_handler, display off!\n");
return -EPERM;
@@ -1402,23 +1404,23 @@
rc = copy_to_user(argp, &metadata, sizeof(metadata));
break;
case MSMFB_OVERLAY_GET:
- rc = copy_from_user(&req, argp, sizeof(req));
+ rc = copy_from_user(req, argp, sizeof(*req));
if (!rc) {
- rc = mdp3_overlay_get(mfd, &req);
+ rc = mdp3_overlay_get(mfd, req);
if (!IS_ERR_VALUE(rc))
- rc = copy_to_user(argp, &req, sizeof(req));
+ rc = copy_to_user(argp, req, sizeof(*req));
}
if (rc)
pr_err("OVERLAY_GET failed (%d)\n", rc);
break;
case MSMFB_OVERLAY_SET:
- rc = copy_from_user(&req, argp, sizeof(req));
+ rc = copy_from_user(req, argp, sizeof(*req));
if (!rc) {
- rc = mdp3_overlay_set(mfd, &req);
+ rc = mdp3_overlay_set(mfd, req);
if (!IS_ERR_VALUE(rc))
- rc = copy_to_user(argp, &req, sizeof(req));
+ rc = copy_to_user(argp, req, sizeof(*req));
}
if (rc)
pr_err("OVERLAY_SET failed (%d)\n", rc);
diff --git a/drivers/video/msm/mdss/mdp3_ctrl.h b/drivers/video/msm/mdss/mdp3_ctrl.h
index 7c4f6ac..66ed3d5 100644
--- a/drivers/video/msm/mdss/mdp3_ctrl.h
+++ b/drivers/video/msm/mdss/mdp3_ctrl.h
@@ -45,6 +45,7 @@
int vsync_period;
struct sysfs_dirent *vsync_event_sd;
struct mdp_overlay overlay;
+ struct mdp_overlay req_overlay;
struct mdp3_buffer_queue bufq_in;
struct mdp3_buffer_queue bufq_out;
int histo_status;
diff --git a/drivers/video/msm/mdss/mdss_dsi.c b/drivers/video/msm/mdss/mdss_dsi.c
index 927cfa9..bb1f8ae 100644
--- a/drivers/video/msm/mdss/mdss_dsi.c
+++ b/drivers/video/msm/mdss/mdss_dsi.c
@@ -1305,6 +1305,7 @@
}
ctrl_pdata->panel_data.event_handler = mdss_dsi_event_handler;
+ ctrl_pdata->check_status = mdss_dsi_bta_status_check;
if (ctrl_pdata->bklt_ctrl == BL_PWM)
mdss_dsi_panel_pwm_cfg(ctrl_pdata);
diff --git a/drivers/video/msm/mdss/mdss_dsi.h b/drivers/video/msm/mdss/mdss_dsi.h
index 13dad06..7202c62 100644
--- a/drivers/video/msm/mdss/mdss_dsi.h
+++ b/drivers/video/msm/mdss/mdss_dsi.h
@@ -118,6 +118,8 @@
#define DSI_INTR_ERROR_MASK BIT(25)
#define DSI_INTR_ERROR BIT(24)
+#define DSI_INTR_BTA_DONE_MASK BIT(21)
+#define DSI_INTR_BTA_DONE BIT(20)
#define DSI_INTR_VIDEO_DONE_MASK BIT(17)
#define DSI_INTR_VIDEO_DONE BIT(16)
#define DSI_INTR_CMD_MDP_DONE_MASK BIT(9)
@@ -133,6 +135,7 @@
#define DSI_VIDEO_TERM BIT(16)
#define DSI_MDP_TERM BIT(8)
+#define DSI_BTA_TERM BIT(1)
#define DSI_CMD_TERM BIT(0)
extern struct device dsi_dev;
@@ -315,6 +318,7 @@
int (*on) (struct mdss_panel_data *pdata);
int (*off) (struct mdss_panel_data *pdata);
int (*partial_update_fnc) (struct mdss_panel_data *pdata);
+ int (*check_status) (struct mdss_dsi_ctrl_pdata *pdata);
struct mdss_panel_data panel_data;
unsigned char *ctrl_base;
int reg_size;
@@ -360,6 +364,7 @@
struct completion dma_comp;
struct completion mdp_comp;
struct completion video_comp;
+ struct completion bta_comp;
spinlock_t irq_lock;
spinlock_t mdp_lock;
int mdp_busy;
@@ -428,6 +433,7 @@
struct dcs_cmd_req *cmdreq);
struct dcs_cmd_req *mdss_dsi_cmdlist_get(struct mdss_dsi_ctrl_pdata *ctrl);
void mdss_dsi_cmdlist_kickoff(int intf);
+int mdss_dsi_bta_status_check(struct mdss_dsi_ctrl_pdata *ctrl);
int mdss_dsi_panel_init(struct device_node *node,
struct mdss_dsi_ctrl_pdata *ctrl_pdata,
diff --git a/drivers/video/msm/mdss/mdss_dsi_host.c b/drivers/video/msm/mdss/mdss_dsi_host.c
index bb2818b..750fbf3 100644
--- a/drivers/video/msm/mdss/mdss_dsi_host.c
+++ b/drivers/video/msm/mdss/mdss_dsi_host.c
@@ -49,6 +49,8 @@
#define DSI_EVENT_Q_MAX 4
+#define DSI_BTA_EVENT_TIMEOUT (HZ / 10)
+
/* event */
struct dsi_event_q {
struct mdss_dsi_ctrl_pdata *ctrl;
@@ -98,6 +100,7 @@
init_completion(&ctrl->dma_comp);
init_completion(&ctrl->mdp_comp);
init_completion(&ctrl->video_comp);
+ init_completion(&ctrl->bta_comp);
spin_lock_init(&ctrl->irq_lock);
spin_lock_init(&ctrl->mdp_lock);
mutex_init(&ctrl->mutex);
@@ -1107,14 +1110,14 @@
if (mode == DSI_VIDEO_MODE) {
dsi_ctrl |= 0x03;
- intr_ctrl = DSI_INTR_CMD_DMA_DONE_MASK;
+ intr_ctrl = DSI_INTR_CMD_DMA_DONE_MASK | DSI_INTR_BTA_DONE_MASK;
} else { /* command mode */
dsi_ctrl |= 0x05;
if (pdata->panel_info.type == MIPI_VIDEO_PANEL)
dsi_ctrl |= 0x02;
intr_ctrl = DSI_INTR_CMD_DMA_DONE_MASK | DSI_INTR_ERROR_MASK |
- DSI_INTR_CMD_MDP_DONE_MASK;
+ DSI_INTR_CMD_MDP_DONE_MASK | DSI_INTR_BTA_DONE_MASK;
}
if (ctrl_pdata->shared_pdata.broadcast_enable)
@@ -1160,6 +1163,45 @@
pr_debug("%s: BTA done, status = %d\n", __func__, status);
}
+int mdss_dsi_bta_status_check(struct mdss_dsi_ctrl_pdata *ctrl_pdata)
+{
+ int ret = 0;
+ unsigned long flag;
+
+ if (ctrl_pdata == NULL) {
+ pr_err("%s: Invalid input data\n", __func__);
+
+ /*
+ * This should not return error otherwise
+ * BTA status thread will treat it as dead panel scenario
+ * and request for blank/unblank
+ */
+ return 0;
+ }
+
+ pr_debug("%s: Checking BTA status\n", __func__);
+
+ mdss_dsi_clk_ctrl(ctrl_pdata, 1);
+ spin_lock_irqsave(&ctrl_pdata->mdp_lock, flag);
+ INIT_COMPLETION(ctrl_pdata->bta_comp);
+ mdss_dsi_enable_irq(ctrl_pdata, DSI_BTA_TERM);
+ spin_unlock_irqrestore(&ctrl_pdata->mdp_lock, flag);
+ MIPI_OUTP(ctrl_pdata->ctrl_base + 0x098, 0x01); /* trigger */
+ wmb();
+
+ ret = wait_for_completion_killable_timeout(&ctrl_pdata->bta_comp,
+ DSI_BTA_EVENT_TIMEOUT);
+ if (ret <= 0) {
+ mdss_dsi_disable_irq(ctrl_pdata, DSI_BTA_TERM);
+ pr_err("%s: DSI BTA error: %i\n", __func__, ret);
+ }
+
+ mdss_dsi_clk_ctrl(ctrl_pdata, 0);
+ pr_debug("%s: BTA done with ret: %d\n", __func__, ret);
+
+ return ret;
+}
+
static char set_tear_on[2] = {0x35, 0x00};
static struct dsi_cmd_desc dsi_tear_on_cmd = {
{DTYPE_DCS_WRITE1, 1, 0, 0, 0, sizeof(set_tear_on)}, set_tear_on};
@@ -2078,5 +2120,12 @@
spin_unlock(&ctrl->mdp_lock);
}
+ if (isr & DSI_INTR_BTA_DONE) {
+ spin_lock(&ctrl->mdp_lock);
+ mdss_dsi_disable_irq_nosync(ctrl, DSI_BTA_TERM);
+ complete(&ctrl->bta_comp);
+ spin_unlock(&ctrl->mdp_lock);
+ }
+
return IRQ_HANDLED;
}
diff --git a/drivers/video/msm/mdss/mdss_dsi_panel.c b/drivers/video/msm/mdss/mdss_dsi_panel.c
index 9932186..890066e 100644
--- a/drivers/video/msm/mdss/mdss_dsi_panel.c
+++ b/drivers/video/msm/mdss/mdss_dsi_panel.c
@@ -293,6 +293,15 @@
ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
panel_data);
+ /*
+ * Some backlight controllers specify a minimum duty cycle
+ * for the backlight brightness. If the brightness is less
+ * than it, the controller can malfunction.
+ */
+
+ if ((bl_level < pdata->panel_info.bl_min) && (bl_level != 0))
+ bl_level = pdata->panel_info.bl_min;
+
switch (ctrl_pdata->bklt_ctrl) {
case BL_WLED:
led_trigger_event(bl_led_trigger, bl_level);
diff --git a/drivers/video/msm/mdss/mdss_dsi_status.c b/drivers/video/msm/mdss/mdss_dsi_status.c
new file mode 100644
index 0000000..f0c4f4c
--- /dev/null
+++ b/drivers/video/msm/mdss/mdss_dsi_status.c
@@ -0,0 +1,208 @@
+/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/fb.h>
+#include <linux/notifier.h>
+#include <linux/workqueue.h>
+#include <linux/delay.h>
+#include <linux/debugfs.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+#include <linux/iopoll.h>
+#include <linux/kobject.h>
+#include <linux/string.h>
+#include <linux/sysfs.h>
+
+#include "mdss_fb.h"
+#include "mdss_dsi.h"
+#include "mdss_panel.h"
+#include "mdss_mdp.h"
+
+#define STATUS_CHECK_INTERVAL 5000
+
+struct dsi_status_data {
+ struct notifier_block fb_notifier;
+ struct delayed_work check_status;
+ struct msm_fb_data_type *mfd;
+ uint32_t check_interval;
+};
+struct dsi_status_data *pstatus_data;
+static uint32_t interval = STATUS_CHECK_INTERVAL;
+
+/*
+ * check_dsi_ctrl_status() - Check DSI controller status periodically.
+ * @work : dsi controller status data
+ *
+ * This function calls check_status API on DSI controller to send the BTA
+ * command. If DSI controller fails to acknowledge the BTA command, it sends
+ * the PANEL_ALIVE=0 status to HAL layer.
+ */
+static void check_dsi_ctrl_status(struct work_struct *work)
+{
+ struct dsi_status_data *pdsi_status = NULL;
+ struct mdss_panel_data *pdata = NULL;
+ struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL;
+ struct mdss_overlay_private *mdp5_data = NULL;
+ struct mdss_mdp_ctl *ctl = NULL;
+ int ret = 0;
+
+ pdsi_status = container_of(to_delayed_work(work),
+ struct dsi_status_data, check_status);
+ if (!pdsi_status) {
+ pr_err("%s: DSI status data not available\n", __func__);
+ return;
+ }
+
+ pdata = dev_get_platdata(&pdsi_status->mfd->pdev->dev);
+ if (!pdata) {
+ pr_err("%s: Panel data not available\n", __func__);
+ return;
+ }
+
+ ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata,
+ panel_data);
+ if (!ctrl_pdata || !ctrl_pdata->check_status) {
+ pr_err("%s: DSI ctrl or status_check callback not available\n",
+ __func__);
+ return;
+ }
+
+ mdp5_data = mfd_to_mdp5_data(pdsi_status->mfd);
+ ctl = mfd_to_ctl(pdsi_status->mfd);
+
+ if (ctl->shared_lock)
+ mutex_lock(ctl->shared_lock);
+ mutex_lock(&mdp5_data->ov_lock);
+
+ /*
+ * For the command mode panels, we return pan display
+ * IOCTL on vsync interrupt. So, after vsync interrupt comes
+ * and when DMA_P is in progress, if the panel stops responding
+ * and if we trigger BTA before DMA_P finishes, then the DSI
+ * FIFO will not be cleared since the DSI data bus control
+ * doesn't come back to the host after BTA. This may cause the
+ * display reset not to be proper. Hence, wait for DMA_P done
+ * for command mode panels before triggering BTA.
+ */
+ if (ctl->wait_pingpong)
+ ctl->wait_pingpong(ctl, NULL);
+
+ pr_debug("%s: DSI ctrl wait for ping pong done\n", __func__);
+
+ mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false);
+ ret = ctrl_pdata->check_status(ctrl_pdata);
+ mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
+
+ mutex_unlock(&mdp5_data->ov_lock);
+ if (ctl->shared_lock)
+ mutex_unlock(ctl->shared_lock);
+
+ if ((pdsi_status->mfd->panel_power_on)) {
+ if (ret > 0) {
+ schedule_delayed_work(&pdsi_status->check_status,
+ msecs_to_jiffies(pdsi_status->check_interval));
+ } else {
+ char *envp[2] = {"PANEL_ALIVE=0", NULL};
+ pdata->panel_info.panel_dead = true;
+ ret = kobject_uevent_env(
+ &pdsi_status->mfd->fbi->dev->kobj,
+ KOBJ_CHANGE, envp);
+ pr_err("%s: Panel has gone bad, sending uevent - %s\n",
+ __func__, envp[0]);
+ }
+ }
+}
+
+/*
+ * fb_event_callback() - Call back function for the fb_register_client()
+ * notifying events
+ * @self : notifier block
+ * @event : The event that was triggered
+ * @data : Of type struct fb_event
+ *
+ * This function listens for FB_BLANK_UNBLANK and FB_BLANK_POWERDOWN events
+ * from frame buffer. DSI status check work is either scheduled again after
+ * PANEL_STATUS_CHECK_INTERVAL or cancelled based on the event.
+ */
+static int fb_event_callback(struct notifier_block *self,
+ unsigned long event, void *data)
+{
+ struct fb_event *evdata = data;
+ struct dsi_status_data *pdata = container_of(self,
+ struct dsi_status_data, fb_notifier);
+ pdata->mfd = evdata->info->par;
+
+ if (event == FB_EVENT_BLANK && evdata) {
+ int *blank = evdata->data;
+ switch (*blank) {
+ case FB_BLANK_UNBLANK:
+ schedule_delayed_work(&pdata->check_status,
+ msecs_to_jiffies(pdata->check_interval));
+ break;
+ case FB_BLANK_POWERDOWN:
+ cancel_delayed_work(&pdata->check_status);
+ break;
+ }
+ }
+ return 0;
+}
+
+int __init mdss_dsi_status_init(void)
+{
+ int rc = 0;
+
+ pstatus_data = kzalloc(sizeof(struct dsi_status_data), GFP_KERNEL);
+ if (!pstatus_data) {
+ pr_err("%s: can't allocate memory\n", __func__);
+ return -ENOMEM;
+ }
+
+ pstatus_data->fb_notifier.notifier_call = fb_event_callback;
+
+ rc = fb_register_client(&pstatus_data->fb_notifier);
+ if (rc < 0) {
+ pr_err("%s: fb_register_client failed, returned with rc=%d\n",
+ __func__, rc);
+ kfree(pstatus_data);
+ return -EPERM;
+ }
+
+ pstatus_data->check_interval = interval;
+ pr_info("%s: DSI status check interval:%d\n", __func__, interval);
+
+ INIT_DELAYED_WORK(&pstatus_data->check_status, check_dsi_ctrl_status);
+
+ pr_debug("%s: DSI ctrl status work queue initialized\n", __func__);
+
+ return rc;
+}
+
+void __exit mdss_dsi_status_exit(void)
+{
+ fb_unregister_client(&pstatus_data->fb_notifier);
+ cancel_delayed_work_sync(&pstatus_data->check_status);
+ kfree(pstatus_data);
+ pr_debug("%s: DSI ctrl status work queue removed\n", __func__);
+}
+
+module_param(interval, uint, 0);
+MODULE_PARM_DESC(interval,
+ "Duration in milliseconds to send BTA command for checking"
+ "DSI status periodically");
+
+module_init(mdss_dsi_status_init);
+module_exit(mdss_dsi_status_exit);
+
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/video/msm/mdss/mdss_fb.c b/drivers/video/msm/mdss/mdss_fb.c
index 047c0f0..211b540 100644
--- a/drivers/video/msm/mdss/mdss_fb.c
+++ b/drivers/video/msm/mdss/mdss_fb.c
@@ -705,8 +705,10 @@
case FB_BLANK_UNBLANK:
if (!mfd->panel_power_on && mfd->mdp.on_fnc) {
ret = mfd->mdp.on_fnc(mfd);
- if (ret == 0)
+ if (ret == 0) {
mfd->panel_power_on = true;
+ mfd->panel_info->panel_dead = false;
+ }
mutex_lock(&mfd->update.lock);
mfd->update.type = NOTIFY_TYPE_UPDATE;
mutex_unlock(&mfd->update.lock);
diff --git a/drivers/video/msm/mdss/mdss_hdmi_hdcp.c b/drivers/video/msm/mdss/mdss_hdmi_hdcp.c
index 80b27ed..ca21b51 100644
--- a/drivers/video/msm/mdss/mdss_hdmi_hdcp.c
+++ b/drivers/video/msm/mdss/mdss_hdmi_hdcp.c
@@ -289,6 +289,10 @@
}
DEV_DBG("%s: %s: BCAPS=%02x\n", __func__, HDCP_STATE_NAME, bcaps);
+ /* receiver (0), repeater (1) */
+ hdcp_ctrl->current_tp.ds_type =
+ (bcaps & BIT(6)) >> 6 ? DS_REPEATER : DS_RECEIVER;
+
/*
* HDCP setup prior to enabling HDCP_CTRL.
* Setup seed values for random number An.
@@ -644,40 +648,12 @@
memset(ksv_fifo, 0,
sizeof(hdcp_ctrl->current_tp.ksv_list));
- /* Read BCAPS at offset 0x40 */
- memset(&ddc_data, 0, sizeof(ddc_data));
- ddc_data.dev_addr = 0x74;
- ddc_data.offset = 0x40;
- ddc_data.data_buf = &bcaps;
- ddc_data.data_len = 1;
- ddc_data.request_len = 1;
- ddc_data.retry = 5;
- ddc_data.what = "Bcaps";
- ddc_data.no_align = false;
- rc = hdmi_ddc_read(hdcp_ctrl->init_data.ddc_ctrl, &ddc_data);
- if (rc) {
- DEV_ERR("%s: %s: BCAPS read failed\n", __func__,
- HDCP_STATE_NAME);
- goto error;
- }
- DEV_DBG("%s: %s: BCAPS=%02x (%s)\n", __func__, HDCP_STATE_NAME, bcaps,
- (bcaps & BIT(6)) ? "repeater" : "no repeater");
-
- /* receiver (0), repeater (1) */
- hdcp_ctrl->current_tp.ds_type =
- (bcaps & BIT(6)) >> 6 ? DS_REPEATER : DS_RECEIVER;
-
- /* if REPEATER (Bit 6), perform Part2 Authentication */
- if (!(bcaps & BIT(6))) {
- DEV_INFO("%s: %s: auth part II skipped, no repeater\n",
- __func__, HDCP_STATE_NAME);
- return 0;
- }
-
- /* Wait until READY bit is set in BCAPS */
+ /*
+ * Wait until READY bit is set in BCAPS, as per HDCP specifications
+ * maximum permitted time to check for READY bit is five seconds.
+ */
timeout_count = 50;
- while (!(bcaps & BIT(5)) && timeout_count) {
- msleep(100);
+ do {
timeout_count--;
/* Read BCAPS at offset 0x40 */
memset(&ddc_data, 0, sizeof(ddc_data));
@@ -695,7 +671,8 @@
HDCP_STATE_NAME);
goto error;
}
- }
+ msleep(100);
+ } while (!(bcaps & BIT(5)) && timeout_count);
/* Read BSTATUS at offset 0x41 */
memset(&ddc_data, 0, sizeof(ddc_data));
@@ -976,11 +953,15 @@
goto error;
}
- rc = hdmi_hdcp_authentication_part2(hdcp_ctrl);
- if (rc) {
- DEV_DBG("%s: %s: HDCP Auth Part II failed\n", __func__,
- HDCP_STATE_NAME);
- goto error;
+ if (hdcp_ctrl->current_tp.ds_type == DS_REPEATER) {
+ rc = hdmi_hdcp_authentication_part2(hdcp_ctrl);
+ if (rc) {
+ DEV_DBG("%s: %s: HDCP Auth Part II failed\n", __func__,
+ HDCP_STATE_NAME);
+ goto error;
+ }
+ } else {
+ DEV_INFO("%s: Downstream device is not a repeater\n", __func__);
}
/* Disabling software DDC before going into part3 to make sure
* there is no Arbitration between software and hardware for DDC */
diff --git a/drivers/video/msm/mdss/mdss_hdmi_tx.c b/drivers/video/msm/mdss/mdss_hdmi_tx.c
index e46e361..abb72ad 100644
--- a/drivers/video/msm/mdss/mdss_hdmi_tx.c
+++ b/drivers/video/msm/mdss/mdss_hdmi_tx.c
@@ -2456,6 +2456,10 @@
mutex_unlock(&hdmi_ctrl->mutex);
DEV_INFO("%s: HDMI Core: OFF\n", __func__);
+
+ if (hdmi_ctrl->hdmi_tx_hpd_done)
+ hdmi_ctrl->hdmi_tx_hpd_done(
+ hdmi_ctrl->downstream_data);
} /* hdmi_tx_power_off_work */
static int hdmi_tx_power_off(struct mdss_panel_data *panel_data)
@@ -2558,6 +2562,9 @@
hdmi_tx_hpd_polarity_setup(hdmi_ctrl, HPD_DISCONNECT_POLARITY);
+ if (hdmi_ctrl->hdmi_tx_hpd_done)
+ hdmi_ctrl->hdmi_tx_hpd_done(hdmi_ctrl->downstream_data);
+
return 0;
} /* hdmi_tx_power_on */
diff --git a/drivers/video/msm/mdss/mdss_hdmi_tx.h b/drivers/video/msm/mdss/mdss_hdmi_tx.h
index fd95582..c4d0326 100644
--- a/drivers/video/msm/mdss/mdss_hdmi_tx.h
+++ b/drivers/video/msm/mdss/mdss_hdmi_tx.h
@@ -84,6 +84,9 @@
struct hdmi_tx_ddc_ctrl ddc_ctrl;
+ void (*hdmi_tx_hpd_done) (void *data);
+ void *downstream_data;
+
void *feature_data[HDMI_TX_FEAT_MAX];
};
diff --git a/drivers/video/msm/mdss/mdss_mdp_ctl.c b/drivers/video/msm/mdss/mdss_mdp_ctl.c
index 4f9045e..aa7c4dd 100644
--- a/drivers/video/msm/mdss/mdss_mdp_ctl.c
+++ b/drivers/video/msm/mdss/mdss_mdp_ctl.c
@@ -1560,9 +1560,17 @@
struct mdss_mdp_mixer *mdss_mdp_mixer_get(struct mdss_mdp_ctl *ctl, int mux)
{
struct mdss_mdp_mixer *mixer = NULL;
- struct mdss_overlay_private *mdp5_data = mfd_to_mdp5_data(ctl->mfd);
- if (!ctl)
+ struct mdss_overlay_private *mdp5_data = NULL;
+ if (!ctl || !ctl->mfd) {
+ pr_err("ctl not initialized\n");
return NULL;
+ }
+
+ mdp5_data = mfd_to_mdp5_data(ctl->mfd);
+ if (!mdp5_data) {
+ pr_err("ctl not initialized\n");
+ return NULL;
+ }
switch (mux) {
case MDSS_MDP_MIXER_MUX_DEFAULT:
diff --git a/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c b/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c
index 6056f21..d3e18ac 100644
--- a/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c
+++ b/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c
@@ -532,6 +532,7 @@
int mdss_mdp_cmd_stop(struct mdss_mdp_ctl *ctl)
{
struct mdss_mdp_cmd_ctx *ctx;
+ struct mdss_panel_info *pinfo;
unsigned long flags;
struct mdss_mdp_vsync_handler *tmp, *handle;
int need_wait = 0;
@@ -555,9 +556,23 @@
if (need_wait)
if (wait_for_completion_timeout(&ctx->stop_comp, STOP_TIMEOUT)
- <= 0)
+ <= 0) {
WARN(1, "stop cmd time out\n");
+ if (IS_ERR_OR_NULL(ctl->panel_data)) {
+ pr_err("no panel data\n");
+ } else {
+ pinfo = &ctl->panel_data->panel_info;
+
+ if (pinfo->panel_dead) {
+ mdss_mdp_irq_disable
+ (MDSS_MDP_IRQ_PING_PONG_RD_PTR,
+ ctx->pp_num);
+ ctx->rdptr_enabled = 0;
+ }
+ }
+ }
+
if (cancel_work_sync(&ctx->clk_work))
pr_debug("no pending clk work\n");
diff --git a/drivers/video/msm/mdss/mdss_mdp_intf_video.c b/drivers/video/msm/mdss/mdss_mdp_intf_video.c
index 8f7905a..bd1c3eb 100644
--- a/drivers/video/msm/mdss/mdss_mdp_intf_video.c
+++ b/drivers/video/msm/mdss/mdss_mdp_intf_video.c
@@ -438,10 +438,9 @@
} else {
rc = 0;
}
-
- mdss_mdp_ctl_notify(ctl,
- rc ? MDP_NOTIFY_FRAME_TIMEOUT : MDP_NOTIFY_FRAME_DONE);
}
+ mdss_mdp_ctl_notify(ctl,
+ rc ? MDP_NOTIFY_FRAME_TIMEOUT : MDP_NOTIFY_FRAME_DONE);
if (ctx->wait_pending) {
ctx->wait_pending = 0;
diff --git a/drivers/video/msm/mdss/mdss_mdp_overlay.c b/drivers/video/msm/mdss/mdss_mdp_overlay.c
index c565d98..f096f16 100644
--- a/drivers/video/msm/mdss/mdss_mdp_overlay.c
+++ b/drivers/video/msm/mdss/mdss_mdp_overlay.c
@@ -1475,15 +1475,26 @@
static void mdss_mdp_overlay_handle_vsync(struct mdss_mdp_ctl *ctl,
ktime_t t)
{
- struct msm_fb_data_type *mfd = ctl->mfd;
- struct mdss_overlay_private *mdp5_data;
+ struct msm_fb_data_type *mfd = NULL;
+ struct mdss_overlay_private *mdp5_data = NULL;
+ if (!ctl) {
+ pr_err("ctl is NULL\n");
+ return;
+ }
+
+ mfd = ctl->mfd;
if (!mfd || !mfd->mdp.private1) {
pr_warn("Invalid handle for vsync\n");
return;
}
mdp5_data = mfd_to_mdp5_data(mfd);
+ if (!mdp5_data) {
+ pr_err("mdp5_data is NULL\n");
+ return;
+ }
+
pr_debug("vsync on fb%d play_cnt=%d\n", mfd->index, ctl->play_cnt);
mdp5_data->vsync_time = t;
diff --git a/drivers/video/msm/mdss/mdss_mdp_pipe.c b/drivers/video/msm/mdss/mdss_mdp_pipe.c
index 779f74c..72c8759 100644
--- a/drivers/video/msm/mdss/mdss_mdp_pipe.c
+++ b/drivers/video/msm/mdss/mdss_mdp_pipe.c
@@ -728,7 +728,8 @@
dst = pipe->dst;
src = pipe->src;
- mdss_mdp_crop_rect(&src, &dst, &sci);
+ if (pipe->mixer->type == MDSS_MDP_MIXER_TYPE_INTF)
+ mdss_mdp_crop_rect(&src, &dst, &sci);
src_size = (src.h << 16) | src.w;
src_xy = (src.y << 16) | src.x;
diff --git a/drivers/video/msm/mdss/mdss_panel.h b/drivers/video/msm/mdss/mdss_panel.h
index 75fc095..b859598 100644
--- a/drivers/video/msm/mdss/mdss_panel.h
+++ b/drivers/video/msm/mdss/mdss_panel.h
@@ -299,6 +299,8 @@
struct ion_handle *splash_ihdl;
u32 panel_power_on;
+ uint32_t panel_dead;
+
struct lcd_panel_info lcdc;
struct fbc_panel_info fbc;
struct mipi_panel_info mipi;
diff --git a/include/linux/diagchar.h b/include/linux/diagchar.h
index 0739ece..d525e84 100644
--- a/include/linux/diagchar.h
+++ b/include/linux/diagchar.h
@@ -726,25 +726,27 @@
};
/* LOG CODES */
+static const uint32_t log_code_last_tbl[] = {
+ 0x0, /* EQUIP ID 0 */
+ 0x182F, /* EQUIP ID 1 */
+ 0x0, /* EQUIP ID 2 */
+ 0x0, /* EQUIP ID 3 */
+ 0x4910, /* EQUIP ID 4 */
+ 0x5420, /* EQUIP ID 5 */
+ 0x0, /* EQUIP ID 6 */
+ 0x74FF, /* EQUIP ID 7 */
+ 0x0, /* EQUIP ID 8 */
+ 0x0, /* EQUIP ID 9 */
+ 0xA38A, /* EQUIP ID 10 */
+ 0xB201, /* EQUIP ID 11 */
+ 0x0, /* EQUIP ID 12 */
+ 0x0, /* EQUIP ID 13 */
+ 0x0, /* EQUIP ID 14 */
+ 0x0, /* EQUIP ID 15 */
+};
-#define LOG_0 0x0
-#define LOG_1 0x1808
-#define LOG_2 0x0
-#define LOG_3 0x0
-#define LOG_4 0x4910
-#define LOG_5 0x5420
-#define LOG_6 0x0
-#define LOG_7 0x74FF
-#define LOG_8 0x0
-#define LOG_9 0x0
-#define LOG_10 0xA38A
-#define LOG_11 0xB201
-#define LOG_12 0x0
-#define LOG_13 0x0
-#define LOG_14 0x0
-#define LOG_15 0x0
-
-#define LOG_GET_ITEM_NUM(xx_code) (xx_code & 0x0FFF)
-#define LOG_GET_EQUIP_ID(xx_code) ((xx_code & 0xF000) >> 12)
+#define LOG_GET_ITEM_NUM(xx_code) (xx_code & 0x0FFF)
+#define LOG_GET_EQUIP_ID(xx_code) ((xx_code & 0xF000) >> 12)
+#define LOG_ITEMS_TO_SIZE(num_items) ((num_items+7)/8)
#endif
diff --git a/include/linux/mm_inline.h b/include/linux/mm_inline.h
index 227fd3e..9a584c0 100644
--- a/include/linux/mm_inline.h
+++ b/include/linux/mm_inline.h
@@ -2,6 +2,7 @@
#define LINUX_MM_INLINE_H
#include <linux/huge_mm.h>
+#include <linux/swap.h>
/**
* page_is_file_cache - should the page be on a file LRU or anon LRU?
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index 7539e03..381fff5 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -375,7 +375,6 @@
* free areas of different sizes
*/
spinlock_t lock;
- int all_unreclaimable; /* All pages pinned */
#if defined CONFIG_COMPACTION || defined CONFIG_CMA
/* Set to true when the PG_migrate_skip bits should be cleared */
bool compact_blockskip_flush;
diff --git a/include/linux/swap.h b/include/linux/swap.h
index 036b107..c1fcf34 100644
--- a/include/linux/swap.h
+++ b/include/linux/swap.h
@@ -197,6 +197,18 @@
struct block_device *bdev; /* swap device or bdev of swap file */
struct file *swap_file; /* seldom referenced */
unsigned int old_block_size; /* seldom referenced */
+ spinlock_t lock; /*
+ * protect map scan related fields like
+ * swap_map, lowest_bit, highest_bit,
+ * inuse_pages, cluster_next,
+ * cluster_nr, lowest_alloc and
+ * highest_alloc. other fields are only
+ * changed at swapon/swapoff, so are
+ * protected by swap_lock. changing
+ * flags need hold this lock and
+ * swap_lock. If both locks need hold,
+ * hold swap_lock first.
+ */
};
struct swap_list_t {
@@ -204,9 +216,6 @@
int next; /* swapfile to be used next */
};
-/* Swap 50% full? Release swapcache more aggressively.. */
-#define vm_swap_full() (nr_swap_pages*2 < total_swap_pages)
-
/* linux/mm/page_alloc.c */
extern unsigned long totalram_pages;
extern unsigned long totalreserve_pages;
@@ -335,8 +344,20 @@
struct vm_area_struct *vma, unsigned long addr);
/* linux/mm/swapfile.c */
-extern long nr_swap_pages;
+extern atomic_long_t nr_swap_pages;
extern long total_swap_pages;
+
+/* Swap 50% full? Release swapcache more aggressively.. */
+static inline bool vm_swap_full(void)
+{
+ return atomic_long_read(&nr_swap_pages) * 2 < total_swap_pages;
+}
+
+static inline long get_nr_swap_pages(void)
+{
+ return atomic_long_read(&nr_swap_pages);
+}
+
extern void si_swapinfo(struct sysinfo *);
extern swp_entry_t get_swap_page(void);
extern swp_entry_t get_swap_page_of_type(int);
@@ -370,9 +391,10 @@
#else /* CONFIG_SWAP */
-#define nr_swap_pages 0L
+#define get_nr_swap_pages() 0L
#define total_swap_pages 0L
#define total_swapcache_pages 0UL
+#define vm_swap_full() 0
#define si_swapinfo(val) \
do { (val)->freeswap = (val)->totalswap = 0; } while (0)
diff --git a/include/linux/vmstat.h b/include/linux/vmstat.h
index 1d10474..2d59889 100644
--- a/include/linux/vmstat.h
+++ b/include/linux/vmstat.h
@@ -140,7 +140,6 @@
}
extern unsigned long global_reclaimable_pages(void);
-extern unsigned long zone_reclaimable_pages(struct zone *zone);
#ifdef CONFIG_NUMA
/*
diff --git a/mm/internal.h b/mm/internal.h
index 3439ef4..f5369cc 100644
--- a/mm/internal.h
+++ b/mm/internal.h
@@ -90,6 +90,8 @@
*/
extern int isolate_lru_page(struct page *page);
extern void putback_lru_page(struct page *page);
+extern unsigned long zone_reclaimable_pages(struct zone *zone);
+extern bool zone_reclaimable(struct zone *zone);
/*
* in mm/page_alloc.c
diff --git a/mm/mmap.c b/mm/mmap.c
index 848ef52..9932edb 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -133,7 +133,7 @@
*/
free -= global_page_state(NR_SHMEM);
- free += nr_swap_pages;
+ free += get_nr_swap_pages();
/*
* Any slabs which are created with the
diff --git a/mm/nommu.c b/mm/nommu.c
index bb8f4f0..6bb7042 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -1928,7 +1928,7 @@
*/
free -= global_page_state(NR_SHMEM);
- free += nr_swap_pages;
+ free += get_nr_swap_pages();
/*
* Any slabs which are created with the
diff --git a/mm/page-writeback.c b/mm/page-writeback.c
index 26adea8..a5e8dc2 100644
--- a/mm/page-writeback.c
+++ b/mm/page-writeback.c
@@ -34,8 +34,11 @@
#include <linux/syscalls.h>
#include <linux/buffer_head.h> /* __set_page_dirty_buffers */
#include <linux/pagevec.h>
+#include <linux/mm_inline.h>
#include <trace/events/writeback.h>
+#include "internal.h"
+
/*
* Sleep at most 200ms at a time in balance_dirty_pages().
*/
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 46ccd2f..a1e4f77 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -57,6 +57,7 @@
#include <linux/ftrace_event.h>
#include <linux/memcontrol.h>
#include <linux/prefetch.h>
+#include <linux/mm_inline.h>
#include <linux/migrate.h>
#include <linux/page-debug-flags.h>
@@ -647,7 +648,6 @@
int mt = 0;
spin_lock(&zone->lock);
- zone->all_unreclaimable = 0;
zone->pages_scanned = 0;
while (to_free) {
@@ -693,7 +693,6 @@
int migratetype)
{
spin_lock(&zone->lock);
- zone->all_unreclaimable = 0;
zone->pages_scanned = 0;
__free_one_page(page, zone, order, migratetype);
@@ -2997,7 +2996,7 @@
K(zone_page_state(zone, NR_FREE_CMA_PAGES)),
K(zone_page_state(zone, NR_WRITEBACK_TEMP)),
zone->pages_scanned,
- (zone->all_unreclaimable ? "yes" : "no")
+ (!zone_reclaimable(zone) ? "yes" : "no")
);
printk("lowmem_reserve[]:");
for (i = 0; i < MAX_NR_ZONES; i++)
diff --git a/mm/swap_state.c b/mm/swap_state.c
index 4c5ff7f..eb6a79c 100644
--- a/mm/swap_state.c
+++ b/mm/swap_state.c
@@ -58,7 +58,8 @@
printk("Swap cache stats: add %lu, delete %lu, find %lu/%lu\n",
swap_cache_info.add_total, swap_cache_info.del_total,
swap_cache_info.find_success, swap_cache_info.find_total);
- printk("Free swap = %ldkB\n", nr_swap_pages << (PAGE_SHIFT - 10));
+ printk("Free swap = %ldkB\n",
+ get_nr_swap_pages() << (PAGE_SHIFT - 10));
printk("Total swap = %lukB\n", total_swap_pages << (PAGE_SHIFT - 10));
}
diff --git a/mm/swapfile.c b/mm/swapfile.c
index a6c07fd..9ae4c8d 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -45,9 +45,11 @@
static DEFINE_SPINLOCK(swap_lock);
static unsigned int nr_swapfiles;
-long nr_swap_pages;
+atomic_long_t nr_swap_pages;
+/* protected with swap_lock. reading in vm_swap_full() doesn't need lock */
long total_swap_pages;
static int least_priority;
+static atomic_t highest_priority_index = ATOMIC_INIT(-1);
static const char Bad_file[] = "Bad swap file entry ";
static const char Unused_file[] = "Unused swap file entry ";
@@ -221,7 +223,7 @@
si->lowest_alloc = si->max;
si->highest_alloc = 0;
}
- spin_unlock(&swap_lock);
+ spin_unlock(&si->lock);
/*
* If seek is expensive, start searching for new cluster from
@@ -240,7 +242,7 @@
if (si->swap_map[offset])
last_in_cluster = offset + SWAPFILE_CLUSTER;
else if (offset == last_in_cluster) {
- spin_lock(&swap_lock);
+ spin_lock(&si->lock);
offset -= SWAPFILE_CLUSTER - 1;
si->cluster_next = offset;
si->cluster_nr = SWAPFILE_CLUSTER - 1;
@@ -261,7 +263,7 @@
if (si->swap_map[offset])
last_in_cluster = offset + SWAPFILE_CLUSTER;
else if (offset == last_in_cluster) {
- spin_lock(&swap_lock);
+ spin_lock(&si->lock);
offset -= SWAPFILE_CLUSTER - 1;
si->cluster_next = offset;
si->cluster_nr = SWAPFILE_CLUSTER - 1;
@@ -275,7 +277,7 @@
}
offset = scan_base;
- spin_lock(&swap_lock);
+ spin_lock(&si->lock);
si->cluster_nr = SWAPFILE_CLUSTER - 1;
si->lowest_alloc = 0;
}
@@ -291,9 +293,9 @@
/* reuse swap entry of cache-only swap if not busy. */
if (vm_swap_full() && si->swap_map[offset] == SWAP_HAS_CACHE) {
int swap_was_freed;
- spin_unlock(&swap_lock);
+ spin_unlock(&si->lock);
swap_was_freed = __try_to_reclaim_swap(si, offset);
- spin_lock(&swap_lock);
+ spin_lock(&si->lock);
/* entry was freed successfully, try to use this again */
if (swap_was_freed)
goto checks;
@@ -333,13 +335,13 @@
si->lowest_alloc <= last_in_cluster)
last_in_cluster = si->lowest_alloc - 1;
si->flags |= SWP_DISCARDING;
- spin_unlock(&swap_lock);
+ spin_unlock(&si->lock);
if (offset < last_in_cluster)
discard_swap_cluster(si, offset,
last_in_cluster - offset + 1);
- spin_lock(&swap_lock);
+ spin_lock(&si->lock);
si->lowest_alloc = 0;
si->flags &= ~SWP_DISCARDING;
@@ -353,10 +355,10 @@
* could defer that delay until swap_writepage,
* but it's easier to keep this self-contained.
*/
- spin_unlock(&swap_lock);
+ spin_unlock(&si->lock);
wait_on_bit(&si->flags, ilog2(SWP_DISCARDING),
wait_for_discard, TASK_UNINTERRUPTIBLE);
- spin_lock(&swap_lock);
+ spin_lock(&si->lock);
} else {
/*
* Note pages allocated by racing tasks while
@@ -372,14 +374,14 @@
return offset;
scan:
- spin_unlock(&swap_lock);
+ spin_unlock(&si->lock);
while (++offset <= si->highest_bit) {
if (!si->swap_map[offset]) {
- spin_lock(&swap_lock);
+ spin_lock(&si->lock);
goto checks;
}
if (vm_swap_full() && si->swap_map[offset] == SWAP_HAS_CACHE) {
- spin_lock(&swap_lock);
+ spin_lock(&si->lock);
goto checks;
}
if (unlikely(--latency_ration < 0)) {
@@ -390,11 +392,11 @@
offset = si->lowest_bit;
while (++offset < scan_base) {
if (!si->swap_map[offset]) {
- spin_lock(&swap_lock);
+ spin_lock(&si->lock);
goto checks;
}
if (vm_swap_full() && si->swap_map[offset] == SWAP_HAS_CACHE) {
- spin_lock(&swap_lock);
+ spin_lock(&si->lock);
goto checks;
}
if (unlikely(--latency_ration < 0)) {
@@ -402,7 +404,7 @@
latency_ration = LATENCY_LIMIT;
}
}
- spin_lock(&swap_lock);
+ spin_lock(&si->lock);
no_page:
si->flags -= SWP_SCANNING;
@@ -415,13 +417,34 @@
pgoff_t offset;
int type, next;
int wrapped = 0;
+ int hp_index;
spin_lock(&swap_lock);
- if (nr_swap_pages <= 0)
+ if (atomic_long_read(&nr_swap_pages) <= 0)
goto noswap;
- nr_swap_pages--;
+ atomic_long_dec(&nr_swap_pages);
for (type = swap_list.next; type >= 0 && wrapped < 2; type = next) {
+ hp_index = atomic_xchg(&highest_priority_index, -1);
+ /*
+ * highest_priority_index records current highest priority swap
+ * type which just frees swap entries. If its priority is
+ * higher than that of swap_list.next swap type, we use it. It
+ * isn't protected by swap_lock, so it can be an invalid value
+ * if the corresponding swap type is swapoff. We double check
+ * the flags here. It's even possible the swap type is swapoff
+ * and swapon again and its priority is changed. In such rare
+ * case, low prority swap type might be used, but eventually
+ * high priority swap will be used after several rounds of
+ * swap.
+ */
+ if (hp_index != -1 && hp_index != type &&
+ swap_info[type]->prio < swap_info[hp_index]->prio &&
+ (swap_info[hp_index]->flags & SWP_WRITEOK)) {
+ type = hp_index;
+ swap_list.next = type;
+ }
+
si = swap_info[type];
next = si->next;
if (next < 0 ||
@@ -430,22 +453,29 @@
wrapped++;
}
- if (!si->highest_bit)
+ spin_lock(&si->lock);
+ if (!si->highest_bit) {
+ spin_unlock(&si->lock);
continue;
- if (!(si->flags & SWP_WRITEOK))
+ }
+ if (!(si->flags & SWP_WRITEOK)) {
+ spin_unlock(&si->lock);
continue;
+ }
swap_list.next = next;
+
+ spin_unlock(&swap_lock);
/* This is called for allocating swap entry for cache */
offset = scan_swap_map(si, SWAP_HAS_CACHE);
- if (offset) {
- spin_unlock(&swap_lock);
+ spin_unlock(&si->lock);
+ if (offset)
return swp_entry(type, offset);
- }
+ spin_lock(&swap_lock);
next = swap_list.next;
}
- nr_swap_pages++;
+ atomic_long_inc(&nr_swap_pages);
noswap:
spin_unlock(&swap_lock);
return (swp_entry_t) {0};
@@ -457,19 +487,19 @@
struct swap_info_struct *si;
pgoff_t offset;
- spin_lock(&swap_lock);
si = swap_info[type];
+ spin_lock(&si->lock);
if (si && (si->flags & SWP_WRITEOK)) {
- nr_swap_pages--;
+ atomic_long_dec(&nr_swap_pages);
/* This is called for allocating swap entry, not cache */
offset = scan_swap_map(si, 1);
if (offset) {
- spin_unlock(&swap_lock);
+ spin_unlock(&si->lock);
return swp_entry(type, offset);
}
- nr_swap_pages++;
+ atomic_long_inc(&nr_swap_pages);
}
- spin_unlock(&swap_lock);
+ spin_unlock(&si->lock);
return (swp_entry_t) {0};
}
@@ -491,7 +521,7 @@
goto bad_offset;
if (!p->swap_map[offset])
goto bad_free;
- spin_lock(&swap_lock);
+ spin_lock(&p->lock);
return p;
bad_free:
@@ -509,6 +539,27 @@
return NULL;
}
+/*
+ * This swap type frees swap entry, check if it is the highest priority swap
+ * type which just frees swap entry. get_swap_page() uses
+ * highest_priority_index to search highest priority swap type. The
+ * swap_info_struct.lock can't protect us if there are multiple swap types
+ * active, so we use atomic_cmpxchg.
+ */
+static void set_highest_priority_index(int type)
+{
+ int old_hp_index, new_hp_index;
+
+ do {
+ old_hp_index = atomic_read(&highest_priority_index);
+ if (old_hp_index != -1 &&
+ swap_info[old_hp_index]->prio >= swap_info[type]->prio)
+ break;
+ new_hp_index = type;
+ } while (atomic_cmpxchg(&highest_priority_index,
+ old_hp_index, new_hp_index) != old_hp_index);
+}
+
static unsigned char swap_entry_free(struct swap_info_struct *p,
swp_entry_t entry, unsigned char usage)
{
@@ -552,10 +603,8 @@
p->lowest_bit = offset;
if (offset > p->highest_bit)
p->highest_bit = offset;
- if (swap_list.next >= 0 &&
- p->prio > swap_info[swap_list.next]->prio)
- swap_list.next = p->type;
- nr_swap_pages++;
+ set_highest_priority_index(p->type);
+ atomic_long_inc(&nr_swap_pages);
p->inuse_pages--;
if ((p->flags & SWP_BLKDEV) &&
disk->fops->swap_slot_free_notify)
@@ -576,7 +625,7 @@
p = swap_info_get(entry);
if (p) {
swap_entry_free(p, entry, 1);
- spin_unlock(&swap_lock);
+ spin_unlock(&p->lock);
}
}
@@ -593,7 +642,7 @@
count = swap_entry_free(p, entry, SWAP_HAS_CACHE);
if (page)
mem_cgroup_uncharge_swapcache(page, entry, count != 0);
- spin_unlock(&swap_lock);
+ spin_unlock(&p->lock);
}
}
@@ -612,7 +661,7 @@
p = swap_info_get(entry);
if (p) {
count = swap_count(p->swap_map[swp_offset(entry)]);
- spin_unlock(&swap_lock);
+ spin_unlock(&p->lock);
}
return count;
}
@@ -700,7 +749,7 @@
page = NULL;
}
}
- spin_unlock(&swap_lock);
+ spin_unlock(&p->lock);
}
if (page) {
/*
@@ -829,11 +878,13 @@
if ((unsigned int)type < nr_swapfiles) {
struct swap_info_struct *sis = swap_info[type];
+ spin_lock(&sis->lock);
if (sis->flags & SWP_WRITEOK) {
n = sis->pages;
if (free)
n -= sis->inuse_pages;
}
+ spin_unlock(&sis->lock);
}
spin_unlock(&swap_lock);
return n;
@@ -1529,7 +1580,7 @@
p->prio = --least_priority;
p->swap_map = swap_map;
p->flags |= SWP_WRITEOK;
- nr_swap_pages += p->pages;
+ atomic_long_add(p->pages, &nr_swap_pages);
total_swap_pages += p->pages;
/* insert swap space into swap_list: */
@@ -1606,14 +1657,16 @@
/* just pick something that's safe... */
swap_list.next = swap_list.head;
}
+ spin_lock(&p->lock);
if (p->prio < 0) {
for (i = p->next; i >= 0; i = swap_info[i]->next)
swap_info[i]->prio = p->prio--;
least_priority++;
}
- nr_swap_pages -= p->pages;
+ atomic_long_sub(p->pages, &nr_swap_pages);
total_swap_pages -= p->pages;
p->flags &= ~SWP_WRITEOK;
+ spin_unlock(&p->lock);
spin_unlock(&swap_lock);
oom_score_adj = test_set_oom_score_adj(OOM_SCORE_ADJ_MAX);
@@ -1638,14 +1691,17 @@
mutex_lock(&swapon_mutex);
spin_lock(&swap_lock);
+ spin_lock(&p->lock);
drain_mmlist();
/* wait for anyone still in scan_swap_map */
p->highest_bit = 0; /* cuts scans short */
while (p->flags >= SWP_SCANNING) {
+ spin_unlock(&p->lock);
spin_unlock(&swap_lock);
schedule_timeout_uninterruptible(1);
spin_lock(&swap_lock);
+ spin_lock(&p->lock);
}
swap_file = p->swap_file;
@@ -1654,6 +1710,7 @@
swap_map = p->swap_map;
p->swap_map = NULL;
p->flags = 0;
+ spin_unlock(&p->lock);
spin_unlock(&swap_lock);
mutex_unlock(&swapon_mutex);
vfree(swap_map);
@@ -1857,6 +1914,7 @@
p->flags = SWP_USED;
p->next = -1;
spin_unlock(&swap_lock);
+ spin_lock_init(&p->lock);
return p;
}
@@ -2178,7 +2236,7 @@
if ((si->flags & SWP_USED) && !(si->flags & SWP_WRITEOK))
nr_to_be_unused += si->inuse_pages;
}
- val->freeswap = nr_swap_pages + nr_to_be_unused;
+ val->freeswap = atomic_long_read(&nr_swap_pages) + nr_to_be_unused;
val->totalswap = total_swap_pages + nr_to_be_unused;
spin_unlock(&swap_lock);
}
@@ -2211,7 +2269,7 @@
p = swap_info[type];
offset = swp_offset(entry);
- spin_lock(&swap_lock);
+ spin_lock(&p->lock);
if (unlikely(offset >= p->max))
goto unlock_out;
@@ -2246,7 +2304,7 @@
p->swap_map[offset] = count | has_cache;
unlock_out:
- spin_unlock(&swap_lock);
+ spin_unlock(&p->lock);
out:
return err;
@@ -2371,7 +2429,7 @@
}
if (!page) {
- spin_unlock(&swap_lock);
+ spin_unlock(&si->lock);
return -ENOMEM;
}
@@ -2419,7 +2477,7 @@
list_add_tail(&page->lru, &head->lru);
page = NULL; /* now it's attached, don't free it */
out:
- spin_unlock(&swap_lock);
+ spin_unlock(&si->lock);
outer:
if (page)
__free_page(page);
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 1438de9..9e95109 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -158,8 +158,28 @@
return &mz->zone->reclaim_stat;
}
+unsigned long zone_reclaimable_pages(struct zone *zone)
+{
+ int nr;
+
+ nr = zone_page_state(zone, NR_ACTIVE_FILE) +
+ zone_page_state(zone, NR_INACTIVE_FILE);
+
+ if (get_nr_swap_pages() > 0)
+ nr += zone_page_state(zone, NR_ACTIVE_ANON) +
+ zone_page_state(zone, NR_INACTIVE_ANON);
+
+ return nr;
+}
+
+bool zone_reclaimable(struct zone *zone)
+{
+ return zone->pages_scanned < zone_reclaimable_pages(zone) * 6;
+}
+
static unsigned long zone_nr_lru_pages(struct mem_cgroup_zone *mz,
enum lru_list lru)
+
{
if (!mem_cgroup_disabled())
return mem_cgroup_zone_nr_lru_pages(mz->mem_cgroup,
@@ -1648,13 +1668,13 @@
* latencies, so it's better to scan a minimum amount there as
* well.
*/
- if (current_is_kswapd() && mz->zone->all_unreclaimable)
+ if (current_is_kswapd() && !zone_reclaimable(mz->zone))
force_scan = true;
if (!global_reclaim(sc))
force_scan = true;
/* If we have no swap space, do not bother scanning anon pages. */
- if (!sc->may_swap || (nr_swap_pages <= 0)) {
+ if (!sc->may_swap || (get_nr_swap_pages() <= 0)) {
noswap = 1;
fraction[0] = 0;
fraction[1] = 1;
@@ -1798,7 +1818,7 @@
*/
pages_for_compaction = (2UL << sc->order);
inactive_lru_pages = zone_nr_lru_pages(mz, LRU_INACTIVE_FILE);
- if (nr_swap_pages > 0)
+ if (get_nr_swap_pages() > 0)
inactive_lru_pages += zone_nr_lru_pages(mz, LRU_INACTIVE_ANON);
if (sc->nr_reclaimed < pages_for_compaction &&
inactive_lru_pages > pages_for_compaction)
@@ -1995,8 +2015,8 @@
if (global_reclaim(sc)) {
if (!cpuset_zone_allowed_hardwall(zone, GFP_KERNEL))
continue;
- if (zone->all_unreclaimable &&
- sc->priority != DEF_PRIORITY)
+ if (sc->priority != DEF_PRIORITY &&
+ !zone_reclaimable(zone))
continue; /* Let kswapd poll it */
if (COMPACTION_BUILD) {
/*
@@ -2034,11 +2054,6 @@
return aborted_reclaim;
}
-static bool zone_reclaimable(struct zone *zone)
-{
- return zone->pages_scanned < zone_reclaimable_pages(zone) * 6;
-}
-
/* All zones in zonelist are unreclaimable? */
static bool all_unreclaimable(struct zonelist *zonelist,
struct scan_control *sc)
@@ -2052,7 +2067,7 @@
continue;
if (!cpuset_zone_allowed_hardwall(zone, GFP_KERNEL))
continue;
- if (!zone->all_unreclaimable)
+ if (zone_reclaimable(zone))
return false;
}
@@ -2377,7 +2392,7 @@
* they must be considered balanced here as well if kswapd
* is to sleep
*/
- if (zone->all_unreclaimable) {
+ if (!zone_reclaimable(zone)) {
balanced += zone->present_pages;
continue;
}
@@ -2470,8 +2485,8 @@
if (!populated_zone(zone))
continue;
- if (zone->all_unreclaimable &&
- sc.priority != DEF_PRIORITY)
+ if (sc.priority != DEF_PRIORITY &&
+ !zone_reclaimable(zone))
continue;
/*
@@ -2525,8 +2540,8 @@
if (!populated_zone(zone))
continue;
- if (zone->all_unreclaimable &&
- sc.priority != DEF_PRIORITY)
+ if (sc.priority != DEF_PRIORITY &&
+ !zone_reclaimable(zone))
continue;
sc.nr_scanned = 0;
@@ -2576,8 +2591,6 @@
sc.nr_reclaimed += reclaim_state->reclaimed_slab;
total_scanned += sc.nr_scanned;
- if (nr_slab == 0 && !zone_reclaimable(zone))
- zone->all_unreclaimable = 1;
}
/*
@@ -2589,7 +2602,7 @@
total_scanned > sc.nr_reclaimed + sc.nr_reclaimed / 2)
sc.may_writepage = 1;
- if (zone->all_unreclaimable) {
+ if (!zone_reclaimable(zone)) {
if (end_zone && end_zone == i)
end_zone--;
continue;
@@ -2912,27 +2925,13 @@
nr = global_page_state(NR_ACTIVE_FILE) +
global_page_state(NR_INACTIVE_FILE);
- if (nr_swap_pages > 0)
+ if (get_nr_swap_pages() > 0)
nr += global_page_state(NR_ACTIVE_ANON) +
global_page_state(NR_INACTIVE_ANON);
return nr;
}
-unsigned long zone_reclaimable_pages(struct zone *zone)
-{
- int nr;
-
- nr = zone_page_state(zone, NR_ACTIVE_FILE) +
- zone_page_state(zone, NR_INACTIVE_FILE);
-
- if (nr_swap_pages > 0)
- nr += zone_page_state(zone, NR_ACTIVE_ANON) +
- zone_page_state(zone, NR_INACTIVE_ANON);
-
- return nr;
-}
-
#ifdef CONFIG_HIBERNATION
/*
* Try to free `nr_to_reclaim' of memory, system-wide, and return the number of
@@ -3227,7 +3226,7 @@
zone_page_state(zone, NR_SLAB_RECLAIMABLE) <= zone->min_slab_pages)
return ZONE_RECLAIM_FULL;
- if (zone->all_unreclaimable)
+ if (!zone_reclaimable(zone))
return ZONE_RECLAIM_FULL;
/*
diff --git a/mm/vmstat.c b/mm/vmstat.c
index 959a558..9559032 100644
--- a/mm/vmstat.c
+++ b/mm/vmstat.c
@@ -19,6 +19,9 @@
#include <linux/math64.h>
#include <linux/writeback.h>
#include <linux/compaction.h>
+#include <linux/mm_inline.h>
+
+#include "internal.h"
#ifdef CONFIG_VM_EVENT_COUNTERS
DEFINE_PER_CPU(struct vm_event_state, vm_event_states) = {{0}};
@@ -1027,7 +1030,7 @@
"\n all_unreclaimable: %u"
"\n start_pfn: %lu"
"\n inactive_ratio: %u",
- zone->all_unreclaimable,
+ !zone_reclaimable(zone),
zone->zone_start_pfn,
zone->inactive_ratio);
seq_putc(m, '\n');
diff --git a/sound/soc/codecs/msm8x10-wcd.c b/sound/soc/codecs/msm8x10-wcd.c
index 6785fe1..52af21c 100644
--- a/sound/soc/codecs/msm8x10-wcd.c
+++ b/sound/soc/codecs/msm8x10-wcd.c
@@ -3007,10 +3007,21 @@
return NULL;
}
+static int msm8x10_wcd_device_down(struct snd_soc_codec *codec)
+{
+ dev_dbg(codec->dev, "%s: device down!\n", __func__);
+
+ snd_soc_card_change_online_state(codec->card, 0);
+ return 0;
+}
static int msm8x10_wcd_device_up(struct snd_soc_codec *codec)
{
- pr_debug("%s: device up!\n", __func__);
+ dev_dbg(codec->dev, "%s: device up!\n", __func__);
+
+ snd_soc_card_change_online_state(codec->card, 1);
+ /* delay is required to make sure sound card state updated */
+ usleep_range(5000, 5100);
mutex_lock(&codec->mutex);
@@ -3029,7 +3040,9 @@
bool timedout;
unsigned long timeout;
- if (value == SUBSYS_AFTER_POWERUP) {
+ if (value == SUBSYS_BEFORE_SHUTDOWN)
+ msm8x10_wcd_device_down(registered_codec);
+ else if (value == SUBSYS_AFTER_POWERUP) {
pr_debug("%s: ADSP is about to power up. bring up codec\n",
__func__);
diff --git a/sound/soc/codecs/wcd9320.c b/sound/soc/codecs/wcd9320.c
index bc02513..6dc2ec0 100644
--- a/sound/soc/codecs/wcd9320.c
+++ b/sound/soc/codecs/wcd9320.c
@@ -5975,6 +5975,10 @@
/* Set HPH Path to low power mode */
TAIKO_REG_VAL(TAIKO_A_RX_HPH_BIAS_PA, 0x55),
+
+ /* BUCK default */
+ TAIKO_REG_VAL(WCD9XXX_A_BUCK_CTRL_CCL_4, 0x51),
+ TAIKO_REG_VAL(WCD9XXX_A_BUCK_CTRL_CCL_1, 0x5B),
};
static const struct wcd9xxx_reg_mask_val taiko_1_0_reg_defaults[] = {
@@ -5983,13 +5987,9 @@
* Taiko 2.0 will have appropriate defaults for these registers.
*/
- /* BUCK default */
- TAIKO_REG_VAL(WCD9XXX_A_BUCK_CTRL_CCL_4, 0x50),
-
/* Required defaults for class H operation */
TAIKO_REG_VAL(TAIKO_A_RX_HPH_CHOP_CTL, 0xF4),
TAIKO_REG_VAL(TAIKO_A_BIAS_CURR_CTL_2, 0x08),
- TAIKO_REG_VAL(WCD9XXX_A_BUCK_CTRL_CCL_1, 0x5B),
TAIKO_REG_VAL(WCD9XXX_A_BUCK_CTRL_CCL_3, 0x60),
/* Choose max non-overlap time for NCP */
@@ -6040,7 +6040,7 @@
TAIKO_REG_VAL(TAIKO_A_CDC_TX_5_6_ADC_IB, 0x44),
TAIKO_REG_VAL(WCD9XXX_A_BUCK_MODE_3, 0xCE),
TAIKO_REG_VAL(WCD9XXX_A_BUCK_CTRL_VCL_1, 0x8),
- TAIKO_REG_VAL(WCD9XXX_A_BUCK_CTRL_CCL_4, 0x51),
+ TAIKO_REG_VAL(TAIKO_A_BUCK_CTRL_CCL_4, 0x51),
TAIKO_REG_VAL(TAIKO_A_NCP_DTEST, 0x10),
TAIKO_REG_VAL(TAIKO_A_RX_HPH_CHOP_CTL, 0xA4),
TAIKO_REG_VAL(TAIKO_A_RX_HPH_OCP_CTL, 0x69),
@@ -6081,6 +6081,7 @@
TAIKO_REG_VAL(TAIKO_A_CDC_SPKR_CLIPDET_B1_CTL, 0x0),
TAIKO_REG_VAL(TAIKO_A_CDC_COMP0_B4_CTL, 0x37),
TAIKO_REG_VAL(TAIKO_A_CDC_COMP0_B5_CTL, 0x7f),
+ TAIKO_REG_VAL(TAIKO_A_CDC_COMP0_B5_CTL, 0x7f),
};
static void taiko_update_reg_defaults(struct snd_soc_codec *codec)
diff --git a/sound/soc/codecs/wcd9xxx-common.c b/sound/soc/codecs/wcd9xxx-common.c
index 05f2191..b104a6b 100644
--- a/sound/soc/codecs/wcd9xxx-common.c
+++ b/sound/soc/codecs/wcd9xxx-common.c
@@ -22,12 +22,11 @@
#define CLSH_COMPUTE_HPH_L 0x02
#define CLSH_COMPUTE_HPH_R 0x03
+#define BUCK_VREF_0P494V 0x3F
#define BUCK_VREF_2V 0xFF
+#define BUCK_VREF_0P494V 0x3F
#define BUCK_VREF_1P8V 0xE6
-#define NCP_FCLK_LEVEL_8 0x08
-#define NCP_FCLK_LEVEL_5 0x05
-
#define BUCK_SETTLE_TIME_US 50
#define NCP_SETTLE_TIME_US 50
@@ -414,12 +413,16 @@
{32164, 22},
};
-static inline void wcd9xxx_enable_clsh_block(
- struct snd_soc_codec *codec,
- bool on)
+static inline void
+wcd9xxx_enable_clsh_block(struct snd_soc_codec *codec,
+ struct wcd9xxx_clsh_cdc_data *clsh_d, bool enable)
{
- snd_soc_update_bits(codec, WCD9XXX_A_CDC_CLSH_B1_CTL,
- 0x01, on ? 0x01 : 0x00);
+ if ((enable && ++clsh_d->clsh_users == 1) ||
+ (!enable && --clsh_d->clsh_users == 0))
+ snd_soc_update_bits(codec, WCD9XXX_A_CDC_CLSH_B1_CTL,
+ 0x01, enable ? 0x01 : 0x00);
+ dev_dbg(codec->dev, "%s: clsh_users %d, enable %d", __func__,
+ clsh_d->clsh_users, enable);
}
static inline void wcd9xxx_enable_anc_delay(
@@ -430,64 +433,56 @@
0x02, on ? 0x02 : 0x00);
}
-static inline void wcd9xxx_enable_ncp(
- struct snd_soc_codec *codec,
- bool on)
+static inline void
+wcd9xxx_enable_buck(struct snd_soc_codec *codec,
+ struct wcd9xxx_clsh_cdc_data *clsh_d, bool enable)
{
- snd_soc_update_bits(codec, WCD9XXX_A_NCP_EN,
- 0x01, on ? 0x01 : 0x00);
+ if ((enable && ++clsh_d->buck_users == 1) ||
+ (!enable && --clsh_d->buck_users == 0))
+ snd_soc_update_bits(codec, WCD9XXX_A_BUCK_MODE_1,
+ 0x80, enable ? 0x80 : 0x00);
+ dev_dbg(codec->dev, "%s: buck_users %d, enable %d", __func__,
+ clsh_d->buck_users, enable);
}
-static inline void wcd9xxx_enable_buck(
- struct snd_soc_codec *codec,
- bool on)
-{
- snd_soc_update_bits(codec, WCD9XXX_A_BUCK_MODE_1,
- 0x80, on ? 0x80 : 0x00);
-}
+static void (*clsh_state_fp[NUM_CLSH_STATES])(struct snd_soc_codec *,
+ struct wcd9xxx_clsh_cdc_data *,
+ u8 req_state, bool req_type);
-static int cdc_lo_count;
-
-static void (*clsh_state_fp[NUM_CLSH_STATES])
- (struct snd_soc_codec *,
- struct wcd9xxx_clsh_cdc_data *,
- u8 req_state, bool req_type);
-
-static const char *state_to_str(u8 state)
-{
- if (state == WCD9XXX_CLSH_STATE_IDLE)
- return "STATE_IDLE";
- else if (state == WCD9XXX_CLSH_STATE_EAR)
- return "STATE_EAR";
- else if (state == WCD9XXX_CLSH_STATE_HPHL)
- return "STATE_HPH_L";
- else if (state == WCD9XXX_CLSH_STATE_HPHR)
- return "STATE_HPH_R";
- else if (state == (WCD9XXX_CLSH_STATE_HPHL
- | WCD9XXX_CLSH_STATE_HPHR))
- return "STATE_HPH_L_R";
- else if (state == WCD9XXX_CLSH_STATE_LO)
- return "STATE_LO";
-
- return "UNKNOWN_STATE";
-}
-
-static void wcd9xxx_cfg_clsh_buck(
- struct snd_soc_codec *codec)
+static const char *state_to_str(u8 state, char *buf, size_t buflen)
{
int i;
- const struct wcd9xxx_reg_mask_val reg_set[] = {
- {WCD9XXX_A_BUCK_CTRL_CCL_4, 0x0B, 0x00},
- {WCD9XXX_A_BUCK_CTRL_CCL_1, 0xF0, 0x50},
- {WCD9XXX_A_BUCK_CTRL_CCL_3, 0x03, 0x00},
- {WCD9XXX_A_BUCK_CTRL_CCL_3, 0x0B, 0x00},
+ int cnt = 0;
+ /*
+ * This array of strings should match with enum wcd9xxx_clsh_state_bit.
+ */
+ const char *states[] = {
+ "STATE_EAR",
+ "STATE_HPH_L",
+ "STATE_HPH_R",
+ "STATE_LO",
};
- for (i = 0; i < ARRAY_SIZE(reg_set); i++)
- snd_soc_update_bits(codec, reg_set[i].reg, reg_set[i].mask,
- reg_set[i].val);
+ if (state == WCD9XXX_CLSH_STATE_IDLE) {
+ snprintf(buf, buflen, "[STATE_IDLE]");
+ goto done;
+ }
- dev_dbg(codec->dev, "%s: Programmed buck parameters", __func__);
+ buf[0] = '\0';
+ for (i = 0; i < ARRAY_SIZE(states); i++) {
+ if (!(state & (1 << i)))
+ continue;
+ cnt = snprintf(buf, buflen - cnt - 1, "%s%s%s", buf,
+ buf[0] == '\0' ? "[" : "|",
+ states[i]);
+ }
+ if (cnt > 0)
+ strlcat(buf + cnt, "]", buflen);
+
+done:
+ if (buf[0] == '\0')
+ snprintf(buf, buflen, "[STATE_UNKNOWN]");
+ return buf;
}
static void wcd9xxx_cfg_clsh_param_common(
@@ -515,26 +510,25 @@
__func__);
}
-static void wcd9xxx_chargepump_request(
- struct snd_soc_codec *codec, bool on)
+static void wcd9xxx_chargepump_request(struct snd_soc_codec *codec, bool on)
{
static int cp_count;
if (on && (++cp_count == 1)) {
snd_soc_update_bits(codec, WCD9XXX_A_CDC_CLK_OTHR_CTL,
- 0x01, 0x01);
+ 0x01, 0x01);
dev_dbg(codec->dev, "%s: Charge Pump enabled, count = %d\n",
- __func__, cp_count);
- }
-
- else if (!on) {
+ __func__, cp_count);
+ } else if (!on) {
if (--cp_count < 0) {
- dev_dbg(codec->dev, "%s: Unbalanced disable for charge pump\n",
+ dev_dbg(codec->dev,
+ "%s: Unbalanced disable for charge pump\n",
+ __func__);
+ if (snd_soc_read(codec, WCD9XXX_A_CDC_CLK_OTHR_CTL) &
+ 0x01) {
+ dev_dbg(codec->dev,
+ "%s: Actual chargepump is ON\n",
__func__);
- if (snd_soc_read(codec, WCD9XXX_A_CDC_CLK_OTHR_CTL)
- & 0x01) {
- dev_dbg(codec->dev, "%s: Actual chargepump is ON\n",
- __func__);
}
cp_count = 0;
WARN_ON(1);
@@ -542,9 +536,10 @@
if (cp_count == 0) {
snd_soc_update_bits(codec, WCD9XXX_A_CDC_CLK_OTHR_CTL,
- 0x01, 0x00);
- dev_dbg(codec->dev, "%s: Charge pump disabled, count = %d\n",
- __func__, cp_count);
+ 0x01, 0x00);
+ dev_dbg(codec->dev,
+ "%s: Charge pump disabled, count = %d\n",
+ __func__, cp_count);
}
}
}
@@ -617,7 +612,6 @@
}
}
-
int wcd9xxx_soc_update_bits_push(struct snd_soc_codec *codec,
struct list_head *list,
uint16_t reg, uint8_t mask,
@@ -657,18 +651,15 @@
}
EXPORT_SYMBOL(wcd9xxx_restore_registers);
-static void wcd9xxx_enable_buck_mode(struct snd_soc_codec *codec,
- u8 buck_vref)
+static void wcd9xxx_set_buck_mode(struct snd_soc_codec *codec, u8 buck_vref)
{
int i;
const struct wcd9xxx_reg_mask_val reg_set[] = {
- {WCD9XXX_A_BUCK_MODE_5, 0x02, 0x03},
+ {WCD9XXX_A_BUCK_MODE_5, 0x02, 0x02},
{WCD9XXX_A_BUCK_MODE_4, 0xFF, buck_vref},
{WCD9XXX_A_BUCK_MODE_1, 0x04, 0x04},
- {WCD9XXX_A_BUCK_MODE_1, 0x08, 0x00},
{WCD9XXX_A_BUCK_MODE_3, 0x04, 0x00},
{WCD9XXX_A_BUCK_MODE_3, 0x08, 0x00},
- {WCD9XXX_A_BUCK_MODE_1, 0x80, 0x80},
};
for (i = 0; i < ARRAY_SIZE(reg_set); i++)
@@ -704,25 +695,51 @@
}
-static void wcd9xxx_set_fclk_enable_ncp(struct snd_soc_codec *codec,
- u8 fclk_level)
+static void wcd9xxx_set_fclk_get_ncp(struct snd_soc_codec *codec,
+ struct wcd9xxx_clsh_cdc_data *clsh_d,
+ enum ncp_fclk_level fclk_level)
{
- int i;
- const struct wcd9xxx_reg_mask_val reg_set[] = {
- {WCD9XXX_A_NCP_STATIC, 0x20, 0x20},
- {WCD9XXX_A_NCP_EN, 0x01, 0x01},
- };
- snd_soc_update_bits(codec, WCD9XXX_A_NCP_STATIC,
- 0x010, 0x00);
- snd_soc_update_bits(codec, WCD9XXX_A_NCP_STATIC,
- 0x0F, fclk_level);
- for (i = 0; i < ARRAY_SIZE(reg_set); i++)
- snd_soc_update_bits(codec, reg_set[i].reg,
- reg_set[i].mask, reg_set[i].val);
+ clsh_d->ncp_users[fclk_level]++;
- usleep_range(NCP_SETTLE_TIME_US, NCP_SETTLE_TIME_US);
+ pr_debug("%s: enter ncp type %d users fclk8 %d, fclk5 %d\n", __func__,
+ fclk_level, clsh_d->ncp_users[NCP_FCLK_LEVEL_8],
+ clsh_d->ncp_users[NCP_FCLK_LEVEL_5]);
- dev_dbg(codec->dev, "%s: set ncp done\n", __func__);
+ snd_soc_update_bits(codec, WCD9XXX_A_NCP_STATIC, 0x10, 0x00);
+ /* fclk level 8 dominates level 5 */
+ if (clsh_d->ncp_users[NCP_FCLK_LEVEL_8] > 0)
+ snd_soc_update_bits(codec, WCD9XXX_A_NCP_STATIC, 0x0F, 0x08);
+ else if (clsh_d->ncp_users[NCP_FCLK_LEVEL_5] > 0)
+ snd_soc_update_bits(codec, WCD9XXX_A_NCP_STATIC, 0x0F, 0x05);
+ else
+ WARN_ONCE(1, "Unexpected users %d,%d\n",
+ clsh_d->ncp_users[NCP_FCLK_LEVEL_8],
+ clsh_d->ncp_users[NCP_FCLK_LEVEL_5]);
+ snd_soc_update_bits(codec, WCD9XXX_A_NCP_STATIC, 0x20, 0x20);
+
+ /* enable NCP and wait until settles down */
+ if (snd_soc_update_bits(codec, WCD9XXX_A_NCP_EN, 0x01, 0x01))
+ usleep_range(NCP_SETTLE_TIME_US, NCP_SETTLE_TIME_US);
+ pr_debug("%s: leave\n", __func__);
+}
+
+static void wcd9xxx_set_fclk_put_ncp(struct snd_soc_codec *codec,
+ struct wcd9xxx_clsh_cdc_data *clsh_d,
+ enum ncp_fclk_level fclk_level)
+{
+ clsh_d->ncp_users[fclk_level]--;
+
+ pr_debug("%s: enter ncp type %d users fclk8 %d, fclk5 %d\n", __func__,
+ fclk_level, clsh_d->ncp_users[NCP_FCLK_LEVEL_8],
+ clsh_d->ncp_users[NCP_FCLK_LEVEL_5]);
+
+ if (clsh_d->ncp_users[NCP_FCLK_LEVEL_8] == 0 &&
+ clsh_d->ncp_users[NCP_FCLK_LEVEL_5] == 0)
+ snd_soc_update_bits(codec, WCD9XXX_A_NCP_EN, 0x01, 0x00);
+ else if (clsh_d->ncp_users[NCP_FCLK_LEVEL_8] == 0)
+ /* if dominating level 8 has gone, switch to 5 */
+ snd_soc_update_bits(codec, WCD9XXX_A_NCP_STATIC, 0x0F, 0x05);
+ pr_debug("%s: leave\n", __func__);
}
static void wcd9xxx_cfg_clsh_param_ear(struct snd_soc_codec *codec)
@@ -790,72 +807,30 @@
__func__);
}
-static void wcd9xxx_clsh_turnoff_postpa
- (struct snd_soc_codec *codec)
-{
-
- int i;
-
- const struct wcd9xxx_reg_mask_val reg_set[] = {
- {WCD9XXX_A_NCP_EN, 0x01, 0x00},
- {WCD9XXX_A_BUCK_MODE_1, 0x80, 0x00},
- {WCD9XXX_A_CDC_CLSH_B1_CTL, 0x10, 0x00},
- };
-
- wcd9xxx_chargepump_request(codec, false);
-
- for (i = 0; i < ARRAY_SIZE(reg_set); i++)
- snd_soc_update_bits(codec, reg_set[i].reg,
- reg_set[i].mask, reg_set[i].val);
-
- wcd9xxx_enable_clsh_block(codec, false);
-
- dev_dbg(codec->dev, "%s: Done\n", __func__);
-}
-
-static void wcd9xxx_clsh_state_idle(struct snd_soc_codec *codec,
- struct wcd9xxx_clsh_cdc_data *clsh_d,
- u8 req_state, bool is_enable)
-{
- if (is_enable) {
- dev_dbg(codec->dev, "%s: wrong transition, cannot enable IDLE state\n",
- __func__);
- } else {
- if (req_state == WCD9XXX_CLSH_STATE_EAR) {
- wcd9xxx_clsh_turnoff_postpa(codec);
- } else if (req_state == WCD9XXX_CLSH_STATE_HPHL) {
- wcd9xxx_clsh_comp_req(codec, clsh_d, CLSH_COMPUTE_HPH_L,
- false);
- wcd9xxx_clsh_turnoff_postpa(codec);
- } else if (req_state == WCD9XXX_CLSH_STATE_HPHR) {
- wcd9xxx_clsh_comp_req(codec, clsh_d, CLSH_COMPUTE_HPH_R,
- false);
- wcd9xxx_clsh_turnoff_postpa(codec);
- } else if (req_state == WCD9XXX_CLSH_STATE_LO) {
- wcd9xxx_enable_ncp(codec, false);
- wcd9xxx_enable_buck(codec, false);
- }
- }
-}
-
static void wcd9xxx_clsh_state_ear(struct snd_soc_codec *codec,
struct wcd9xxx_clsh_cdc_data *clsh_d,
u8 req_state, bool is_enable)
{
+ pr_debug("%s: enter %s\n", __func__, is_enable ? "enable" : "disable");
if (is_enable) {
- wcd9xxx_cfg_clsh_buck(codec);
wcd9xxx_cfg_clsh_param_common(codec);
wcd9xxx_cfg_clsh_param_ear(codec);
- wcd9xxx_enable_clsh_block(codec, true);
+ wcd9xxx_enable_clsh_block(codec, clsh_d, true);
wcd9xxx_chargepump_request(codec, true);
wcd9xxx_enable_anc_delay(codec, true);
wcd9xxx_clsh_comp_req(codec, clsh_d, CLSH_COMPUTE_EAR, true);
- wcd9xxx_enable_buck_mode(codec, BUCK_VREF_2V);
- wcd9xxx_set_fclk_enable_ncp(codec, NCP_FCLK_LEVEL_8);
+ wcd9xxx_set_buck_mode(codec, BUCK_VREF_2V);
+ wcd9xxx_enable_buck(codec, clsh_d, true);
+ wcd9xxx_set_fclk_get_ncp(codec, clsh_d, NCP_FCLK_LEVEL_8);
dev_dbg(codec->dev, "%s: Enabled ear mode class h\n", __func__);
} else {
dev_dbg(codec->dev, "%s: stub fallback to ear\n", __func__);
+ wcd9xxx_set_fclk_put_ncp(codec, clsh_d, NCP_FCLK_LEVEL_8);
+ wcd9xxx_enable_buck(codec, clsh_d, false);
+ wcd9xxx_clsh_comp_req(codec, clsh_d, CLSH_COMPUTE_EAR, true);
+ wcd9xxx_chargepump_request(codec, false);
+ wcd9xxx_enable_clsh_block(codec, clsh_d, false);
}
}
@@ -863,26 +838,26 @@
struct wcd9xxx_clsh_cdc_data *clsh_d,
u8 req_state, bool is_enable)
{
+ pr_debug("%s: enter %s\n", __func__, is_enable ? "enable" : "disable");
+
if (is_enable) {
- wcd9xxx_cfg_clsh_buck(codec);
wcd9xxx_cfg_clsh_param_common(codec);
wcd9xxx_cfg_clsh_param_hph(codec);
- wcd9xxx_enable_clsh_block(codec, true);
+ wcd9xxx_enable_clsh_block(codec, clsh_d, true);
wcd9xxx_chargepump_request(codec, true);
wcd9xxx_enable_anc_delay(codec, true);
wcd9xxx_clsh_comp_req(codec, clsh_d, CLSH_COMPUTE_HPH_L, true);
- wcd9xxx_enable_buck_mode(codec, BUCK_VREF_2V);
- wcd9xxx_set_fclk_enable_ncp(codec, NCP_FCLK_LEVEL_8);
+ wcd9xxx_set_buck_mode(codec, BUCK_VREF_0P494V);
+ wcd9xxx_enable_buck(codec, clsh_d, true);
+ wcd9xxx_set_fclk_get_ncp(codec, clsh_d, NCP_FCLK_LEVEL_8);
dev_dbg(codec->dev, "%s: Done\n", __func__);
} else {
- if (req_state == WCD9XXX_CLSH_STATE_HPHR) {
- wcd9xxx_clsh_comp_req(codec, clsh_d, CLSH_COMPUTE_HPH_R,
- false);
- } else {
- dev_dbg(codec->dev, "%s: stub fallback to hph_l\n",
- __func__);
- }
+ wcd9xxx_set_fclk_put_ncp(codec, clsh_d, NCP_FCLK_LEVEL_8);
+ wcd9xxx_enable_buck(codec, clsh_d, false);
+ wcd9xxx_clsh_comp_req(codec, clsh_d, CLSH_COMPUTE_HPH_L, false);
+ wcd9xxx_chargepump_request(codec, false);
+ wcd9xxx_enable_clsh_block(codec, clsh_d, false);
}
}
@@ -890,27 +865,26 @@
struct wcd9xxx_clsh_cdc_data *clsh_d,
u8 req_state, bool is_enable)
{
- if (is_enable) {
+ pr_debug("%s: enter %s\n", __func__, is_enable ? "enable" : "disable");
- wcd9xxx_cfg_clsh_buck(codec);
+ if (is_enable) {
wcd9xxx_cfg_clsh_param_common(codec);
wcd9xxx_cfg_clsh_param_hph(codec);
- wcd9xxx_enable_clsh_block(codec, true);
+ wcd9xxx_enable_clsh_block(codec, clsh_d, true);
wcd9xxx_chargepump_request(codec, true);
wcd9xxx_enable_anc_delay(codec, true);
wcd9xxx_clsh_comp_req(codec, clsh_d, CLSH_COMPUTE_HPH_R, true);
- wcd9xxx_enable_buck_mode(codec, BUCK_VREF_2V);
- wcd9xxx_set_fclk_enable_ncp(codec, NCP_FCLK_LEVEL_8);
+ wcd9xxx_set_buck_mode(codec, BUCK_VREF_0P494V);
+ wcd9xxx_enable_buck(codec, clsh_d, true);
+ wcd9xxx_set_fclk_get_ncp(codec, clsh_d, NCP_FCLK_LEVEL_8);
dev_dbg(codec->dev, "%s: Done\n", __func__);
} else {
- if (req_state == WCD9XXX_CLSH_STATE_HPHL) {
- wcd9xxx_clsh_comp_req(codec, clsh_d, CLSH_COMPUTE_HPH_L,
- false);
- } else {
- dev_dbg(codec->dev, "%s: stub fallback to hph_r\n",
- __func__);
- }
+ wcd9xxx_set_fclk_put_ncp(codec, clsh_d, NCP_FCLK_LEVEL_8);
+ wcd9xxx_enable_buck(codec, clsh_d, false);
+ wcd9xxx_clsh_comp_req(codec, clsh_d, CLSH_COMPUTE_HPH_R, false);
+ wcd9xxx_chargepump_request(codec, false);
+ wcd9xxx_enable_clsh_block(codec, clsh_d, false);
}
}
@@ -918,9 +892,11 @@
struct wcd9xxx_clsh_cdc_data *clsh_d,
u8 req_state, bool is_enable)
{
+ pr_debug("%s: enter %s\n", __func__, is_enable ? "enable" : "disable");
+
if (is_enable) {
wcd9xxx_clsh_comp_req(codec, clsh_d, CLSH_COMPUTE_HPH_L, true);
- wcd9xxx_clsh_comp_req(codec, clsh_d, CLSH_COMPUTE_HPH_R, true);
+ wcd9xxx_clsh_comp_req(codec, clsh_d, CLSH_COMPUTE_HPH_R, true);
} else {
dev_dbg(codec->dev, "%s: stub fallback to hph_st\n", __func__);
}
@@ -930,38 +906,36 @@
struct wcd9xxx_clsh_cdc_data *clsh_d,
u8 req_state, bool is_enable)
{
- if (is_enable) {
- if (++cdc_lo_count > 1)
- return;
+ pr_debug("%s: enter %s, buck_mv %d\n", __func__,
+ is_enable ? "enable" : "disable", clsh_d->buck_mv);
- wcd9xxx_enable_buck_mode(codec, BUCK_VREF_1P8V);
- wcd9xxx_set_fclk_enable_ncp(codec, NCP_FCLK_LEVEL_5);
+ if (is_enable) {
+ wcd9xxx_set_buck_mode(codec, BUCK_VREF_1P8V);
+ wcd9xxx_enable_buck(codec, clsh_d, true);
+ wcd9xxx_set_fclk_get_ncp(codec, clsh_d, NCP_FCLK_LEVEL_5);
if (clsh_d->buck_mv == WCD9XXX_CDC_BUCK_MV_1P8) {
- wcd9xxx_enable_buck(codec, false);
+ wcd9xxx_enable_buck(codec, clsh_d, false);
snd_soc_update_bits(codec, WCD9XXX_A_NCP_STATIC,
- 0x20, 0x01);
- wcd9xxx_enable_ncp(codec, true);
+ 1 << 4, 1 << 4);
/* NCP settle time recommended by codec specification */
usleep_range(NCP_SETTLE_TIME_US,
- NCP_SETTLE_TIME_US + 10);
-
+ NCP_SETTLE_TIME_US + 10);
} else {
- snd_soc_update_bits(codec, WCD9XXX_A_NCP_EN,
- 0x40, 0x00);
- wcd9xxx_enable_ncp(codec, true);
/* NCP settle time recommended by codec specification */
usleep_range(NCP_SETTLE_TIME_US,
- NCP_SETTLE_TIME_US + 10);
+ NCP_SETTLE_TIME_US + 10);
snd_soc_update_bits(codec, WCD9XXX_A_BUCK_MODE_5,
- 0x01, 0x01);
+ 0x01, (0x01 & 0x03));
snd_soc_update_bits(codec, WCD9XXX_A_BUCK_MODE_5,
- 0xFB, (0x02 << 2));
+ 0xFC, (0xFC & 0xB));
}
- snd_soc_update_bits(codec, WCD9XXX_A_BUCK_MODE_1,
- 0x04, 0x00);
+ snd_soc_update_bits(codec, WCD9XXX_A_BUCK_MODE_1, 0x04, 0x00);
} else {
dev_dbg(codec->dev, "%s: stub fallback to lineout\n", __func__);
+ wcd9xxx_set_fclk_put_ncp(codec, clsh_d, NCP_FCLK_LEVEL_5);
+ if (clsh_d->buck_mv != WCD9XXX_CDC_BUCK_MV_1P8)
+ wcd9xxx_enable_buck(codec, clsh_d, false);
}
}
@@ -969,9 +943,12 @@
struct wcd9xxx_clsh_cdc_data *clsh_d,
u8 req_state, bool is_enable)
{
- dev_dbg(codec->dev, "%s Wrong request for class H state machine requested to %s %s"
- , __func__, is_enable ? "enable" : "disable",
- state_to_str(req_state));
+ char msg[128];
+
+ dev_dbg(codec->dev,
+ "%s Wrong request for class H state machine requested to %s %s",
+ __func__, is_enable ? "enable" : "disable",
+ state_to_str(req_state, msg, sizeof(msg)));
WARN_ON(1);
}
@@ -980,51 +957,45 @@
u8 req_state, bool req_type, u8 clsh_event)
{
u8 old_state, new_state;
+ char msg0[128], msg1[128];
switch (clsh_event) {
-
case WCD9XXX_CLSH_EVENT_PRE_DAC:
-
/* PRE_DAC event should be used only for Enable */
BUG_ON(req_type != WCD9XXX_CLSH_REQ_ENABLE);
old_state = cdc_clsh_d->state;
new_state = old_state | req_state;
- (*clsh_state_fp[new_state]) (codec, cdc_clsh_d,
- req_state, req_type);
+ (*clsh_state_fp[req_state]) (codec, cdc_clsh_d, req_state,
+ req_type);
cdc_clsh_d->state = new_state;
dev_dbg(codec->dev, "%s: ClassH state transition from %s to %s\n",
- __func__, state_to_str(old_state),
- state_to_str(cdc_clsh_d->state));
+ __func__, state_to_str(old_state, msg0, sizeof(msg0)),
+ state_to_str(cdc_clsh_d->state, msg1, sizeof(msg1)));
break;
-
case WCD9XXX_CLSH_EVENT_POST_PA:
-
if (req_type == WCD9XXX_CLSH_REQ_DISABLE) {
- if (req_state == WCD9XXX_CLSH_STATE_LO
- && --cdc_lo_count > 0)
- break;
-
old_state = cdc_clsh_d->state;
new_state = old_state & (~req_state);
if (new_state < NUM_CLSH_STATES) {
- (*clsh_state_fp[new_state]) (codec, cdc_clsh_d,
- req_state, req_type);
+ (*clsh_state_fp[req_state]) (codec, cdc_clsh_d,
+ req_state,
+ req_type);
cdc_clsh_d->state = new_state;
dev_dbg(codec->dev, "%s: ClassH state transition from %s to %s\n",
- __func__, state_to_str(old_state),
- state_to_str(cdc_clsh_d->state));
+ __func__, state_to_str(old_state, msg0,
+ sizeof(msg0)),
+ state_to_str(cdc_clsh_d->state, msg1,
+ sizeof(msg1)));
} else {
dev_dbg(codec->dev, "%s: wrong new state = %x\n",
__func__, new_state);
}
-
-
- } else if (req_state != WCD9XXX_CLSH_STATE_LO) {
+ } else if (!(cdc_clsh_d->state & WCD9XXX_CLSH_STATE_LO)) {
wcd9xxx_clsh_enable_post_pa(codec, cdc_clsh_d);
}
@@ -1044,7 +1015,6 @@
for (i = 0; i < NUM_CLSH_STATES; i++)
clsh_state_fp[i] = wcd9xxx_clsh_state_err;
- clsh_state_fp[WCD9XXX_CLSH_STATE_IDLE] = wcd9xxx_clsh_state_idle;
clsh_state_fp[WCD9XXX_CLSH_STATE_EAR] = wcd9xxx_clsh_state_ear;
clsh_state_fp[WCD9XXX_CLSH_STATE_HPHL] =
wcd9xxx_clsh_state_hph_l;
diff --git a/sound/soc/codecs/wcd9xxx-common.h b/sound/soc/codecs/wcd9xxx-common.h
index 0239c86..324f6e9 100644
--- a/sound/soc/codecs/wcd9xxx-common.h
+++ b/sound/soc/codecs/wcd9xxx-common.h
@@ -63,11 +63,20 @@
u8 val;
};
+enum ncp_fclk_level {
+ NCP_FCLK_LEVEL_8,
+ NCP_FCLK_LEVEL_5,
+ NCP_FCLK_LEVEL_MAX,
+};
+
/* Class H data that the codec driver will maintain */
struct wcd9xxx_clsh_cdc_data {
u8 state;
int buck_mv;
bool is_dynamic_vdd_cp;
+ int clsh_users;
+ int buck_users;
+ int ncp_users[NCP_FCLK_LEVEL_MAX];
struct wcd9xxx_resmgr *resmgr;
};
diff --git a/sound/soc/msm/msm-pcm-host-voice.c b/sound/soc/msm/msm-pcm-host-voice.c
index 2eafc1d..1b68bcf 100644
--- a/sound/soc/msm/msm-pcm-host-voice.c
+++ b/sound/soc/msm/msm-pcm-host-voice.c
@@ -989,7 +989,7 @@
spin_unlock_irqrestore(&dai_data->dsp_lock, dsp_flags);
ret = copy_to_user(buf,
&buf_node->frame.voc_pkt,
- count);
+ buf_node->frame.len);
if (ret) {
pr_err("%s: Copy to user retuned %d\n",
__func__, ret);
diff --git a/sound/soc/msm/qdsp6v2/audio_acdb.c b/sound/soc/msm/qdsp6v2/audio_acdb.c
index 01422cf..8187616 100644
--- a/sound/soc/msm/qdsp6v2/audio_acdb.c
+++ b/sound/soc/msm/qdsp6v2/audio_acdb.c
@@ -38,64 +38,60 @@
#define MAX_HW_DELAY_ENTRIES 25
-struct sidetone_atomic_cal {
- atomic_t enable;
- atomic_t gain;
-};
-
-
struct acdb_data {
+ uint32_t usage_count;
+
struct mutex acdb_mutex;
/* ANC Cal */
- struct acdb_atomic_cal_block anc_cal;
+ struct acdb_cal_block anc_cal;
/* AANC Cal */
- struct acdb_atomic_cal_block aanc_cal;
+ struct acdb_cal_block aanc_cal;
/* LSM Cal */
- struct acdb_atomic_cal_block lsm_cal;
+ struct acdb_cal_block lsm_cal;
/* AudProc Cal */
- atomic_t asm_topology;
- atomic_t adm_topology[MAX_AUDPROC_TYPES];
- struct acdb_atomic_cal_block audproc_cal[MAX_AUDPROC_TYPES];
- struct acdb_atomic_cal_block audstrm_cal[MAX_AUDPROC_TYPES];
- struct acdb_atomic_cal_block audvol_cal[MAX_AUDPROC_TYPES];
+ uint32_t asm_topology;
+ uint32_t adm_topology[MAX_AUDPROC_TYPES];
+ struct acdb_cal_block audproc_cal[MAX_AUDPROC_TYPES];
+ struct acdb_cal_block audstrm_cal[MAX_AUDPROC_TYPES];
+ struct acdb_cal_block audvol_cal[MAX_AUDPROC_TYPES];
/* VocProc Cal */
- atomic_t voice_rx_topology;
- atomic_t voice_tx_topology;
- struct acdb_atomic_cal_block vocproc_cal;
- struct acdb_atomic_cal_block vocstrm_cal;
- struct acdb_atomic_cal_block vocvol_cal;
+ uint32_t voice_rx_topology;
+ uint32_t voice_tx_topology;
+ struct acdb_cal_block vocproc_cal;
+ struct acdb_cal_block vocstrm_cal;
+ struct acdb_cal_block vocvol_cal;
/* Voice Column data */
- struct acdb_atomic_cal_block vocproc_col_cal[MAX_VOCPROC_TYPES];
+ struct acdb_cal_block vocproc_col_cal[MAX_VOCPROC_TYPES];
uint32_t *col_data[MAX_VOCPROC_TYPES];
/* VocProc dev cfg cal*/
- struct acdb_atomic_cal_block vocproc_dev_cal;
+ struct acdb_cal_block vocproc_dev_cal;
/* Custom topology */
- struct acdb_atomic_cal_block adm_custom_topology;
- struct acdb_atomic_cal_block asm_custom_topology;
- atomic_t valid_adm_custom_top;
- atomic_t valid_asm_custom_top;
+ struct acdb_cal_block adm_custom_topology;
+ struct acdb_cal_block asm_custom_topology;
+ uint32_t valid_adm_custom_top;
+ uint32_t valid_asm_custom_top;
/* AFE cal */
- struct acdb_atomic_cal_block afe_cal[MAX_AUDPROC_TYPES];
+ struct acdb_cal_block afe_cal[MAX_AUDPROC_TYPES];
/* Sidetone Cal */
- struct sidetone_atomic_cal sidetone_cal;
+ struct sidetone_cal sidetone_cal;
/* Allocation information */
struct ion_client *ion_client;
struct ion_handle *ion_handle;
- atomic_t map_handle;
- atomic64_t paddr;
- atomic64_t kvaddr;
- atomic64_t mem_len;
+ uint32_t map_handle;
+ uint64_t paddr;
+ uint64_t kvaddr;
+ uint64_t mem_len;
/* Speaker protection */
struct msm_spk_prot_cfg spk_prot_cfg;
@@ -106,62 +102,63 @@
};
static struct acdb_data acdb_data;
-static atomic_t usage_count;
uint32_t get_voice_rx_topology(void)
{
- return atomic_read(&acdb_data.voice_rx_topology);
+ return acdb_data.voice_rx_topology;
}
void store_voice_rx_topology(uint32_t topology)
{
- atomic_set(&acdb_data.voice_rx_topology, topology);
+ acdb_data.voice_rx_topology = topology;
}
uint32_t get_voice_tx_topology(void)
{
- return atomic_read(&acdb_data.voice_tx_topology);
+ return acdb_data.voice_tx_topology;
}
void store_voice_tx_topology(uint32_t topology)
{
- atomic_set(&acdb_data.voice_tx_topology, topology);
+ acdb_data.voice_tx_topology = topology;
}
uint32_t get_adm_rx_topology(void)
{
- return atomic_read(&acdb_data.adm_topology[RX_CAL]);
+ return acdb_data.adm_topology[RX_CAL];
}
void store_adm_rx_topology(uint32_t topology)
{
- atomic_set(&acdb_data.adm_topology[RX_CAL], topology);
+ acdb_data.adm_topology[RX_CAL] = topology;
}
uint32_t get_adm_tx_topology(void)
{
- return atomic_read(&acdb_data.adm_topology[TX_CAL]);
+ return acdb_data.adm_topology[TX_CAL];
}
void store_adm_tx_topology(uint32_t topology)
{
- atomic_set(&acdb_data.adm_topology[TX_CAL], topology);
+ acdb_data.adm_topology[TX_CAL] = topology;
}
uint32_t get_asm_topology(void)
{
- return atomic_read(&acdb_data.asm_topology);
+ return acdb_data.asm_topology;
}
void store_asm_topology(uint32_t topology)
{
- atomic_set(&acdb_data.asm_topology, topology);
+ acdb_data.asm_topology = topology;
}
void reset_custom_topology_flags(void)
{
- atomic_set(&acdb_data.valid_adm_custom_top, 1);
- atomic_set(&acdb_data.valid_asm_custom_top, 1);
+ mutex_lock(&acdb_data.acdb_mutex);
+ acdb_data.valid_adm_custom_top = 1;
+ acdb_data.valid_asm_custom_top = 1;
+ mutex_unlock(&acdb_data.acdb_mutex);
}
int get_adm_custom_topology(struct acdb_cal_block *cal_block)
@@ -175,19 +172,19 @@
goto done;
}
+ mutex_lock(&acdb_data.acdb_mutex);
/* Only return allow one access after memory registered */
- if (atomic_read(&acdb_data.valid_adm_custom_top) == 0) {
+ if (acdb_data.valid_adm_custom_top == 0) {
cal_block->cal_size = 0;
- goto done;
+ goto unlock;
}
- atomic_set(&acdb_data.valid_adm_custom_top, 0);
+ acdb_data.valid_adm_custom_top = 0;
- cal_block->cal_size =
- atomic_read(&acdb_data.adm_custom_topology.cal_size);
- cal_block->cal_paddr =
- atomic_read(&acdb_data.adm_custom_topology.cal_paddr);
- cal_block->cal_kvaddr =
- atomic_read(&acdb_data.adm_custom_topology.cal_kvaddr);
+ cal_block->cal_size = acdb_data.adm_custom_topology.cal_size;
+ cal_block->cal_paddr = acdb_data.adm_custom_topology.cal_paddr;
+ cal_block->cal_kvaddr = acdb_data.adm_custom_topology.cal_kvaddr;
+unlock:
+ mutex_unlock(&acdb_data.acdb_mutex);
done:
return result;
}
@@ -197,21 +194,18 @@
int result = 0;
pr_debug("%s,\n", __func__);
- if (cal_block->cal_offset > atomic64_read(&acdb_data.mem_len)) {
- pr_err("%s: offset %d is > mem_len %ld\n",
- __func__, cal_block->cal_offset,
- (long)atomic64_read(&acdb_data.mem_len));
+ if (cal_block->cal_offset > acdb_data.mem_len) {
+ pr_err("%s: offset %d is > mem_len %llu\n",
+ __func__, cal_block->cal_offset, acdb_data.mem_len);
result = -EINVAL;
goto done;
}
- atomic_set(&acdb_data.adm_custom_topology.cal_size,
- cal_block->cal_size);
- atomic_set(&acdb_data.adm_custom_topology.cal_paddr,
- cal_block->cal_offset + atomic64_read(&acdb_data.paddr));
- atomic_set(&acdb_data.adm_custom_topology.cal_kvaddr,
- cal_block->cal_offset +
- atomic64_read(&acdb_data.kvaddr));
+ acdb_data.adm_custom_topology.cal_size = cal_block->cal_size;
+ acdb_data.adm_custom_topology.cal_paddr =
+ cal_block->cal_offset + acdb_data.paddr;
+ acdb_data.adm_custom_topology.cal_kvaddr =
+ cal_block->cal_offset + acdb_data.kvaddr;
done:
return result;
}
@@ -227,19 +221,19 @@
goto done;
}
+ mutex_lock(&acdb_data.acdb_mutex);
/* Only return allow one access after memory registered */
- if (atomic_read(&acdb_data.valid_asm_custom_top) == 0) {
+ if (acdb_data.valid_asm_custom_top == 0) {
cal_block->cal_size = 0;
- goto done;
+ goto unlock;
}
- atomic_set(&acdb_data.valid_asm_custom_top, 0);
+ acdb_data.valid_asm_custom_top = 0;
- cal_block->cal_size =
- atomic_read(&acdb_data.asm_custom_topology.cal_size);
- cal_block->cal_paddr =
- atomic_read(&acdb_data.asm_custom_topology.cal_paddr);
- cal_block->cal_kvaddr =
- atomic_read(&acdb_data.asm_custom_topology.cal_kvaddr);
+ cal_block->cal_size = acdb_data.asm_custom_topology.cal_size;
+ cal_block->cal_paddr = acdb_data.asm_custom_topology.cal_paddr;
+ cal_block->cal_kvaddr = acdb_data.asm_custom_topology.cal_kvaddr;
+unlock:
+ mutex_unlock(&acdb_data.acdb_mutex);
done:
return result;
}
@@ -249,21 +243,18 @@
int result = 0;
pr_debug("%s,\n", __func__);
- if (cal_block->cal_offset > atomic64_read(&acdb_data.mem_len)) {
- pr_err("%s: offset %d is > mem_len %ld\n",
- __func__, cal_block->cal_offset,
- (long)atomic64_read(&acdb_data.mem_len));
+ if (cal_block->cal_offset > acdb_data.mem_len) {
+ pr_err("%s: offset %d is > mem_len %llu\n",
+ __func__, cal_block->cal_offset, acdb_data.mem_len);
result = -EINVAL;
goto done;
}
- atomic_set(&acdb_data.asm_custom_topology.cal_size,
- cal_block->cal_size);
- atomic_set(&acdb_data.asm_custom_topology.cal_paddr,
- cal_block->cal_offset + atomic64_read(&acdb_data.paddr));
- atomic_set(&acdb_data.asm_custom_topology.cal_kvaddr,
- cal_block->cal_offset +
- atomic64_read(&acdb_data.kvaddr));
+ acdb_data.asm_custom_topology.cal_size = cal_block->cal_size;
+ acdb_data.asm_custom_topology.cal_paddr =
+ cal_block->cal_offset + acdb_data.paddr;
+ acdb_data.asm_custom_topology.cal_kvaddr =
+ cal_block->cal_offset + acdb_data.kvaddr;
done:
return result;
}
@@ -280,10 +271,8 @@
}
cal_block->cal_size = ACDB_TOTAL_VOICE_ALLOCATION;
- cal_block->cal_paddr =
- atomic_read(&acdb_data.vocproc_cal.cal_paddr);
- cal_block->cal_kvaddr =
- atomic_read(&acdb_data.vocproc_cal.cal_kvaddr);
+ cal_block->cal_paddr = acdb_data.vocproc_cal.cal_paddr;
+ cal_block->cal_kvaddr = acdb_data.vocproc_cal.cal_kvaddr;
done:
return result;
}
@@ -299,12 +288,9 @@
goto done;
}
- cal_block->cal_size =
- atomic_read(&acdb_data.aanc_cal.cal_size);
- cal_block->cal_paddr =
- atomic_read(&acdb_data.aanc_cal.cal_paddr);
- cal_block->cal_kvaddr =
- atomic_read(&acdb_data.aanc_cal.cal_kvaddr);
+ cal_block->cal_size = acdb_data.aanc_cal.cal_size;
+ cal_block->cal_paddr = acdb_data.aanc_cal.cal_paddr;
+ cal_block->cal_kvaddr = acdb_data.aanc_cal.cal_kvaddr;
done:
return result;
}
@@ -314,20 +300,18 @@
int result = 0;
pr_debug("%s,\n", __func__);
- if (cal_block->cal_offset > atomic64_read(&acdb_data.mem_len)) {
- pr_err("%s: offset %d is > mem_len %ld\n",
- __func__, cal_block->cal_offset,
- (long)atomic64_read(&acdb_data.mem_len));
+ if (cal_block->cal_offset > acdb_data.mem_len) {
+ pr_err("%s: offset %d is > mem_len %llu\n",
+ __func__, cal_block->cal_offset, acdb_data.mem_len);
result = -EINVAL;
goto done;
}
- atomic_set(&acdb_data.aanc_cal.cal_size,
- cal_block->cal_size);
- atomic_set(&acdb_data.aanc_cal.cal_paddr,
- cal_block->cal_offset + atomic64_read(&acdb_data.paddr));
- atomic_set(&acdb_data.aanc_cal.cal_kvaddr,
- cal_block->cal_offset + atomic64_read(&acdb_data.kvaddr));
+ acdb_data.aanc_cal.cal_size = cal_block->cal_size;
+ acdb_data.aanc_cal.cal_paddr =
+ cal_block->cal_offset + acdb_data.paddr;
+ acdb_data.aanc_cal.cal_kvaddr =
+ cal_block->cal_offset + acdb_data.kvaddr;
done:
return result;
}
@@ -343,12 +327,9 @@
goto done;
}
- cal_block->cal_size =
- atomic_read(&acdb_data.lsm_cal.cal_size);
- cal_block->cal_paddr =
- atomic_read(&acdb_data.lsm_cal.cal_paddr);
- cal_block->cal_kvaddr =
- atomic_read(&acdb_data.lsm_cal.cal_kvaddr);
+ cal_block->cal_size = acdb_data.lsm_cal.cal_size;
+ cal_block->cal_paddr = acdb_data.lsm_cal.cal_paddr;
+ cal_block->cal_kvaddr = acdb_data.lsm_cal.cal_kvaddr;
done:
return result;
}
@@ -358,20 +339,18 @@
int result = 0;
pr_debug("%s,\n", __func__);
- if (cal_block->cal_offset > atomic64_read(&acdb_data.mem_len)) {
- pr_err("%s: offset %d is > mem_len %ld\n",
- __func__, cal_block->cal_offset,
- (long)atomic64_read(&acdb_data.mem_len));
+ if (cal_block->cal_offset > acdb_data.mem_len) {
+ pr_err("%s: offset %d is > mem_len %llu\n",
+ __func__, cal_block->cal_offset, acdb_data.mem_len);
result = -EINVAL;
goto done;
}
- atomic_set(&acdb_data.lsm_cal.cal_size,
- cal_block->cal_size);
- atomic_set(&acdb_data.lsm_cal.cal_paddr,
- cal_block->cal_offset + atomic64_read(&acdb_data.paddr));
- atomic_set(&acdb_data.lsm_cal.cal_kvaddr,
- cal_block->cal_offset + atomic64_read(&acdb_data.kvaddr));
+ acdb_data.lsm_cal.cal_size = cal_block->cal_size;
+ acdb_data.lsm_cal.cal_paddr =
+ cal_block->cal_offset + acdb_data.paddr;
+ acdb_data.lsm_cal.cal_kvaddr =
+ cal_block->cal_offset + acdb_data.kvaddr;
done:
return result;
}
@@ -470,7 +449,6 @@
pr_debug("ACDB=> %s : Path = %d num_entries = %d\n",
__func__, path, delay.num_entries);
- mutex_lock(&acdb_data.acdb_mutex);
if (path == RX_CAL)
delay_dest = &acdb_data.hw_delay_rx;
else if (path == TX_CAL)
@@ -487,7 +465,6 @@
__func__, result, path);
result = -EFAULT;
}
- mutex_unlock(&acdb_data.acdb_mutex);
done:
return result;
}
@@ -503,12 +480,9 @@
goto done;
}
- cal_block->cal_size =
- atomic_read(&acdb_data.anc_cal.cal_size);
- cal_block->cal_paddr =
- atomic_read(&acdb_data.anc_cal.cal_paddr);
- cal_block->cal_kvaddr =
- atomic_read(&acdb_data.anc_cal.cal_kvaddr);
+ cal_block->cal_size = acdb_data.anc_cal.cal_size;
+ cal_block->cal_paddr = acdb_data.anc_cal.cal_paddr;
+ cal_block->cal_kvaddr = acdb_data.anc_cal.cal_kvaddr;
done:
return result;
}
@@ -518,20 +492,18 @@
int result = 0;
pr_debug("%s,\n", __func__);
- if (cal_block->cal_offset > atomic64_read(&acdb_data.mem_len)) {
- pr_err("%s: offset %d is > mem_len %ld\n",
- __func__, cal_block->cal_offset,
- (long)atomic64_read(&acdb_data.mem_len));
+ if (cal_block->cal_offset > acdb_data.mem_len) {
+ pr_err("%s: offset %d is > mem_len %llu\n",
+ __func__, cal_block->cal_offset, acdb_data.mem_len);
result = -EINVAL;
goto done;
}
- atomic_set(&acdb_data.anc_cal.cal_size,
- cal_block->cal_size);
- atomic_set(&acdb_data.anc_cal.cal_paddr,
- cal_block->cal_offset + atomic64_read(&acdb_data.paddr));
- atomic_set(&acdb_data.anc_cal.cal_kvaddr,
- cal_block->cal_offset + atomic64_read(&acdb_data.kvaddr));
+ acdb_data.anc_cal.cal_size = cal_block->cal_size;
+ acdb_data.anc_cal.cal_paddr =
+ cal_block->cal_offset + acdb_data.paddr;
+ acdb_data.anc_cal.cal_kvaddr =
+ cal_block->cal_offset + acdb_data.kvaddr;
done:
return result;
}
@@ -541,10 +513,9 @@
int result = 0;
pr_debug("%s, path = %d\n", __func__, path);
- if (cal_block->cal_offset > atomic64_read(&acdb_data.mem_len)) {
- pr_err("%s: offset %d is > mem_len %ld\n",
- __func__, cal_block->cal_offset,
- (long)atomic64_read(&acdb_data.mem_len));
+ if (cal_block->cal_offset > acdb_data.mem_len) {
+ pr_err("%s: offset %d is > mem_len %llu\n",
+ __func__, cal_block->cal_offset, acdb_data.mem_len);
result = -EINVAL;
goto done;
}
@@ -555,12 +526,11 @@
goto done;
}
- atomic_set(&acdb_data.afe_cal[path].cal_size,
- cal_block->cal_size);
- atomic_set(&acdb_data.afe_cal[path].cal_paddr,
- cal_block->cal_offset + atomic64_read(&acdb_data.paddr));
- atomic_set(&acdb_data.afe_cal[path].cal_kvaddr,
- cal_block->cal_offset + atomic64_read(&acdb_data.kvaddr));
+ acdb_data.afe_cal[path].cal_size = cal_block->cal_size;
+ acdb_data.afe_cal[path].cal_paddr =
+ cal_block->cal_offset + acdb_data.paddr;
+ acdb_data.afe_cal[path].cal_kvaddr =
+ cal_block->cal_offset + acdb_data.kvaddr;
done:
return result;
}
@@ -582,12 +552,9 @@
goto done;
}
- cal_block->cal_size =
- atomic_read(&acdb_data.afe_cal[path].cal_size);
- cal_block->cal_paddr =
- atomic_read(&acdb_data.afe_cal[path].cal_paddr);
- cal_block->cal_kvaddr =
- atomic_read(&acdb_data.afe_cal[path].cal_kvaddr);
+ cal_block->cal_size = acdb_data.afe_cal[path].cal_size;
+ cal_block->cal_paddr = acdb_data.afe_cal[path].cal_paddr;
+ cal_block->cal_kvaddr = acdb_data.afe_cal[path].cal_kvaddr;
done:
return result;
}
@@ -597,10 +564,9 @@
int result = 0;
pr_debug("%s, path = %d\n", __func__, path);
- if (cal_block->cal_offset > atomic64_read(&acdb_data.mem_len)) {
- pr_err("%s: offset %d is > mem_len %ld\n",
- __func__, cal_block->cal_offset,
- (long)atomic64_read(&acdb_data.mem_len));
+ if (cal_block->cal_offset > acdb_data.mem_len) {
+ pr_err("%s: offset %d is > mem_len %llu\n",
+ __func__, cal_block->cal_offset, acdb_data.mem_len);
result = -EINVAL;
goto done;
}
@@ -611,12 +577,11 @@
goto done;
}
- atomic_set(&acdb_data.audproc_cal[path].cal_size,
- cal_block->cal_size);
- atomic_set(&acdb_data.audproc_cal[path].cal_paddr,
- cal_block->cal_offset + atomic64_read(&acdb_data.paddr));
- atomic_set(&acdb_data.audproc_cal[path].cal_kvaddr,
- cal_block->cal_offset + atomic64_read(&acdb_data.kvaddr));
+ acdb_data.audproc_cal[path].cal_size = cal_block->cal_size;
+ acdb_data.audproc_cal[path].cal_paddr =
+ cal_block->cal_offset + acdb_data.paddr;
+ acdb_data.audproc_cal[path].cal_kvaddr =
+ cal_block->cal_offset + acdb_data.kvaddr;
done:
return result;
}
@@ -638,12 +603,9 @@
goto done;
}
- cal_block->cal_size =
- atomic_read(&acdb_data.audproc_cal[path].cal_size);
- cal_block->cal_paddr =
- atomic_read(&acdb_data.audproc_cal[path].cal_paddr);
- cal_block->cal_kvaddr =
- atomic_read(&acdb_data.audproc_cal[path].cal_kvaddr);
+ cal_block->cal_size = acdb_data.audproc_cal[path].cal_size;
+ cal_block->cal_paddr = acdb_data.audproc_cal[path].cal_paddr;
+ cal_block->cal_kvaddr = acdb_data.audproc_cal[path].cal_kvaddr;
done:
return result;
}
@@ -653,10 +615,9 @@
int result = 0;
pr_debug("%s, path = %d\n", __func__, path);
- if (cal_block->cal_offset > atomic64_read(&acdb_data.mem_len)) {
- pr_err("%s: offset %d is > mem_len %ld\n",
- __func__, cal_block->cal_offset,
- (long)atomic64_read(&acdb_data.mem_len));
+ if (cal_block->cal_offset > acdb_data.mem_len) {
+ pr_err("%s: offset %d is > mem_len %llu\n",
+ __func__, cal_block->cal_offset, acdb_data.mem_len);
result = -EINVAL;
goto done;
}
@@ -667,12 +628,11 @@
goto done;
}
- atomic_set(&acdb_data.audstrm_cal[path].cal_size,
- cal_block->cal_size);
- atomic_set(&acdb_data.audstrm_cal[path].cal_paddr,
- cal_block->cal_offset + atomic64_read(&acdb_data.paddr));
- atomic_set(&acdb_data.audstrm_cal[path].cal_kvaddr,
- cal_block->cal_offset + atomic64_read(&acdb_data.kvaddr));
+ acdb_data.audstrm_cal[path].cal_size = cal_block->cal_size;
+ acdb_data.audstrm_cal[path].cal_paddr =
+ cal_block->cal_offset + acdb_data.paddr;
+ acdb_data.audstrm_cal[path].cal_kvaddr =
+ cal_block->cal_offset + acdb_data.kvaddr;
done:
return result;
}
@@ -694,12 +654,9 @@
goto done;
}
- cal_block->cal_size =
- atomic_read(&acdb_data.audstrm_cal[path].cal_size);
- cal_block->cal_paddr =
- atomic_read(&acdb_data.audstrm_cal[path].cal_paddr);
- cal_block->cal_kvaddr =
- atomic_read(&acdb_data.audstrm_cal[path].cal_kvaddr);
+ cal_block->cal_size = acdb_data.audstrm_cal[path].cal_size;
+ cal_block->cal_paddr = acdb_data.audstrm_cal[path].cal_paddr;
+ cal_block->cal_kvaddr = acdb_data.audstrm_cal[path].cal_kvaddr;
done:
return result;
}
@@ -709,10 +666,9 @@
int result = 0;
pr_debug("%s, path = %d\n", __func__, path);
- if (cal_block->cal_offset > atomic64_read(&acdb_data.mem_len)) {
- pr_err("%s: offset %d is > mem_len %ld\n",
- __func__, cal_block->cal_offset,
- (long)atomic64_read(&acdb_data.mem_len));
+ if (cal_block->cal_offset > acdb_data.mem_len) {
+ pr_err("%s: offset %d is > mem_len %llu\n",
+ __func__, cal_block->cal_offset, acdb_data.mem_len);
result = -EINVAL;
goto done;
}
@@ -723,12 +679,11 @@
goto done;
}
- atomic_set(&acdb_data.audvol_cal[path].cal_size,
- cal_block->cal_size);
- atomic_set(&acdb_data.audvol_cal[path].cal_paddr,
- cal_block->cal_offset + atomic64_read(&acdb_data.paddr));
- atomic_set(&acdb_data.audvol_cal[path].cal_kvaddr,
- cal_block->cal_offset + atomic64_read(&acdb_data.kvaddr));
+ acdb_data.audvol_cal[path].cal_size = cal_block->cal_size;
+ acdb_data.audvol_cal[path].cal_paddr =
+ cal_block->cal_offset + acdb_data.paddr;
+ acdb_data.audvol_cal[path].cal_kvaddr =
+ cal_block->cal_offset + acdb_data.kvaddr;
done:
return result;
}
@@ -750,12 +705,9 @@
goto done;
}
- cal_block->cal_size =
- atomic_read(&acdb_data.audvol_cal[path].cal_size);
- cal_block->cal_paddr =
- atomic_read(&acdb_data.audvol_cal[path].cal_paddr);
- cal_block->cal_kvaddr =
- atomic_read(&acdb_data.audvol_cal[path].cal_kvaddr);
+ cal_block->cal_size = acdb_data.audvol_cal[path].cal_size;
+ cal_block->cal_paddr = acdb_data.audvol_cal[path].cal_paddr;
+ cal_block->cal_kvaddr = acdb_data.audvol_cal[path].cal_kvaddr;
done:
return result;
}
@@ -767,21 +719,18 @@
pr_debug("%s,\n", __func__);
if (cal_size > MAX_COL_SIZE) {
- pr_err("%s: col size is to big %d\n", __func__,
- cal_size);
+ pr_err("%s: col size is to big %d\n", __func__, cal_size);
result = -EINVAL;
goto done;
}
if (copy_from_user(acdb_data.col_data[vocproc_type],
(void *)((uint8_t *)cal_block + sizeof(cal_size)),
cal_size)) {
- pr_err("%s: fail to copy col size %d\n",
- __func__, cal_size);
+ pr_err("%s: fail to copy col size %d\n", __func__, cal_size);
result = -EINVAL;
goto done;
}
- atomic_set(&acdb_data.vocproc_col_cal[vocproc_type].cal_size,
- cal_size);
+ acdb_data.vocproc_col_cal[vocproc_type].cal_size = cal_size;
done:
return result;
}
@@ -798,12 +747,12 @@
goto done;
}
- cal_block->cal_size = atomic_read(&acdb_data.
- vocproc_col_cal[vocproc_type].cal_size);
- cal_block->cal_paddr = atomic_read(&acdb_data.
- vocproc_col_cal[vocproc_type].cal_paddr);
- cal_block->cal_kvaddr = atomic_read(&acdb_data.
- vocproc_col_cal[vocproc_type].cal_kvaddr);
+ cal_block->cal_size = acdb_data.
+ vocproc_col_cal[vocproc_type].cal_size;
+ cal_block->cal_paddr = acdb_data.
+ vocproc_col_cal[vocproc_type].cal_paddr;
+ cal_block->cal_kvaddr = acdb_data.
+ vocproc_col_cal[vocproc_type].cal_kvaddr;
done:
return result;
}
@@ -815,24 +764,19 @@
if (cal_block->cal_offset >
- atomic64_read(&acdb_data.mem_len)) {
- pr_err("%s: offset %d is > mem_len %ld\n",
- __func__, cal_block->cal_offset,
- (long)atomic64_read(&acdb_data.mem_len));
- atomic_set(&acdb_data.vocproc_dev_cal.cal_size, 0);
+ acdb_data.mem_len) {
+ pr_err("%s: offset %d is > mem_len %llu\n",
+ __func__, cal_block->cal_offset, acdb_data.mem_len);
+ acdb_data.vocproc_dev_cal.cal_size = 0;
result = -EINVAL;
goto done;
}
- atomic_set(&acdb_data.vocproc_dev_cal.cal_size,
- cal_block->cal_size);
- atomic_set(&acdb_data.vocproc_dev_cal.cal_paddr,
- cal_block->cal_offset +
- atomic64_read(&acdb_data.paddr));
- atomic_set(&acdb_data.vocproc_dev_cal.cal_kvaddr,
- cal_block->cal_offset +
- atomic64_read(&acdb_data.kvaddr));
-
+ acdb_data.vocproc_dev_cal.cal_size = cal_block->cal_size;
+ acdb_data.vocproc_dev_cal.cal_paddr =
+ cal_block->cal_offset + acdb_data.paddr;
+ acdb_data.vocproc_dev_cal.cal_kvaddr =
+ cal_block->cal_offset + acdb_data.kvaddr;
done:
return result;
}
@@ -848,12 +792,9 @@
goto done;
}
- cal_block->cal_size =
- atomic_read(&acdb_data.vocproc_dev_cal.cal_size);
- cal_block->cal_paddr =
- atomic_read(&acdb_data.vocproc_dev_cal.cal_paddr);
- cal_block->cal_kvaddr =
- atomic_read(&acdb_data.vocproc_dev_cal.cal_kvaddr);
+ cal_block->cal_size = acdb_data.vocproc_dev_cal.cal_size;
+ cal_block->cal_paddr = acdb_data.vocproc_dev_cal.cal_paddr;
+ cal_block->cal_kvaddr = acdb_data.vocproc_dev_cal.cal_kvaddr;
done:
return result;
}
@@ -866,24 +807,19 @@
pr_debug("%s,\n", __func__);
if (cal_block->cal_offset >
- atomic64_read(&acdb_data.mem_len)) {
- pr_err("%s: offset %d is > mem_len %ld\n",
- __func__, cal_block->cal_offset,
- (long)atomic64_read(&acdb_data.mem_len));
- atomic_set(&acdb_data.vocproc_cal.cal_size, 0);
+ acdb_data.mem_len) {
+ pr_err("%s: offset %d is > mem_len %llu\n",
+ __func__, cal_block->cal_offset, acdb_data.mem_len);
+ acdb_data.vocproc_cal.cal_size = 0;
result = -EINVAL;
goto done;
}
- atomic_set(&acdb_data.vocproc_cal.cal_size,
- cal_block->cal_size);
- atomic_set(&acdb_data.vocproc_cal.cal_paddr,
- cal_block->cal_offset +
- atomic64_read(&acdb_data.paddr));
- atomic_set(&acdb_data.vocproc_cal.cal_kvaddr,
- cal_block->cal_offset +
- atomic64_read(&acdb_data.kvaddr));
-
+ acdb_data.vocproc_cal.cal_size = cal_block->cal_size;
+ acdb_data.vocproc_cal.cal_paddr =
+ cal_block->cal_offset + acdb_data.paddr;
+ acdb_data.vocproc_cal.cal_kvaddr =
+ cal_block->cal_offset + acdb_data.kvaddr;
done:
return result;
}
@@ -899,12 +835,9 @@
goto done;
}
- cal_block->cal_size =
- atomic_read(&acdb_data.vocproc_cal.cal_size);
- cal_block->cal_paddr =
- atomic_read(&acdb_data.vocproc_cal.cal_paddr);
- cal_block->cal_kvaddr =
- atomic_read(&acdb_data.vocproc_cal.cal_kvaddr);
+ cal_block->cal_size = acdb_data.vocproc_cal.cal_size;
+ cal_block->cal_paddr = acdb_data.vocproc_cal.cal_paddr;
+ cal_block->cal_kvaddr = acdb_data.vocproc_cal.cal_kvaddr;
done:
return result;
}
@@ -915,24 +848,19 @@
pr_debug("%s,\n", __func__);
if (cal_block->cal_offset >
- atomic64_read(&acdb_data.mem_len)) {
- pr_err("%s: offset %d is > mem_len %ld\n",
- __func__, cal_block->cal_offset,
- (long)atomic64_read(&acdb_data.mem_len));
- atomic_set(&acdb_data.vocstrm_cal.cal_size, 0);
+ acdb_data.mem_len) {
+ pr_err("%s: offset %d is > mem_len %llu\n",
+ __func__, cal_block->cal_offset, acdb_data.mem_len);
+ acdb_data.vocstrm_cal.cal_size = 0;
result = -EINVAL;
goto done;
}
- atomic_set(&acdb_data.vocstrm_cal.cal_size,
- cal_block->cal_size);
- atomic_set(&acdb_data.vocstrm_cal.cal_paddr,
- cal_block->cal_offset +
- atomic64_read(&acdb_data.paddr));
- atomic_set(&acdb_data.vocstrm_cal.cal_kvaddr,
- cal_block->cal_offset +
- atomic64_read(&acdb_data.kvaddr));
-
+ acdb_data.vocstrm_cal.cal_size = cal_block->cal_size;
+ acdb_data.vocstrm_cal.cal_paddr =
+ cal_block->cal_offset + acdb_data.paddr;
+ acdb_data.vocstrm_cal.cal_kvaddr =
+ cal_block->cal_offset + acdb_data.kvaddr;
done:
return result;
}
@@ -948,12 +876,9 @@
goto done;
}
- cal_block->cal_size =
- atomic_read(&acdb_data.vocstrm_cal.cal_size);
- cal_block->cal_paddr =
- atomic_read(&acdb_data.vocstrm_cal.cal_paddr);
- cal_block->cal_kvaddr =
- atomic_read(&acdb_data.vocstrm_cal.cal_kvaddr);
+ cal_block->cal_size = acdb_data.vocstrm_cal.cal_size;
+ cal_block->cal_paddr = acdb_data.vocstrm_cal.cal_paddr;
+ cal_block->cal_kvaddr = acdb_data.vocstrm_cal.cal_kvaddr;
done:
return result;
}
@@ -963,25 +888,19 @@
int result = 0;
pr_debug("%s,\n", __func__);
- if (cal_block->cal_offset >
- atomic64_read(&acdb_data.mem_len)) {
- pr_err("%s: offset %d is > mem_len %ld\n",
- __func__, cal_block->cal_offset,
- (long)atomic64_read(&acdb_data.mem_len));
- atomic_set(&acdb_data.vocvol_cal.cal_size, 0);
+ if (cal_block->cal_offset > acdb_data.mem_len) {
+ pr_err("%s: offset %d is > mem_len %llu\n",
+ __func__, cal_block->cal_offset, acdb_data.mem_len);
+ acdb_data.vocvol_cal.cal_size = 0;
result = -EINVAL;
goto done;
}
- atomic_set(&acdb_data.vocvol_cal.cal_size,
- cal_block->cal_size);
- atomic_set(&acdb_data.vocvol_cal.cal_paddr,
- cal_block->cal_offset +
- atomic64_read(&acdb_data.paddr));
- atomic_set(&acdb_data.vocvol_cal.cal_kvaddr,
- cal_block->cal_offset +
- atomic64_read(&acdb_data.kvaddr));
-
+ acdb_data.vocvol_cal.cal_size = cal_block->cal_size;
+ acdb_data.vocvol_cal.cal_paddr =
+ cal_block->cal_offset + acdb_data.paddr;
+ acdb_data.vocvol_cal.cal_kvaddr =
+ cal_block->cal_offset + acdb_data.kvaddr;
done:
return result;
}
@@ -997,12 +916,9 @@
goto done;
}
- cal_block->cal_size =
- atomic_read(&acdb_data.vocvol_cal.cal_size);
- cal_block->cal_paddr =
- atomic_read(&acdb_data.vocvol_cal.cal_paddr);
- cal_block->cal_kvaddr =
- atomic_read(&acdb_data.vocvol_cal.cal_kvaddr);
+ cal_block->cal_size = acdb_data.vocvol_cal.cal_size;
+ cal_block->cal_paddr = acdb_data.vocvol_cal.cal_paddr;
+ cal_block->cal_kvaddr = acdb_data.vocvol_cal.cal_kvaddr;
done:
return result;
}
@@ -1011,8 +927,8 @@
{
pr_debug("%s,\n", __func__);
- atomic_set(&acdb_data.sidetone_cal.enable, cal_data->enable);
- atomic_set(&acdb_data.sidetone_cal.gain, cal_data->gain);
+ acdb_data.sidetone_cal.enable = cal_data->enable;
+ acdb_data.sidetone_cal.gain = cal_data->gain;
}
int get_sidetone_cal(struct sidetone_cal *cal_data)
@@ -1026,8 +942,10 @@
goto done;
}
- cal_data->enable = atomic_read(&acdb_data.sidetone_cal.enable);
- cal_data->gain = atomic_read(&acdb_data.sidetone_cal.gain);
+ mutex_lock(&acdb_data.acdb_mutex);
+ cal_data->enable = acdb_data.sidetone_cal.enable;
+ cal_data->gain = acdb_data.sidetone_cal.gain;
+ mutex_unlock(&acdb_data.acdb_mutex);
done:
return result;
}
@@ -1111,14 +1029,15 @@
s32 result = 0;
pr_debug("%s\n", __func__);
- if (atomic64_read(&acdb_data.mem_len)) {
+ mutex_lock(&acdb_data.acdb_mutex);
+ if (acdb_data.mem_len)
pr_debug("%s: ACDB opened but memory allocated, using existing allocation!\n",
__func__);
- }
- atomic_set(&acdb_data.valid_adm_custom_top, 1);
- atomic_set(&acdb_data.valid_asm_custom_top, 1);
- atomic_inc(&usage_count);
+ acdb_data.valid_adm_custom_top = 1;
+ acdb_data.valid_asm_custom_top = 1;
+ acdb_data.usage_count++;
+ mutex_unlock(&acdb_data.acdb_mutex);
return result;
}
@@ -1195,30 +1114,31 @@
int i;
pr_debug("%s\n", __func__);
- mutex_lock(&acdb_data.acdb_mutex);
+ if (acdb_data.mem_len == 0)
+ goto done;
+
+ pr_debug("Remove existing memory\n");
+ acdb_data.mem_len = 0;
+
+ /* unmap all cal data */
+ result = unmap_cal_tables();
+ if (result < 0)
+ pr_err("%s: unmap_cal_tables failed, err = %d\n",
+ __func__, result);
+
+ msm_audio_ion_free(acdb_data.ion_client, acdb_data.ion_handle);
+ acdb_data.ion_client = NULL;
+ acdb_data.ion_handle = NULL;
+
+ for (i = 0; i < MAX_VOCPROC_TYPES; i++) {
+ kfree(acdb_data.col_data[i]);
+ acdb_data.col_data[i] = NULL;
+ }
+
kfree(acdb_data.hw_delay_tx.delay_info);
kfree(acdb_data.hw_delay_rx.delay_info);
-
- if (atomic64_read(&acdb_data.mem_len)) {
- /* unmap all cal data */
- result = unmap_cal_tables();
- if (result < 0)
- pr_err("%s: unmap_cal_tables failed, err = %d\n",
- __func__, result);
-
- atomic64_set(&acdb_data.mem_len, 0);
-
- for (i = 0; i < MAX_VOCPROC_TYPES; i++) {
- kfree(acdb_data.col_data[i]);
- acdb_data.col_data[i] = NULL;
- }
- msm_audio_ion_free(acdb_data.ion_client, acdb_data.ion_handle);
- acdb_data.ion_client = NULL;
- acdb_data.ion_handle = NULL;
- mutex_unlock(&acdb_data.acdb_mutex);
- }
- mutex_unlock(&acdb_data.acdb_mutex);
- return 0;
+done:
+ return result;
}
static int register_memory(void)
@@ -1231,42 +1151,38 @@
unsigned long mem_len;
pr_debug("%s\n", __func__);
- mutex_lock(&acdb_data.acdb_mutex);
- allocate_hw_delay_entries();
- for (i = 0; i < MAX_VOCPROC_TYPES; i++) {
- acdb_data.col_data[i] = kmalloc(MAX_COL_SIZE, GFP_KERNEL);
- atomic_set(&acdb_data.vocproc_col_cal[i].cal_kvaddr,
- (uint32_t)acdb_data.col_data[i]);
- }
-
result = msm_audio_ion_import("audio_acdb_client",
&acdb_data.ion_client,
&acdb_data.ion_handle,
- atomic_read(&acdb_data.map_handle),
+ acdb_data.map_handle,
NULL, 0,
&paddr, (size_t *)&mem_len, &kvptr);
if (result) {
pr_err("%s: audio ION alloc failed, rc = %d\n",
__func__, result);
- result = PTR_ERR(acdb_data.ion_client);
goto err_ion_handle;
}
- kvaddr = (unsigned long)kvptr;
- atomic64_set(&acdb_data.paddr, paddr);
- atomic64_set(&acdb_data.kvaddr, kvaddr);
- atomic64_set(&acdb_data.mem_len, mem_len);
- mutex_unlock(&acdb_data.acdb_mutex);
- pr_debug("%s done! paddr = 0x%lx, kvaddr = 0x%lx, len = x%lx\n",
- __func__,
- (long)atomic64_read(&acdb_data.paddr),
- (long)atomic64_read(&acdb_data.kvaddr),
- (long)atomic64_read(&acdb_data.mem_len));
+ allocate_hw_delay_entries();
+
+ for (i = 0; i < MAX_VOCPROC_TYPES; i++) {
+ acdb_data.col_data[i] = kmalloc(MAX_COL_SIZE, GFP_KERNEL);
+ acdb_data.vocproc_col_cal[i].cal_kvaddr =
+ (uint32_t)acdb_data.col_data[i];
+ }
+
+ kvaddr = (unsigned long)kvptr;
+ acdb_data.paddr = paddr;
+ acdb_data.kvaddr = kvaddr;
+ acdb_data.mem_len = mem_len;
+
+ pr_debug("%s done! paddr = 0x%llx, kvaddr = 0x%llx, len = 0x%llx\n",
+ __func__, acdb_data.paddr, acdb_data.kvaddr,
+ acdb_data.mem_len);
return result;
err_ion_handle:
- atomic64_set(&acdb_data.mem_len, 0);
- mutex_unlock(&acdb_data.acdb_mutex);
+ acdb_data.mem_len = 0;
return result;
}
static long acdb_ioctl(struct file *f,
@@ -1281,26 +1197,26 @@
struct msm_spk_prot_status acdb_spk_status;
pr_debug("%s\n", __func__);
+ mutex_lock(&acdb_data.acdb_mutex);
switch (cmd) {
case AUDIO_REGISTER_PMEM:
pr_debug("AUDIO_REGISTER_PMEM\n");
- if (atomic_read(&acdb_data.mem_len)) {
- deregister_memory();
- pr_debug("Remove the existing memory\n");
- }
+ result = deregister_memory();
+ if (result < 0)
+ pr_err("%s: deregister_memory failed returned %d!\n",
+ __func__, result);
if (copy_from_user(&map_fd, (void *)arg, sizeof(map_fd))) {
pr_err("%s: fail to copy memory handle!\n", __func__);
result = -EFAULT;
} else {
- atomic_set(&acdb_data.map_handle, map_fd);
+ acdb_data.map_handle = map_fd;
result = register_memory();
}
goto done;
-
case AUDIO_DEREGISTER_PMEM:
pr_debug("AUDIO_DEREGISTER_PMEM\n");
- deregister_memory();
+ result = deregister_memory();
goto done;
case AUDIO_SET_VOICE_RX_TOPOLOGY:
if (copy_from_user(&topology, (void *)arg,
@@ -1343,16 +1259,13 @@
store_asm_topology(topology);
goto done;
case AUDIO_SET_SPEAKER_PROT:
- mutex_lock(&acdb_data.acdb_mutex);
if (copy_from_user(&acdb_data.spk_prot_cfg, (void *)arg,
sizeof(acdb_data.spk_prot_cfg))) {
pr_err("%s fail to copy spk_prot_cfg\n", __func__);
result = -EFAULT;
}
- mutex_unlock(&acdb_data.acdb_mutex);
goto done;
case AUDIO_GET_SPEAKER_PROT:
- mutex_lock(&acdb_data.acdb_mutex);
/*Indicates calibration was succesfull*/
if (acdb_data.spk_prot_cfg.mode == MSM_SPKR_PROT_CALIBRATED) {
prot_status.r0 = acdb_data.spk_prot_cfg.r0;
@@ -1379,7 +1292,6 @@
sizeof(prot_status))) {
pr_err("%s: Failed to update prot_status\n", __func__);
}
- mutex_unlock(&acdb_data.acdb_mutex);
goto done;
case AUDIO_REGISTER_VOCPROC_VOL_TABLE:
result = register_vocvol_table();
@@ -1502,23 +1414,25 @@
}
done:
+ mutex_unlock(&acdb_data.acdb_mutex);
return result;
}
static int acdb_mmap(struct file *file, struct vm_area_struct *vma)
{
int result = 0;
- uint32_t size = vma->vm_end - vma->vm_start;
+ size_t size = vma->vm_end - vma->vm_start;
pr_debug("%s\n", __func__);
- if (atomic64_read(&acdb_data.mem_len)) {
- if (size <= atomic64_read(&acdb_data.mem_len)) {
+ mutex_lock(&acdb_data.acdb_mutex);
+ if (acdb_data.mem_len) {
+ if (size <= acdb_data.mem_len) {
vma->vm_page_prot = pgprot_noncached(
vma->vm_page_prot);
result = remap_pfn_range(vma,
vma->vm_start,
- atomic64_read(&acdb_data.paddr) >> PAGE_SHIFT,
+ acdb_data.paddr >> PAGE_SHIFT,
size,
vma->vm_page_prot);
} else {
@@ -1529,25 +1443,29 @@
pr_err("%s: memory is not allocated, yet!\n", __func__);
result = -ENODEV;
}
+ mutex_unlock(&acdb_data.acdb_mutex);
return result;
}
static int acdb_release(struct inode *inode, struct file *f)
{
- s32 result = 0;
+ int result = 0;
+ pr_debug("%s\n", __func__);
- atomic_dec(&usage_count);
- atomic_read(&usage_count);
+ mutex_lock(&acdb_data.acdb_mutex);
+ acdb_data.usage_count--;
- pr_debug("%s: ref count %d!\n", __func__,
- atomic_read(&usage_count));
+ pr_debug("%s: ref count %d!\n", __func__, acdb_data.usage_count);
- if (atomic_read(&usage_count) >= 1)
+ if (acdb_data.usage_count > 0) {
result = -EBUSY;
- else
- result = deregister_memory();
+ goto done;
+ }
+ result = deregister_memory();
+done:
+ mutex_unlock(&acdb_data.acdb_mutex);
return result;
}
@@ -1571,9 +1489,9 @@
/*Speaker protection disabled*/
acdb_data.spk_prot_cfg.mode = MSM_SPKR_PROT_DISABLED;
mutex_init(&acdb_data.acdb_mutex);
- atomic_set(&usage_count, 0);
- atomic_set(&acdb_data.valid_adm_custom_top, 1);
- atomic_set(&acdb_data.valid_asm_custom_top, 1);
+ acdb_data.usage_count = 0;
+ acdb_data.valid_adm_custom_top = 1;
+ acdb_data.valid_asm_custom_top = 1;
return misc_register(&acdb_misc);
}
diff --git a/sound/soc/msm/qdsp6v2/audio_acdb.h b/sound/soc/msm/qdsp6v2/audio_acdb.h
index e2ca395..45a83f6 100644
--- a/sound/soc/msm/qdsp6v2/audio_acdb.h
+++ b/sound/soc/msm/qdsp6v2/audio_acdb.h
@@ -35,12 +35,6 @@
uint32_t cal_paddr;
};
-struct acdb_atomic_cal_block {
- atomic_t cal_size;
- atomic_t cal_kvaddr;
- atomic_t cal_paddr;
-};
-
struct hw_delay_entry {
uint32_t sample_rate;
uint32_t delay_usec;
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.c
index d80ca19..0612805 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.c
@@ -40,8 +40,8 @@
#define MIN_CAPTURE_PERIOD_SIZE (128 * 2 * 4)
#define MAX_CAPTURE_PERIOD_SIZE (128 * 2 * 2 * 6 * 4)
-#define MIN_CAPTURE_NUM_PERIODS (32)
-#define MAX_CAPTURE_NUM_PERIODS (384)
+#define MIN_CAPTURE_NUM_PERIODS (32 * 4)
+#define MAX_CAPTURE_NUM_PERIODS (384 * 4)
static struct snd_pcm_hardware msm_afe_hardware_playback = {
.info = (SNDRV_PCM_INFO_MMAP |
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c
index 11326f6..6f3f8ec 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c
@@ -396,6 +396,18 @@
ret);
}
}
+ ret = snd_pcm_hw_constraint_step(runtime, 0,
+ SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 32);
+ if (ret < 0) {
+ pr_err("constraint for period bytes step ret = %d\n",
+ ret);
+ }
+ ret = snd_pcm_hw_constraint_step(runtime, 0,
+ SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 32);
+ if (ret < 0) {
+ pr_err("constraint for buffer bytes step ret = %d\n",
+ ret);
+ }
prtd->dsp_cnt = 0;
prtd->set_channel_map = false;
diff --git a/sound/soc/msm/qdsp6v2/q6adm.c b/sound/soc/msm/qdsp6v2/q6adm.c
index 27c74ce..3ee6f6e 100644
--- a/sound/soc/msm/qdsp6v2/q6adm.c
+++ b/sound/soc/msm/qdsp6v2/q6adm.c
@@ -1144,8 +1144,8 @@
open.dev_channel_mapping[1] = PCM_CHANNEL_FR;
} else if (channel_mode == 3) {
open.dev_channel_mapping[0] = PCM_CHANNEL_FL;
- open.dev_channel_mapping[0] = PCM_CHANNEL_FR;
- open.dev_channel_mapping[1] = PCM_CHANNEL_FC;
+ open.dev_channel_mapping[1] = PCM_CHANNEL_FR;
+ open.dev_channel_mapping[2] = PCM_CHANNEL_FC;
} else if (channel_mode == 4) {
open.dev_channel_mapping[0] = PCM_CHANNEL_FL;
open.dev_channel_mapping[1] = PCM_CHANNEL_FR;