Merge "msm: lpm_levels: Perform system_unprepare only system low power mode"
diff --git a/Documentation/devicetree/bindings/arm/msm/cpr-regulator.txt b/Documentation/devicetree/bindings/arm/msm/cpr-regulator.txt
index 53b0d1a..40abc5f 100644
--- a/Documentation/devicetree/bindings/arm/msm/cpr-regulator.txt
+++ b/Documentation/devicetree/bindings/arm/msm/cpr-regulator.txt
@@ -213,10 +213,14 @@
the virtual corner value. For example, the first element in the list is the fuse corner
value that virtual corner 1 maps to.
This is required if qcom,cpr-quot-adjust-table is present.
-- qcom,cpr-quotient-adjustment: Present: CPR adjusts quotient value. The
- adjustment equals to the quotient adjustment
- in millivolts multiply the KV value.
- Not Present: CPR will not adjust quotient value.
+- qcom,cpr-quotient-adjustment: Array of three elements of CPR quotient adjustments for each corner.
+ The 3 quotient adjustments with index[0..2] are:
+ [0] => amount to add to the SVS quotient
+ [1] => amount to add to the NORM quotient
+ [2] => amount to add to the TURBO quotient
+ If this property is specified, then the quotient adjustment values are added to the target
+ quotient values read from fuses before writing them into the CPR GCNT target control registers.
+ This property can be used to add static margin to the voltage rail managed by the CPR controller.
- vdd-apc-optional-prim-supply: Present: Regulator of highest priority to supply VDD APC power
Not Present: No such regulator.
- vdd-apc-optional-sec-supply: Present: Regulator of second highest priority to supply VDD APC power.
diff --git a/Documentation/devicetree/bindings/arm/msm/rpm-regulator-smd.txt b/Documentation/devicetree/bindings/arm/msm/rpm-regulator-smd.txt
index 3d70a9b..2b25fcb 100644
--- a/Documentation/devicetree/bindings/arm/msm/rpm-regulator-smd.txt
+++ b/Documentation/devicetree/bindings/arm/msm/rpm-regulator-smd.txt
@@ -32,6 +32,10 @@
- qcom,enable-time: Time in us to delay after enabling the regulator
- qcom,hpm-min-load: Load current in uA which corresponds to the minimum load
which requires the regulator to be in high power mode.
+- qcom,apps-only: Flag which indicates that the regulator only has
+ consumers on the application processor. If this flag
+ is specified, then voltage and current updates are
+ only sent to the RPM if the regulator is enabled.
[Second Level Nodes]
@@ -84,6 +88,7 @@
current updates are only sent if the given
regulator has also been enabled by a Linux
consumer.
+
The following properties specify initial values for parameters to be sent to the
RPM in regulator requests.
- qcom,init-enable: 0 = regulator disabled
diff --git a/Documentation/devicetree/bindings/fb/mdss-mdp.txt b/Documentation/devicetree/bindings/fb/mdss-mdp.txt
index f8c4879..c2b963f 100644
--- a/Documentation/devicetree/bindings/fb/mdss-mdp.txt
+++ b/Documentation/devicetree/bindings/fb/mdss-mdp.txt
@@ -243,6 +243,12 @@
applied in scenarios where panel interface can
be more tolerant to memory latency such as
command mode panels.
+- qcom,mdss-rotator-ot-limit: This integer value indicates maximum number of pending
+ writes that can be allowed from rotator client. Default
+ value is 16 which is the maximum. This value can be
+ used to reduce the pending writes limit dynamically
+ and can be tuned to match performance requirements
+ depending upon system state.
Fudge Factors: Fudge factors are used to boost demand for
resources like bus bandswidth, clk rate etc. to
@@ -351,6 +357,7 @@
qcom,mdss-smp-data = <22 4096>;
qcom,mdss-rot-block-size = <64>;
+ qcom,mdss-rotator-ot-limit = <2>;
qcom,mdss-smp-mb-per-pipe = <2>;
qcom,mdss-pref-prim-intf = "dsi";
qcom,mdss-has-bwc;
diff --git a/Documentation/devicetree/bindings/input/misc/hbtp_input.txt b/Documentation/devicetree/bindings/input/misc/hbtp_input.txt
new file mode 100644
index 0000000..54643c7
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/misc/hbtp_input.txt
@@ -0,0 +1,14 @@
+Platform device for Host Based Touch Processing (hbtp)
+
+Required properties:
+
+ - compatible : should be "qcom,hbtp"
+ - vcc_ana-supply : Analog power supply needed to power device
+
+Example:
+ &soc {
+ hbtp {
+ compatible = "qcom,hbtp";
+ vcc_ana-supply = <&pm8941_l18>;
+ };
+ };
diff --git a/Documentation/devicetree/bindings/input/touchscreen/gt9xx/gt9xx.txt b/Documentation/devicetree/bindings/input/touchscreen/gt9xx/gt9xx.txt
index f2ca95b..d0c2b7d 100644
--- a/Documentation/devicetree/bindings/input/touchscreen/gt9xx/gt9xx.txt
+++ b/Documentation/devicetree/bindings/input/touchscreen/gt9xx/gt9xx.txt
@@ -29,7 +29,7 @@
It is a four tuple consisting of min x,
min y, max x and max y values.
- goodix,i2c-pull-up : To specify pull up is required.
- - goodix,no-force-update : To specify force update is allowed.
+ - goodix,force-update : To specify force update is allowed.
- goodix,enable-power-off : Power off touchscreen during suspend.
- goodix,button-map : Button map of key codes. The number of key codes
depend on panel.
diff --git a/Documentation/devicetree/bindings/nfc/nfc-nci.txt b/Documentation/devicetree/bindings/nfc/nfc-nci.txt
index dca7d5c..2c06599 100644
--- a/Documentation/devicetree/bindings/nfc/nfc-nci.txt
+++ b/Documentation/devicetree/bindings/nfc/nfc-nci.txt
@@ -8,13 +8,15 @@
- reg: NCI i2c slave address.
- qcom,dis-gpio: specific gpio for hardware reset.
- qcom,irq-gpio: specific gpio for read interrupt.
-- qcom,clk-src: nfc clock source ("BBCLK2", "RFCLK3", "GPCLK","GPCLK2" ...)
-- qcom,clk-en-gpio: msm gpio clock,used ony if clock source is msm gpio
+- qcom,clk-src: nfc clock source ("BBCLK2", "RFCLK3", "GPCLK", "GPCLK2", ...)
+- qcom,clk-src-gpio: msm gpio clock,used ony if clock source is msm gpio
+- qcom,clk-req-gpio: clk-req input gpio for MSM based clocks.
+ not used for pmic implementation
- vlogic-supply: LDO for power supply
- interrupt-parent: Should be phandle for the interrupt controller
that services interrupts for this device.
-- interrupts: should contain the NFC interrupt. NFC has one read interrupt.
-- qcom,clk-gpio: pmic gpio on which bbclk2 signal is coming.
+- interrupts: Nfc read interrupt,gpio-clk-req interrupt
+- qcom,clk-gpio: pmic or msm gpio on which bbclk2 signal is coming.
LDO example:
@@ -24,8 +26,8 @@
reg = <0x0e>;
qcom,irq-gpio = <&msmgpio 77 0x00>;
qcom,dis-gpio = <&msmgpio 93 0x00>;
- qcom,clk-en-gpio = <&msmgpio 78 0x00>;
- qcom,clk-src = "GPCLK";
+ qcom,clk-src-gpio = <&msmgpio 78 0x00>;
+ qcom,clk-src = "GPCLK2";
interrupt-parent = <&msmgpio>;
interrupts = <77 0>;
qcom,clk-gpio = <&msmgpio 75 0x00>;
diff --git a/Documentation/devicetree/bindings/regulator/onsemi-ncp6335d.txt b/Documentation/devicetree/bindings/regulator/onsemi-ncp6335d.txt
index efe6ad2..648cb11 100644
--- a/Documentation/devicetree/bindings/regulator/onsemi-ncp6335d.txt
+++ b/Documentation/devicetree/bindings/regulator/onsemi-ncp6335d.txt
@@ -39,7 +39,17 @@
pins are low.
Not Present: Low quiescent current mode when EN and VSEL
pins are low.
-
+- onnn,tlmm-config: Array of 2 elements to indicate the mask value and the value
+ to write in the masked bits.
+ This property is used to allow the VSEL GPIO to toggle on certain
+ Qualcomm processors. If it is not specified, then no register write is required.
+ The 2 elements with index[0..1] are:
+ [0] => the mask value;
+ [1] => the value to write into the masked bits.
+- onnn,mode: A string which specifies the initial mode to use for the regulator.
+ Supported values are "pwm" and "auto". PWM mode is more
+ robust, but draws more current than auto mode. If this propery
+ is not specified, then the regulator will be in the hardware default mode.
Example:
i2c_0 {
diff --git a/arch/arm/boot/dts/dsi-panel-jdi-1080p-video.dtsi b/arch/arm/boot/dts/dsi-panel-jdi-1080p-video.dtsi
index be42509..917c637 100644
--- a/arch/arm/boot/dts/dsi-panel-jdi-1080p-video.dtsi
+++ b/arch/arm/boot/dts/dsi-panel-jdi-1080p-video.dtsi
@@ -66,5 +66,7 @@
qcom,mdss-dsi-mdp-trigger = "none";
qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_wled";
qcom,mdss-dsi-reset-sequence = <1 20>, <0 200>, <1 20>;
+ qcom,mdss-pan-physical-width-dimension = <61>;
+ qcom,mdss-pan-physical-height-dimension = <110>;
};
};
diff --git a/arch/arm/boot/dts/msm8226-mdss.dtsi b/arch/arm/boot/dts/msm8226-mdss.dtsi
index 40576c9..8a98d5c 100644
--- a/arch/arm/boot/dts/msm8226-mdss.dtsi
+++ b/arch/arm/boot/dts/msm8226-mdss.dtsi
@@ -58,6 +58,7 @@
qcom,mdss-wb-off = <0x00011100 0x00013100>;
qcom,mdss-intf-off = <0x00000000 0x00021300>;
qcom,mdss-rot-block-size = <64>;
+ qcom,mdss-rotator-ot-limit = <2>;
qcom,mdss-smp-mb-per-pipe = <4>;
vdd-cx-supply = <&pm8226_s1_corner>;
diff --git a/arch/arm/boot/dts/msm8226-v2.dtsi b/arch/arm/boot/dts/msm8226-v2.dtsi
index 089d415..a285ec9 100644
--- a/arch/arm/boot/dts/msm8226-v2.dtsi
+++ b/arch/arm/boot/dts/msm8226-v2.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2014, 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
@@ -83,31 +83,11 @@
< 384000000 2>,
< 787200000 4>,
<1190400000 7>;
- qcom,speed6-bin-v2 =
- < 0 0>,
- < 384000000 2>,
- < 787200000 4>,
- <1190400000 7>;
qcom,speed2-bin-v2 =
< 0 0>,
< 384000000 2>,
< 787200000 4>,
<1401600000 10>;
- qcom,speed5-bin-v2 =
- < 0 0>,
- < 384000000 2>,
- < 787200000 4>,
- <1401600000 10>;
- qcom,speed4-bin-v2 =
- < 0 0>,
- < 384000000 2>,
- < 787200000 4>,
- <1401600000 10>;
- qcom,speed7-bin-v2 =
- < 0 0>,
- < 384000000 2>,
- < 787200000 4>,
- <1401600000 10>;
qcom,speed1-bin-v2 =
< 0 0>,
< 384000000 2>,
diff --git a/arch/arm/boot/dts/msm8610-mtp.dtsi b/arch/arm/boot/dts/msm8610-mtp.dtsi
index 7f48db0..aad838e 100644
--- a/arch/arm/boot/dts/msm8610-mtp.dtsi
+++ b/arch/arm/boot/dts/msm8610-mtp.dtsi
@@ -151,10 +151,11 @@
reg = <0x0e>;
qcom,irq-gpio = <&msmgpio 77 0x00>;
qcom,dis-gpio = <&msmgpio 93 0x00>;
- qcom,clk-en-gpio = <&msmgpio 78 0x00>;
+ qcom,clk-req-gpio = <&msmgpio 75 0x00>;
+ qcom,clk-src-gpio = <&msmgpio 78 0x00>;
qcom,clk-src = "GPCLK";
interrupt-parent = <&msmgpio>;
- interrupts = <77 0>;
+ interrupts = <77 75 0>;
qcom,clk-gpio = <&pm8110_gpios 1 0>;
};
};
diff --git a/arch/arm/boot/dts/msm8610-qrd-skuaa.dtsi b/arch/arm/boot/dts/msm8610-qrd-skuaa.dtsi
index 719830e..53abb95 100644
--- a/arch/arm/boot/dts/msm8610-qrd-skuaa.dtsi
+++ b/arch/arm/boot/dts/msm8610-qrd-skuaa.dtsi
@@ -38,11 +38,12 @@
compatible = "qcom,nfc-nci";
reg = <0x0e>;
qcom,irq-gpio = <&msmgpio 77 0x00>;
+ qcom,clk-req-gpio = <&msmgpio 75 0x00>;
qcom,dis-gpio = <&msmgpio 93 0x00>;
- qcom,clk-en-gpio = <&msmgpio 78 0x00>;
+ qcom,clk-src-gpio = <&msmgpio 78 0x00>;
qcom,clk-src = "GPCLK2";
interrupt-parent = <&msmgpio>;
- interrupts = <77 0>;
+ interrupts = <77 75 0>;
qcom,clk-gpio = <&msmgpio 75 0x00>;
};
};
diff --git a/arch/arm/boot/dts/msm8926-qrd-skug.dtsi b/arch/arm/boot/dts/msm8926-qrd-skug.dtsi
index fea5a9e..c93ea12 100644
--- a/arch/arm/boot/dts/msm8926-qrd-skug.dtsi
+++ b/arch/arm/boot/dts/msm8926-qrd-skug.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2014, 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
@@ -10,7 +10,6 @@
* GNU General Public License for more details.
*/
-/include/ "msm8926.dtsi"
/include/ "msm8226-qrd.dtsi"
/include/ "msm8926-camera-sensor-qrd.dtsi"
diff --git a/arch/arm/boot/dts/msm8926-1080p-cdp.dts b/arch/arm/boot/dts/msm8926-v1-1080p-cdp.dts
similarity index 89%
copy from arch/arm/boot/dts/msm8926-1080p-cdp.dts
copy to arch/arm/boot/dts/msm8926-v1-1080p-cdp.dts
index 33e484a..1b6f971 100644
--- a/arch/arm/boot/dts/msm8926-1080p-cdp.dts
+++ b/arch/arm/boot/dts/msm8926-v1-1080p-cdp.dts
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2014, 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
@@ -12,7 +12,7 @@
/dts-v1/;
-/include/ "msm8926.dtsi"
+/include/ "msm8926-v1.dtsi"
/include/ "msm8226-1080p-cdp.dtsi"
/include/ "msm8226-camera-sensor-cdp.dtsi"
diff --git a/arch/arm/boot/dts/msm8926-1080p-mtp.dts b/arch/arm/boot/dts/msm8926-v1-1080p-mtp.dts
similarity index 87%
rename from arch/arm/boot/dts/msm8926-1080p-mtp.dts
rename to arch/arm/boot/dts/msm8926-v1-1080p-mtp.dts
index c1217a2..0812c54 100644
--- a/arch/arm/boot/dts/msm8926-1080p-mtp.dts
+++ b/arch/arm/boot/dts/msm8926-v1-1080p-mtp.dts
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2014, 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
@@ -12,7 +12,7 @@
/dts-v1/;
-/include/ "msm8926.dtsi"
+/include/ "msm8926-v1.dtsi"
/include/ "msm8226-1080p-mtp.dtsi"
/include/ "msm8226-camera-sensor-mtp.dtsi"
diff --git a/arch/arm/boot/dts/msm8926-720p-cdp.dts b/arch/arm/boot/dts/msm8926-v1-720p-cdp.dts
similarity index 89%
copy from arch/arm/boot/dts/msm8926-720p-cdp.dts
copy to arch/arm/boot/dts/msm8926-v1-720p-cdp.dts
index 80bb5e6..37da01c 100644
--- a/arch/arm/boot/dts/msm8926-720p-cdp.dts
+++ b/arch/arm/boot/dts/msm8926-v1-720p-cdp.dts
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2014, 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
@@ -12,7 +12,7 @@
/dts-v1/;
-/include/ "msm8926.dtsi"
+/include/ "msm8926-v1.dtsi"
/include/ "msm8226-720p-cdp.dtsi"
/include/ "msm8226-camera-sensor-cdp.dtsi"
diff --git a/arch/arm/boot/dts/msm8926-720p-mtp.dts b/arch/arm/boot/dts/msm8926-v1-720p-mtp.dts
similarity index 87%
copy from arch/arm/boot/dts/msm8926-720p-mtp.dts
copy to arch/arm/boot/dts/msm8926-v1-720p-mtp.dts
index 32301fd..7b49930 100644
--- a/arch/arm/boot/dts/msm8926-720p-mtp.dts
+++ b/arch/arm/boot/dts/msm8926-v1-720p-mtp.dts
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2014, 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
@@ -12,7 +12,7 @@
/dts-v1/;
-/include/ "msm8926.dtsi"
+/include/ "msm8926-v1.dtsi"
/include/ "msm8226-720p-mtp.dtsi"
/include/ "msm8226-camera-sensor-mtp.dtsi"
diff --git a/arch/arm/boot/dts/msm8926-qrd-skug-pvt.dts b/arch/arm/boot/dts/msm8926-v1-qrd-skug-pvt.dts
similarity index 88%
rename from arch/arm/boot/dts/msm8926-qrd-skug-pvt.dts
rename to arch/arm/boot/dts/msm8926-v1-qrd-skug-pvt.dts
index 2a45592..fb5bc01 100644
--- a/arch/arm/boot/dts/msm8926-qrd-skug-pvt.dts
+++ b/arch/arm/boot/dts/msm8926-v1-qrd-skug-pvt.dts
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2014, 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
@@ -11,6 +11,7 @@
*/
/dts-v1/;
+/include/ "msm8926-v1.dtsi"
/include/ "msm8926-qrd-skug.dtsi"
/ {
diff --git a/arch/arm/boot/dts/msm8926-qrd-skug.dts b/arch/arm/boot/dts/msm8926-v1-qrd-skug.dts
similarity index 86%
rename from arch/arm/boot/dts/msm8926-qrd-skug.dts
rename to arch/arm/boot/dts/msm8926-v1-qrd-skug.dts
index 4aab4f9..0cb6119 100644
--- a/arch/arm/boot/dts/msm8926-qrd-skug.dts
+++ b/arch/arm/boot/dts/msm8926-v1-qrd-skug.dts
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2014, 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
@@ -11,6 +11,7 @@
*/
/dts-v1/;
+/include/ "msm8926-v1.dtsi"
/include/ "msm8926-qrd-skug.dtsi"
/ {
diff --git a/arch/arm/boot/dts/msm8926-qrd.dts b/arch/arm/boot/dts/msm8926-v1-qrd.dts
similarity index 86%
rename from arch/arm/boot/dts/msm8926-qrd.dts
rename to arch/arm/boot/dts/msm8926-v1-qrd.dts
index 8ee8828..fa6ff64 100644
--- a/arch/arm/boot/dts/msm8926-qrd.dts
+++ b/arch/arm/boot/dts/msm8926-v1-qrd.dts
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2014, 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
@@ -11,7 +11,7 @@
*/
/dts-v1/;
-/include/ "msm8926.dtsi"
+/include/ "msm8926-v1.dtsi"
/include/ "msm8226-qrd.dtsi"
/ {
diff --git a/arch/arm/boot/dts/msm8926-qrd.dts b/arch/arm/boot/dts/msm8926-v1.dtsi
similarity index 68%
copy from arch/arm/boot/dts/msm8926-qrd.dts
copy to arch/arm/boot/dts/msm8926-v1.dtsi
index 8ee8828..c70cf71 100644
--- a/arch/arm/boot/dts/msm8926-qrd.dts
+++ b/arch/arm/boot/dts/msm8926-v1.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2014, 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
@@ -10,12 +10,11 @@
* GNU General Public License for more details.
*/
-/dts-v1/;
/include/ "msm8926.dtsi"
-/include/ "msm8226-qrd.dtsi"
/ {
- model = "Qualcomm MSM 8926 QRD";
- compatible = "qcom,msm8926-qrd", "qcom,msm8926", "qcom,qrd";
- qcom,board-id = <11 0>;
+ qcom,msm-id = <200 0>,
+ <224 0>,
+ <200 0x10001>,
+ <224 0x10001>;
};
diff --git a/arch/arm/boot/dts/msm8926-1080p-cdp.dts b/arch/arm/boot/dts/msm8926-v2-1080p-cdp.dts
similarity index 89%
rename from arch/arm/boot/dts/msm8926-1080p-cdp.dts
rename to arch/arm/boot/dts/msm8926-v2-1080p-cdp.dts
index 33e484a..a4ebbe1 100644
--- a/arch/arm/boot/dts/msm8926-1080p-cdp.dts
+++ b/arch/arm/boot/dts/msm8926-v2-1080p-cdp.dts
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2014, 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
@@ -12,7 +12,7 @@
/dts-v1/;
-/include/ "msm8926.dtsi"
+/include/ "msm8926-v2.dtsi"
/include/ "msm8226-1080p-cdp.dtsi"
/include/ "msm8226-camera-sensor-cdp.dtsi"
diff --git a/arch/arm/boot/dts/msm8926-1080p-cdp.dts b/arch/arm/boot/dts/msm8926-v2-1080p-ext-buck-cdp.dts
similarity index 86%
copy from arch/arm/boot/dts/msm8926-1080p-cdp.dts
copy to arch/arm/boot/dts/msm8926-v2-1080p-ext-buck-cdp.dts
index 33e484a..64e872b 100644
--- a/arch/arm/boot/dts/msm8926-1080p-cdp.dts
+++ b/arch/arm/boot/dts/msm8926-v2-1080p-ext-buck-cdp.dts
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2014, 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
@@ -12,14 +12,14 @@
/dts-v1/;
-/include/ "msm8926.dtsi"
+/include/ "msm8926-v2-ext-buck.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 2>;
+ qcom,board-id = <1 3>;
};
&pm8226_chg {
diff --git a/arch/arm/boot/dts/msm8926-1080p-mtp.dts b/arch/arm/boot/dts/msm8926-v2-1080p-ext-buck-mtp.dts
similarity index 83%
copy from arch/arm/boot/dts/msm8926-1080p-mtp.dts
copy to arch/arm/boot/dts/msm8926-v2-1080p-ext-buck-mtp.dts
index c1217a2..f9a3cd8 100644
--- a/arch/arm/boot/dts/msm8926-1080p-mtp.dts
+++ b/arch/arm/boot/dts/msm8926-v2-1080p-ext-buck-mtp.dts
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2014, 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
@@ -12,12 +12,12 @@
/dts-v1/;
-/include/ "msm8926.dtsi"
+/include/ "msm8926-v2-ext-buck.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 2>;
+ qcom,board-id = <8 3>;
};
diff --git a/arch/arm/boot/dts/msm8926-1080p-mtp.dts b/arch/arm/boot/dts/msm8926-v2-1080p-mtp.dts
similarity index 87%
copy from arch/arm/boot/dts/msm8926-1080p-mtp.dts
copy to arch/arm/boot/dts/msm8926-v2-1080p-mtp.dts
index c1217a2..1f0bab1 100644
--- a/arch/arm/boot/dts/msm8926-1080p-mtp.dts
+++ b/arch/arm/boot/dts/msm8926-v2-1080p-mtp.dts
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2014, 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
@@ -12,7 +12,7 @@
/dts-v1/;
-/include/ "msm8926.dtsi"
+/include/ "msm8926-v2.dtsi"
/include/ "msm8226-1080p-mtp.dtsi"
/include/ "msm8226-camera-sensor-mtp.dtsi"
diff --git a/arch/arm/boot/dts/msm8926-720p-cdp.dts b/arch/arm/boot/dts/msm8926-v2-720p-cdp.dts
similarity index 89%
rename from arch/arm/boot/dts/msm8926-720p-cdp.dts
rename to arch/arm/boot/dts/msm8926-v2-720p-cdp.dts
index 80bb5e6..1e6e197 100644
--- a/arch/arm/boot/dts/msm8926-720p-cdp.dts
+++ b/arch/arm/boot/dts/msm8926-v2-720p-cdp.dts
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2014, 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
@@ -12,7 +12,7 @@
/dts-v1/;
-/include/ "msm8926.dtsi"
+/include/ "msm8926-v2.dtsi"
/include/ "msm8226-720p-cdp.dtsi"
/include/ "msm8226-camera-sensor-cdp.dtsi"
diff --git a/arch/arm/boot/dts/msm8926-720p-mtp.dts b/arch/arm/boot/dts/msm8926-v2-720p-mtp.dts
similarity index 87%
rename from arch/arm/boot/dts/msm8926-720p-mtp.dts
rename to arch/arm/boot/dts/msm8926-v2-720p-mtp.dts
index 32301fd..59ad506 100644
--- a/arch/arm/boot/dts/msm8926-720p-mtp.dts
+++ b/arch/arm/boot/dts/msm8926-v2-720p-mtp.dts
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2014, 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
@@ -12,7 +12,7 @@
/dts-v1/;
-/include/ "msm8926.dtsi"
+/include/ "msm8926-v2.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-v2-ext-buck.dtsi
similarity index 65%
copy from arch/arm/boot/dts/msm8926-qrd-skug.dts
copy to arch/arm/boot/dts/msm8926-v2-ext-buck.dtsi
index 4aab4f9..07d91a8 100644
--- a/arch/arm/boot/dts/msm8926-qrd-skug.dts
+++ b/arch/arm/boot/dts/msm8926-v2-ext-buck.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2014, 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
@@ -10,12 +10,8 @@
* GNU General Public License for more details.
*/
-/dts-v1/;
-/include/ "msm8926-qrd-skug.dtsi"
+/include/ "msm8926-v2.dtsi"
-/ {
- model = "Qualcomm MSM 8926 QRD SKUG";
- compatible = "qcom,msm8926-qrd", "qcom,msm8926", "qcom,qrd";
- qcom,board-id = <11 5>;
+&soc {
+
};
-
diff --git a/arch/arm/boot/dts/msm8926-qrd-skug-pvt.dts b/arch/arm/boot/dts/msm8926-v2-qrd-skug-pvt.dts
similarity index 88%
copy from arch/arm/boot/dts/msm8926-qrd-skug-pvt.dts
copy to arch/arm/boot/dts/msm8926-v2-qrd-skug-pvt.dts
index 2a45592..f8cd88d 100644
--- a/arch/arm/boot/dts/msm8926-qrd-skug-pvt.dts
+++ b/arch/arm/boot/dts/msm8926-v2-qrd-skug-pvt.dts
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2014, 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
@@ -11,6 +11,7 @@
*/
/dts-v1/;
+/include/ "msm8926-v2.dtsi"
/include/ "msm8926-qrd-skug.dtsi"
/ {
diff --git a/arch/arm/boot/dts/msm8926-qrd-skug.dts b/arch/arm/boot/dts/msm8926-v2-qrd-skug.dts
similarity index 86%
copy from arch/arm/boot/dts/msm8926-qrd-skug.dts
copy to arch/arm/boot/dts/msm8926-v2-qrd-skug.dts
index 4aab4f9..0d69e51 100644
--- a/arch/arm/boot/dts/msm8926-qrd-skug.dts
+++ b/arch/arm/boot/dts/msm8926-v2-qrd-skug.dts
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2014, 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
@@ -11,6 +11,7 @@
*/
/dts-v1/;
+/include/ "msm8926-v2.dtsi"
/include/ "msm8926-qrd-skug.dtsi"
/ {
diff --git a/arch/arm/boot/dts/msm8926-qrd.dts b/arch/arm/boot/dts/msm8926-v2-qrd.dts
similarity index 86%
copy from arch/arm/boot/dts/msm8926-qrd.dts
copy to arch/arm/boot/dts/msm8926-v2-qrd.dts
index 8ee8828..6223055 100644
--- a/arch/arm/boot/dts/msm8926-qrd.dts
+++ b/arch/arm/boot/dts/msm8926-v2-qrd.dts
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2014, 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
@@ -11,7 +11,7 @@
*/
/dts-v1/;
-/include/ "msm8926.dtsi"
+/include/ "msm8926-v2.dtsi"
/include/ "msm8226-qrd.dtsi"
/ {
diff --git a/arch/arm/boot/dts/msm8926-v2.dtsi b/arch/arm/boot/dts/msm8926-v2.dtsi
new file mode 100644
index 0000000..db8e02f
--- /dev/null
+++ b/arch/arm/boot/dts/msm8926-v2.dtsi
@@ -0,0 +1,71 @@
+/* Copyright (c) 2013-2014, 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/ "msm8926.dtsi"
+
+/ {
+ qcom,msm-id = <200 0x20000>,
+ <224 0x20000>;
+};
+
+&msm_gpu {
+ /* Updated chip ID */
+ qcom,chipid = <0x03000512>;
+
+ /* Bus Scale Settings */
+ qcom,msm-bus,num-cases = <4>;
+ qcom,msm-bus,vectors-KBps =
+ <26 512 0 0>, <89 604 0 0>,
+ <26 512 0 1800000>, <89 604 0 3200000>,
+ <26 512 0 3600000>, <89 604 0 5120000>,
+ <26 512 0 4800000>, <89 604 0 6400000>;
+
+ /* Power levels */
+ qcom,gpu-pwrlevels {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ compatible = "qcom,gpu-pwrlevels";
+
+ qcom,gpu-pwrlevel@0 {
+ reg = <0>;
+ qcom,gpu-freq = <500000000>;
+ qcom,bus-freq = <3>;
+ qcom,io-fraction = <0>;
+ };
+
+ qcom,gpu-pwrlevel@1 {
+ reg = <1>;
+ qcom,gpu-freq = <320000000>;
+ qcom,bus-freq = <2>;
+ qcom,io-fraction = <33>;
+ };
+
+ qcom,gpu-pwrlevel@2 {
+ reg = <2>;
+ qcom,gpu-freq = <200000000>;
+ qcom,bus-freq = <1>;
+ qcom,io-fraction = <100>;
+ };
+
+ qcom,gpu-pwrlevel@3 {
+ reg = <3>;
+ qcom,gpu-freq = <19000000>;
+ qcom,bus-freq = <0>;
+ qcom,io-fraction = <0>;
+ };
+ };
+};
+
+&apc_vreg_corner {
+ /delete-property/ qcom,cpr-enable;
+};
diff --git a/arch/arm/boot/dts/msm8926.dtsi b/arch/arm/boot/dts/msm8926.dtsi
index 1cefc7f..2bb202f 100644
--- a/arch/arm/boot/dts/msm8926.dtsi
+++ b/arch/arm/boot/dts/msm8926.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2014, 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
@@ -22,10 +22,6 @@
/ {
model = "Qualcomm MSM 8926";
compatible = "qcom,msm8926";
- qcom,msm-id = <200 0>,
- <224 0>,
- <200 0x10001>,
- <224 0x10001>;
};
&i2c_0 {
@@ -46,6 +42,7 @@
onnn,vsel-gpio = <&msmgpio 2 1>;
onnn,discharge-enable;
onnn,restore-reg;
+ onnn,tlmm-config = <0x80 0x0>;
};
fan53555: fan53555-regulator@60 {
@@ -81,31 +78,11 @@
< 384000000 2>,
< 787200000 4>,
<1190400000 7>;
- qcom,speed6-bin-v1 =
- < 0 0>,
- < 384000000 2>,
- < 787200000 4>,
- <1190400000 7>;
qcom,speed2-bin-v1 =
< 0 0>,
< 384000000 2>,
< 787200000 4>,
<1401600000 10>;
- qcom,speed5-bin-v1 =
- < 0 0>,
- < 384000000 2>,
- < 787200000 4>,
- <1401600000 10>;
- qcom,speed4-bin-v1 =
- < 0 0>,
- < 384000000 2>,
- < 787200000 4>,
- <1401600000 10>;
- qcom,speed7-bin-v1 =
- < 0 0>,
- < 384000000 2>,
- < 787200000 4>,
- <1401600000 10>;
qcom,speed1-bin-v1 =
< 0 0>,
< 384000000 2>,
@@ -203,9 +180,11 @@
qcom,pvs-corner-ceiling-fast = <1050000 1050000 1100000>;
qcom,cpr-step-quotient = <30>;
qcom,cpr-up-threshold = <0>;
- qcom,cpr-down-threshold = <1>;
+ qcom,cpr-down-threshold = <2>;
qcom,cpr-apc-volt-step = <10000>;
- qcom,cpr-quotient-adjustment = <96>;
+ qcom,cpr-quotient-adjustment = <0 72 72>;
+ vdd-apc-optional-prim-supply = <&ncp6335d>;
+ vdd-apc-optional-sec-supply = <&fan53555>;
};
&tsens {
diff --git a/arch/arm/boot/dts/msm8974-fluid.dtsi b/arch/arm/boot/dts/msm8974-fluid.dtsi
index d0ca01d..f4b4d4a 100644
--- a/arch/arm/boot/dts/msm8974-fluid.dtsi
+++ b/arch/arm/boot/dts/msm8974-fluid.dtsi
@@ -133,6 +133,20 @@
};
};
+ i2c@f9928000 { /* BLSP1 QUP6 */
+ nfc-nci@e {
+ compatible = "qcom,nfc-nci";
+ reg = <0x0e>;
+ qcom,irq-gpio = <&msmgpio 59 0x00>;
+ qcom,dis-gpio = <&msmgpio 13 0x00>;
+ qcom,clk-src = "BBCLK2";
+ qcom,clk-en-gpio = <&msmgpio 0 0x00>;
+ interrupt-parent = <&msmgpio>;
+ interrupts = <59 0>;
+ qcom,clk-gpio = <&pm8941_gpios 32 0>;
+ };
+ };
+
i2c@f9967000 {
sii8334@72 {
compatible = "qcom,mhl-sii8334";
@@ -606,6 +620,11 @@
};
gpio@df00 { /* GPIO 32 */
+ 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@e000 { /* GPIO 33 */
diff --git a/arch/arm/boot/dts/msm8974.dtsi b/arch/arm/boot/dts/msm8974.dtsi
index f4aa25b..030a1f3 100644
--- a/arch/arm/boot/dts/msm8974.dtsi
+++ b/arch/arm/boot/dts/msm8974.dtsi
@@ -2347,6 +2347,22 @@
compatible = "qcom,bcl";
};
+ i2c@f9928000 { /* BLSP-1 QUP-6 */
+ cell-index = <3>;
+ compatible = "qcom,i2c-qup";
+ reg = <0xf9928000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg-names = "qup_phys_addr";
+ interrupts = <0 100 0>;
+ interrupt-names = "qup_err_intr";
+ qcom,i2c-bus-freq = <400000>;
+ qcom,i2c-src-freq = <19200000>;
+ qcom,scl-gpio = <&msmgpio 30 0>;
+ qcom,sda-gpio = <&msmgpio 29 0>;
+ qcom,master-id = <86>;
+ };
+
qcom,ssm {
compatible = "qcom,ssm";
qcom,channel-name = "SSM_RTR";
diff --git a/arch/arm/boot/dts/msm8974pro-ab-pm8941-fluid-hbtp.dts b/arch/arm/boot/dts/msm8974pro-ab-pm8941-fluid-hbtp.dts
new file mode 100644
index 0000000..f4f7968
--- /dev/null
+++ b/arch/arm/boot/dts/msm8974pro-ab-pm8941-fluid-hbtp.dts
@@ -0,0 +1,42 @@
+/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+
+/include/ "msm8974pro-ab-pm8941.dtsi"
+/include/ "msm8974-fluid.dtsi"
+
+/ {
+ model = "Qualcomm MSM 8974Pro-AA/AB FLUID";
+ compatible = "qcom,msm8974-fluid", "qcom,msm8974", "qcom,fluid";
+ qcom,board-id = <3 1>;
+};
+
+&soc {
+ spi@f9966000 { /* BLSP2 QUP4 */
+ /* Leave the SPI bus for QDSP to use */
+ status = "disabled";
+ };
+
+ hbtp {
+ compatible = "qcom,hbtp";
+ vcc_ana-supply = <&pm8941_l18>;
+ };
+};
+
+&i2c_0 {
+ /* mhl-sii8334 is on i2c_0 and uses gpio 12 as mhl-pwr-gpio.
+ * Display panel needs gpio 12 as TE gpio in command mode.
+ * Disabling the bus to make sure that display gets the gpio.
+ */
+ status = "disabled";
+};
diff --git a/arch/arm/configs/msm8226-perf_defconfig b/arch/arm/configs/msm8226-perf_defconfig
index a3052c2..3dd9c55 100644
--- a/arch/arm/configs/msm8226-perf_defconfig
+++ b/arch/arm/configs/msm8226-perf_defconfig
@@ -221,6 +221,7 @@
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
CONFIG_QSEECOM=y
+CONFIG_USB_HSIC_SMSC_HUB=y
CONFIG_SCSI=y
CONFIG_SCSI_TGT=y
CONFIG_BLK_DEV_SD=y
diff --git a/arch/arm/configs/msm8226_defconfig b/arch/arm/configs/msm8226_defconfig
index 77df868..38171e6 100644
--- a/arch/arm/configs/msm8226_defconfig
+++ b/arch/arm/configs/msm8226_defconfig
@@ -221,6 +221,7 @@
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
CONFIG_QSEECOM=y
+CONFIG_USB_HSIC_SMSC_HUB=y
CONFIG_SCSI=y
CONFIG_SCSI_TGT=y
CONFIG_BLK_DEV_SD=y
diff --git a/arch/arm/configs/msm8974-perf_defconfig b/arch/arm/configs/msm8974-perf_defconfig
index 5904aea..915b1c3 100755
--- a/arch/arm/configs/msm8974-perf_defconfig
+++ b/arch/arm/configs/msm8974-perf_defconfig
@@ -295,6 +295,7 @@
CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4=y
CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE=y
CONFIG_INPUT_MISC=y
+CONFIG_INPUT_HBTP_INPUT=y
CONFIG_INPUT_UINPUT=y
CONFIG_SERIAL_MSM_HS=y
CONFIG_SERIAL_MSM_HSL=y
diff --git a/arch/arm/configs/msm8974_defconfig b/arch/arm/configs/msm8974_defconfig
index 1f7eb49..f1c285d 100755
--- a/arch/arm/configs/msm8974_defconfig
+++ b/arch/arm/configs/msm8974_defconfig
@@ -301,6 +301,7 @@
CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4=y
CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE=y
CONFIG_INPUT_MISC=y
+CONFIG_INPUT_HBTP_INPUT=y
CONFIG_INPUT_UINPUT=y
CONFIG_SERIAL_MSM_HS=y
CONFIG_SERIAL_MSM_HSL=y
diff --git a/arch/arm/mach-msm/Makefile.boot b/arch/arm/mach-msm/Makefile.boot
index 78df289..c0e9efc 100644
--- a/arch/arm/mach-msm/Makefile.boot
+++ b/arch/arm/mach-msm/Makefile.boot
@@ -69,6 +69,7 @@
dtb-$(CONFIG_ARCH_MSM8974) += msm8974-v2.2-mtp.dtb
dtb-$(CONFIG_ARCH_MSM8974) += msm8974pro-ab-pm8941-cdp.dtb
dtb-$(CONFIG_ARCH_MSM8974) += msm8974pro-ab-pm8941-fluid.dtb
+ dtb-$(CONFIG_ARCH_MSM8974) += msm8974pro-ab-pm8941-fluid-hbtp.dtb
dtb-$(CONFIG_ARCH_MSM8974) += msm8974pro-ab-pm8941-liquid.dtb
dtb-$(CONFIG_ARCH_MSM8974) += msm8974pro-ab-pm8941-mtp.dtb
dtb-$(CONFIG_ARCH_MSM8974) += msm8974pro-ac-pm8941-cdp.dtb
@@ -111,13 +112,22 @@
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) += msm8926-qrd-skug-pvt.dtb
+ dtb-$(CONFIG_ARCH_MSM8226) += msm8926-v1-720p-cdp.dtb
+ dtb-$(CONFIG_ARCH_MSM8226) += msm8926-v1-1080p-cdp.dtb
+ dtb-$(CONFIG_ARCH_MSM8226) += msm8926-v1-720p-mtp.dtb
+ dtb-$(CONFIG_ARCH_MSM8226) += msm8926-v1-1080p-mtp.dtb
+ dtb-$(CONFIG_ARCH_MSM8226) += msm8926-v1-qrd.dtb
+ dtb-$(CONFIG_ARCH_MSM8226) += msm8926-v1-qrd-skug.dtb
+ dtb-$(CONFIG_ARCH_MSM8226) += msm8926-v1-qrd-skug-pvt.dtb
+ dtb-$(CONFIG_ARCH_MSM8226) += msm8926-v2-720p-cdp.dtb
+ dtb-$(CONFIG_ARCH_MSM8226) += msm8926-v2-1080p-cdp.dtb
+ dtb-$(CONFIG_ARCH_MSM8226) += msm8926-v2-1080p-ext-buck-cdp.dtb
+ dtb-$(CONFIG_ARCH_MSM8226) += msm8926-v2-720p-mtp.dtb
+ dtb-$(CONFIG_ARCH_MSM8226) += msm8926-v2-1080p-mtp.dtb
+ dtb-$(CONFIG_ARCH_MSM8226) += msm8926-v2-1080p-ext-buck-mtp.dtb
+ dtb-$(CONFIG_ARCH_MSM8226) += msm8926-v2-qrd.dtb
+ dtb-$(CONFIG_ARCH_MSM8226) += msm8926-v2-qrd-skug.dtb
+ dtb-$(CONFIG_ARCH_MSM8226) += msm8926-v2-qrd-skug-pvt.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
diff --git a/arch/arm/mach-msm/board-8226.c b/arch/arm/mach-msm/board-8226.c
index 5244918..3539ad3 100644
--- a/arch/arm/mach-msm/board-8226.c
+++ b/arch/arm/mach-msm/board-8226.c
@@ -15,6 +15,7 @@
#include <linux/errno.h>
#include <linux/platform_device.h>
#include <linux/io.h>
+#include <linux/i2c/i2c-qup.h>
#include <linux/gpio.h>
#include <linux/irq.h>
#include <linux/irqdomain.h>
@@ -24,6 +25,9 @@
#include <linux/of_fdt.h>
#include <linux/of_irq.h>
#include <linux/memory.h>
+#include <linux/regulator/cpr-regulator.h>
+#include <linux/regulator/fan53555.h>
+#include <linux/regulator/onsemi-ncp6335d.h>
#include <linux/regulator/qpnp-regulator.h>
#include <linux/msm_tsens.h>
#include <asm/mach/map.h>
@@ -31,6 +35,7 @@
#include <asm/mach/arch.h>
#include <asm/mach/time.h>
#include <mach/board.h>
+#include <mach/msm_bus.h>
#include <mach/gpiomux.h>
#include <mach/msm_iomap.h>
#include <mach/restart.h>
@@ -52,6 +57,7 @@
#include "spm.h"
#include "pm.h"
#include "modem_notifier.h"
+#include "spm-regulator.h"
static struct memtype_reserve msm8226_reserve_table[] __initdata = {
[MEMTYPE_SMI] = {
@@ -121,10 +127,16 @@
msm_pm_sleep_status_init();
rpm_regulator_smd_driver_init();
qpnp_regulator_init();
+ spm_regulator_init();
if (of_board_is_rumi())
msm_clock_init(&msm8226_rumi_clock_init_data);
else
msm_clock_init(&msm8226_clock_init_data);
+ msm_bus_fabric_init_driver();
+ qup_i2c_init_driver();
+ ncp6335d_regulator_init();
+ fan53555_regulator_init();
+ cpr_regulator_init();
tsens_tm_init_driver();
msm_thermal_device_init();
}
diff --git a/arch/arm/mach-msm/board-8610-gpiomux.c b/arch/arm/mach-msm/board-8610-gpiomux.c
index 20bb0e4..2e12fc2 100644
--- a/arch/arm/mach-msm/board-8610-gpiomux.c
+++ b/arch/arm/mach-msm/board-8610-gpiomux.c
@@ -615,6 +615,13 @@
static struct msm_gpiomux_config msm_interrupt_configs[] __initdata = {
{
+ .gpio = 75, /* NFC_CLK_REQ_IRQ*/
+ .settings = {
+ [GPIOMUX_ACTIVE] = &interrupt_gpio_active,
+ [GPIOMUX_SUSPENDED] = &interrupt_gpio_suspend_pullup,
+ },
+ },
+ {
.gpio = 77, /* NFC_IRQ */
.settings = {
[GPIOMUX_ACTIVE] = &interrupt_gpio_active,
diff --git a/arch/arm/mach-msm/clock-8610.c b/arch/arm/mach-msm/clock-8610.c
index 672c512..d68762a 100644
--- a/arch/arm/mach-msm/clock-8610.c
+++ b/arch/arm/mach-msm/clock-8610.c
@@ -3150,6 +3150,12 @@
CLK_LOOKUP("bus_clk", gcc_ce1_axi_clk.c, "scm"),
CLK_LOOKUP("core_clk_src", ce1_clk_src.c, "scm"),
+ /* GUD Clocks */
+ CLK_LOOKUP("core_clk", gcc_ce1_clk.c, "mcd"),
+ CLK_LOOKUP("iface_clk", gcc_ce1_ahb_clk.c, "mcd"),
+ CLK_LOOKUP("bus_clk", gcc_ce1_axi_clk.c, "mcd"),
+ CLK_LOOKUP("core_clk_src", ce1_clk_src.c, "mcd"),
+
/* Add QCEDEV clocks */
CLK_LOOKUP("core_clk", gcc_ce1_clk.c, "fd400000.qcom,qcedev"),
CLK_LOOKUP("iface_clk", gcc_ce1_ahb_clk.c, "fd400000.qcom,qcedev"),
diff --git a/arch/arm/mach-msm/cpr-regulator.c b/arch/arm/mach-msm/cpr-regulator.c
index 766fc24..08285aa 100644
--- a/arch/arm/mach-msm/cpr-regulator.c
+++ b/arch/arm/mach-msm/cpr-regulator.c
@@ -223,7 +223,6 @@
int *corner_map;
u32 num_corners;
int *quot_adjust;
- u32 quotient_adjustment;
};
#define CPR_DEBUG_MASK_IRQ BIT(0)
@@ -1095,7 +1094,7 @@
u64 efuse_bits;
int rc, process;
u32 pvs_fuse[4], pvs_fuse_redun_sel[5];
- u32 init_v, quot_adjust;
+ u32 init_v;
bool redundant;
size_t pvs_bins;
@@ -1172,11 +1171,6 @@
cpr_vreg->process = process;
- rc = of_property_read_u32(of_node,
- "qcom,cpr-quotient-adjustment", "_adjust);
- if (!rc)
- cpr_vreg->quotient_adjustment = quot_adjust;
-
return 0;
}
@@ -1391,6 +1385,7 @@
int bp_ro_sel[CPR_FUSE_CORNER_MAX];
u32 ro_sel, val;
u64 fuse_bits, fuse_bits_2;
+ u32 quot_adjust[CPR_FUSE_CORNER_MAX];
rc = of_property_read_u32_array(of_node, "qcom,cpr-fuse-redun-sel",
cpr_fuse_redun_sel, 5);
@@ -1492,13 +1487,22 @@
& CPR_FUSE_RO_SEL_BITS_MASK;
val = (fuse_bits >> bp_target_quot[i])
& CPR_FUSE_TARGET_QUOT_BITS_MASK;
- val += cpr_vreg->quotient_adjustment;
cpr_vreg->cpr_fuse_target_quot[i] = val;
cpr_vreg->cpr_fuse_ro_sel[i] = ro_sel;
pr_info("Corner[%d]: ro_sel = %d, target quot = %d\n",
i, ro_sel, val);
}
+ rc = of_property_read_u32_array(of_node, "qcom,cpr-quotient-adjustment",
+ "_adjust[1], CPR_FUSE_CORNER_MAX - 1);
+ if (!rc) {
+ for (i = CPR_FUSE_CORNER_SVS; i < CPR_FUSE_CORNER_MAX; i++) {
+ cpr_vreg->cpr_fuse_target_quot[i] += quot_adjust[i];
+ pr_info("Corner[%d]: adjusted target quot = %d\n",
+ i, cpr_vreg->cpr_fuse_target_quot[i]);
+ }
+ }
+
if (cpr_vreg->flags & FLAGS_UPLIFT_QUOT_VOLT) {
cpr_voltage_uplift_wa_inc_quot(cpr_vreg, of_node);
for (i = CPR_FUSE_CORNER_SVS; i < CPR_FUSE_CORNER_MAX; i++) {
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_utils.c b/arch/arm/mach-msm/qdsp6v2/audio_utils.c
index 2f1ff3e..109e120 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_utils.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_utils.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2010-2014, 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
@@ -23,6 +23,11 @@
#include <asm/ioctls.h>
#include "audio_utils.h"
+#define MIN_FRAME_SIZE 1536
+#define NUM_FRAMES 5
+#define META_SIZE (sizeof(struct meta_out_dsp))
+#define FRAME_SIZE (1 + ((MIN_FRAME_SIZE + META_SIZE) * NUM_FRAMES))
+
static int audio_in_pause(struct q6audio_in *audio)
{
int rc;
@@ -258,6 +263,11 @@
rc = -EINVAL;
break;
}
+ if ((cfg.buffer_size > FRAME_SIZE) ||
+ (cfg.buffer_count != FRAME_NUM)) {
+ rc = -EINVAL;
+ break;
+ }
audio->str_cfg.buffer_size = cfg.buffer_size;
audio->str_cfg.buffer_count = cfg.buffer_count;
if(audio->opened){
diff --git a/arch/arm/mach-msm/rpm-regulator-smd.c b/arch/arm/mach-msm/rpm-regulator-smd.c
index 7995e9a..c7e9e75 100644
--- a/arch/arm/mach-msm/rpm-regulator-smd.c
+++ b/arch/arm/mach-msm/rpm-regulator-smd.c
@@ -163,6 +163,7 @@
struct mutex mlock;
unsigned long flags;
bool sleep_request_sent;
+ bool apps_only;
struct msm_rpm_request *handle_active;
struct msm_rpm_request *handle_sleep;
};
@@ -241,6 +242,16 @@
& BIT(RPM_REGULATOR_PARAM_ENABLE)));
}
+static inline bool rpm_vreg_shared_active_or_sleep_enabled_valid
+ (struct rpm_vreg *rpm_vreg)
+{
+ return !rpm_vreg->apps_only &&
+ ((rpm_vreg->aggr_req_active.valid
+ & BIT(RPM_REGULATOR_PARAM_ENABLE))
+ || (rpm_vreg->aggr_req_sleep.valid
+ & BIT(RPM_REGULATOR_PARAM_ENABLE)));
+}
+
/*
* This is used when voting for LPM or HPM by subtracting or adding to the
* hpm_min_load of a regulator. It has units of uA.
@@ -660,7 +671,8 @@
* if the regulator has been configured to always send voltage updates.
*/
if (reg->always_send_voltage
- || rpm_vreg_active_or_sleep_enabled(reg->rpm_vreg))
+ || rpm_vreg_active_or_sleep_enabled(reg->rpm_vreg)
+ || rpm_vreg_shared_active_or_sleep_enabled_valid(reg->rpm_vreg))
rc = rpm_vreg_aggregate_requests(reg);
if (rc) {
@@ -719,7 +731,8 @@
* updates.
*/
if (reg->always_send_voltage
- || rpm_vreg_active_or_sleep_enabled(reg->rpm_vreg))
+ || rpm_vreg_active_or_sleep_enabled(reg->rpm_vreg)
+ || rpm_vreg_shared_active_or_sleep_enabled_valid(reg->rpm_vreg))
rc = rpm_vreg_aggregate_requests(reg);
if (rc) {
@@ -774,7 +787,8 @@
* voltage updates.
*/
if (reg->always_send_voltage
- || rpm_vreg_active_or_sleep_enabled(reg->rpm_vreg))
+ || rpm_vreg_active_or_sleep_enabled(reg->rpm_vreg)
+ || rpm_vreg_shared_active_or_sleep_enabled_valid(reg->rpm_vreg))
rc = rpm_vreg_aggregate_requests(reg);
if (rc) {
@@ -829,7 +843,8 @@
* current updates.
*/
if (reg->always_send_current
- || rpm_vreg_active_or_sleep_enabled(reg->rpm_vreg))
+ || rpm_vreg_active_or_sleep_enabled(reg->rpm_vreg)
+ || rpm_vreg_shared_active_or_sleep_enabled_valid(reg->rpm_vreg))
rc = rpm_vreg_aggregate_requests(reg);
if (rc) {
@@ -1579,6 +1594,7 @@
of_property_read_u32(node, "qcom,enable-time", &rpm_vreg->enable_time);
of_property_read_u32(node, "qcom,hpm-min-load",
&rpm_vreg->hpm_min_load);
+ rpm_vreg->apps_only = of_property_read_bool(node, "qcom,apps-only");
rpm_vreg->handle_active = msm_rpm_create_request(RPM_SET_ACTIVE,
resource_type, rpm_vreg->resource_id, RPM_REGULATOR_PARAM_MAX);
diff --git a/block/blk-core.c b/block/blk-core.c
index 123f79a..00eab3b 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -314,7 +314,8 @@
if (!q->notified_urgent &&
q->elevator->type->ops.elevator_is_urgent_fn &&
q->urgent_request_fn &&
- q->elevator->type->ops.elevator_is_urgent_fn(q)) {
+ q->elevator->type->ops.elevator_is_urgent_fn(q) &&
+ list_empty(&q->flush_data_in_flight)) {
q->notified_urgent = true;
q->urgent_request_fn(q);
} else
diff --git a/drivers/bluetooth/bluetooth-power.c b/drivers/bluetooth/bluetooth-power.c
index 13c9080..9ccee05 100644
--- a/drivers/bluetooth/bluetooth-power.c
+++ b/drivers/bluetooth/bluetooth-power.c
@@ -30,7 +30,7 @@
#define BT_PWR_DBG(fmt, arg...) pr_debug("%s: " fmt "\n" , __func__ , ## arg)
#define BT_PWR_INFO(fmt, arg...) pr_info("%s: " fmt "\n" , __func__ , ## arg)
#define BT_PWR_ERR(fmt, arg...) pr_err("%s: " fmt "\n" , __func__ , ## arg)
-
+#define BT_VDD_PA_CURRENT 60000
static struct of_device_id bt_power_match_table[] = {
{ .compatible = "qca,ar3002" },
@@ -213,6 +213,9 @@
BT_PWR_ERR("bt_power vddpa config failed");
goto vdd_pa_fail;
}
+ regulator_set_optimum_mode(
+ bt_power_pdata->bt_vdd_pa->reg,
+ BT_VDD_PA_CURRENT);
}
if (bt_power_pdata->bt_chip_pwd) {
rc = bt_configure_vreg(bt_power_pdata->bt_chip_pwd);
diff --git a/drivers/bluetooth/hci_ath.c b/drivers/bluetooth/hci_ath.c
index 0383d8f..8272528 100644
--- a/drivers/bluetooth/hci_ath.c
+++ b/drivers/bluetooth/hci_ath.c
@@ -5,7 +5,7 @@
* power management protocol extension to H4 to support AR300x Bluetooth Chip.
*
* Copyright (c) 2009-2010 Atheros Communications Inc.
- * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved.
*
* Acknowledgements:
* This file is based on hci_h4.c, which was written
diff --git a/drivers/char/diag/diag_dci.c b/drivers/char/diag/diag_dci.c
index 37c236d..0edfdad 100644
--- a/drivers/char/diag/diag_dci.c
+++ b/drivers/char/diag/diag_dci.c
@@ -847,6 +847,22 @@
return ret;
}
+int diag_dci_find_client_index_health(int client_id)
+{
+ int i, ret = DCI_CLIENT_INDEX_INVALID;
+
+ for (i = 0; i < MAX_DCI_CLIENTS; i++) {
+ if (driver->dci_client_tbl[i].client != NULL) {
+ if (driver->dci_client_tbl[i].client_id ==
+ client_id) {
+ ret = i;
+ break;
+ }
+ }
+ }
+ return ret;
+}
+
int diag_dci_find_client_index(int client_id)
{
int i, ret = DCI_CLIENT_INDEX_INVALID;
diff --git a/drivers/char/diag/diag_dci.h b/drivers/char/diag/diag_dci.h
index 2ab8a36..870b0f3 100644
--- a/drivers/char/diag/diag_dci.h
+++ b/drivers/char/diag/diag_dci.h
@@ -56,6 +56,7 @@
} __packed;
struct diag_dci_client_tbl {
+ uint32_t client_id;
struct task_struct *client;
uint16_t list; /* bit mask */
int signal_type;
@@ -74,6 +75,7 @@
/* This is used for DCI health stats */
struct diag_dci_health_stats {
+ int client_id;
int dropped_logs;
int dropped_events;
int received_logs;
@@ -119,6 +121,8 @@
int recd_bytes);
int diag_process_dci_transaction(unsigned char *buf, int len);
void extract_dci_pkt_rsp(struct diag_smd_info *smd_info, unsigned char *buf);
+
+int diag_dci_find_client_index_health(int client_id);
int diag_dci_find_client_index(int client_id);
/* DCI Log streaming functions */
void create_dci_log_mask_tbl(unsigned char *tbl_buf);
diff --git a/drivers/char/diag/diag_debugfs.c b/drivers/char/diag/diag_debugfs.c
index d8b5599..3a1c96b 100644
--- a/drivers/char/diag/diag_debugfs.c
+++ b/drivers/char/diag/diag_debugfs.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2014, 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
@@ -33,14 +33,14 @@
{
char *buf;
int ret;
-
+ unsigned int buf_size;
buf = kzalloc(sizeof(char) * DEBUG_BUF_SIZE, GFP_KERNEL);
if (!buf) {
pr_err("diag: %s, Error allocating memory\n", __func__);
return -ENOMEM;
}
-
- ret = scnprintf(buf, DEBUG_BUF_SIZE,
+ buf_size = ksize(buf);
+ ret = scnprintf(buf, buf_size,
"modem ch: 0x%x\n"
"lpass ch: 0x%x\n"
"riva ch: 0x%x\n"
@@ -181,7 +181,7 @@
driver->real_time_mode);
#ifdef CONFIG_DIAG_OVER_USB
- ret += scnprintf(buf+ret, DEBUG_BUF_SIZE,
+ ret += scnprintf(buf+ret, buf_size-ret,
"usb_connected: %d\n",
driver->usb_connected);
#endif
@@ -198,7 +198,8 @@
unsigned int bytes_remaining, bytes_written = 0;
unsigned int bytes_in_buf = 0, i = 0;
struct diag_dci_data_info *temp_data = dci_data_smd;
- int buf_size = (DEBUG_BUF_SIZE < count) ? DEBUG_BUF_SIZE : count;
+ unsigned int buf_size;
+ buf_size = (DEBUG_BUF_SIZE < count) ? DEBUG_BUF_SIZE : count;
if (diag_dbgfs_dci_finished) {
diag_dbgfs_dci_finished = 0;
@@ -211,6 +212,7 @@
return -ENOMEM;
}
+ buf_size = ksize(buf);
bytes_remaining = buf_size;
if (diag_dbgfs_dci_data_index == 0) {
@@ -287,6 +289,7 @@
{
char *buf;
int ret;
+ unsigned int buf_size;
buf = kzalloc(sizeof(char) * DEBUG_BUF_SIZE, GFP_KERNEL);
if (!buf) {
@@ -294,7 +297,8 @@
return -ENOMEM;
}
- ret = scnprintf(buf, DEBUG_BUF_SIZE,
+ buf_size = ksize(buf);
+ ret = scnprintf(buf, buf_size,
"Pending status for work_stucts:\n"
"diag_drain_work: %d\n"
"Modem data diag_read_smd_work: %d\n"
@@ -342,7 +346,7 @@
diag_notify_update_smd_work)));
#ifdef CONFIG_DIAG_OVER_USB
- ret += scnprintf(buf+ret, DEBUG_BUF_SIZE,
+ ret += scnprintf(buf+ret, buf_size-ret,
"diag_proc_hdlc_work: %d\n"
"diag_read_work: %d\n",
work_pending(&(driver->diag_proc_hdlc_work)),
@@ -363,7 +367,8 @@
unsigned int bytes_remaining;
unsigned int bytes_in_buffer = 0;
unsigned int bytes_written;
- int buf_size = (DEBUG_BUF_SIZE < count) ? DEBUG_BUF_SIZE : count;
+ unsigned int buf_size;
+ buf_size = (DEBUG_BUF_SIZE < count) ? DEBUG_BUF_SIZE : count;
if (diag_dbgfs_table_index >= diag_max_reg) {
/* Done. Reset to prepare for future requests */
@@ -376,7 +381,7 @@
pr_err("diag: %s, Error allocating memory\n", __func__);
return -ENOMEM;
}
-
+ buf_size = ksize(buf);
bytes_remaining = buf_size;
if (diag_dbgfs_table_index == 0) {
@@ -385,6 +390,7 @@
"WCNSS: %d, APPS: %d\n",
MODEM_DATA, LPASS_DATA, WCNSS_DATA, APPS_DATA);
bytes_in_buffer += bytes_written;
+ bytes_remaining -= bytes_written;
}
for (i = diag_dbgfs_table_index; i < diag_max_reg; i++) {
@@ -428,14 +434,15 @@
{
char *buf = NULL;
int ret = 0, i = 0;
-
+ unsigned int buf_size;
buf = kzalloc(sizeof(char) * DEBUG_BUF_SIZE, GFP_KERNEL);
if (ZERO_OR_NULL_PTR(buf)) {
pr_err("diag: %s, Error allocating memory\n", __func__);
return -ENOMEM;
}
+ buf_size = ksize(buf);
- ret = scnprintf(buf, DEBUG_BUF_SIZE,
+ ret = scnprintf(buf, buf_size,
"POOL_TYPE_COPY: [0x%p : 0x%p] count = %d\n"
"POOL_TYPE_HDLC: [0x%p : 0x%p] count = %d\n"
"POOL_TYPE_USER: [0x%p : 0x%p] count = %d\n"
@@ -456,7 +463,7 @@
for (i = 0; i < MAX_HSIC_CH; i++) {
if (!diag_hsic[i].hsic_inited)
continue;
- ret += scnprintf(buf+ret, DEBUG_BUF_SIZE-ret,
+ ret += scnprintf(buf+ret, buf_size-ret,
"POOL_TYPE_HSIC_%d: [0x%p : 0x%p] count = %d\n",
i+1,
diag_hsic[i].diag_hsic_pool,
@@ -467,7 +474,7 @@
for (i = 0; i < MAX_HSIC_CH; i++) {
if (!diag_hsic[i].hsic_inited)
continue;
- ret += scnprintf(buf+ret, DEBUG_BUF_SIZE-ret,
+ ret += scnprintf(buf+ret, buf_size-ret,
"POOL_TYPE_HSIC_%d_WRITE: [0x%p : 0x%p] count = %d\n",
i+1,
diag_hsic[i].diag_hsic_write_pool,
@@ -486,6 +493,7 @@
{
char *buf = NULL;
int ret = 0;
+ unsigned int buf_size;
buf = kzalloc(sizeof(char) * DEBUG_BUF_SIZE, GFP_KERNEL);
if (ZERO_OR_NULL_PTR(buf)) {
@@ -493,7 +501,8 @@
return -ENOMEM;
}
- ret = scnprintf(buf, DEBUG_BUF_SIZE,
+ buf_size = ksize(buf);
+ ret = scnprintf(buf, buf_size,
"POOL_TYPE_COPY: [0x%p : 0x%p] count = %d\n"
"POOL_TYPE_HDLC: [0x%p : 0x%p] count = %d\n"
"POOL_TYPE_USER: [0x%p : 0x%p] count = %d\n"
@@ -528,10 +537,12 @@
unsigned int bytes_remaining;
unsigned int bytes_in_buffer = 0;
unsigned int bytes_written;
- int buf_size = (DEBUG_BUF_SIZE < count) ? DEBUG_BUF_SIZE : count;
+ unsigned int buf_size;
int bytes_hsic_inited = 45;
int bytes_hsic_not_inited = 410;
+ buf_size = (DEBUG_BUF_SIZE < count) ? DEBUG_BUF_SIZE : count;
+
if (diag_dbgfs_finished) {
diag_dbgfs_finished = 0;
return 0;
@@ -543,6 +554,7 @@
return -ENOMEM;
}
+ buf_size = ksize(buf);
bytes_remaining = buf_size;
/* Only one smux for now */
@@ -584,8 +596,8 @@
"in_busy_hsic_write: %d\n"
"count_hsic_pool: %d\n"
"count_hsic_write_pool: %d\n"
- "diag_hsic_pool: %x\n"
- "diag_hsic_write_pool: %x\n"
+ "diag_hsic_pool: %p\n"
+ "diag_hsic_write_pool: %p\n"
"HSIC write_len: %d\n"
"num_hsic_buf_tbl_entries: %d\n"
"HSIC usb_connected: %d\n"
@@ -602,8 +614,8 @@
diag_hsic[i].in_busy_hsic_write,
diag_hsic[i].count_hsic_pool,
diag_hsic[i].count_hsic_write_pool,
- (unsigned int)diag_hsic[i].diag_hsic_pool,
- (unsigned int)diag_hsic[i].diag_hsic_write_pool,
+ diag_hsic[i].diag_hsic_pool,
+ diag_hsic[i].diag_hsic_write_pool,
diag_bridge[i].write_len,
diag_hsic[i].num_hsic_buf_tbl_entries,
diag_bridge[i].usb_connected,
diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c
index 0c9797e..0e475c9 100644
--- a/drivers/char/diag/diagchar_core.c
+++ b/drivers/char/diag/diagchar_core.c
@@ -479,8 +479,8 @@
for (i = 0; i < diag_hsic[index].poolsize_hsic_write; i++) {
if (hsic_buf_tbl[i].length > 0) {
- pr_debug("diag: HSIC copy to user, i: %d, buf: %x, len: %d\n",
- i, (unsigned int)hsic_buf_tbl[i].buf,
+ pr_debug("diag: HSIC copy to user, i: %d, buf: %p, len: %d\n",
+ i, hsic_buf_tbl[i].buf,
hsic_buf_tbl[i].length);
num_data++;
@@ -943,6 +943,8 @@
for (i = 0; i < MAX_DCI_CLIENTS; i++) {
if (driver->dci_client_tbl[i].client == NULL) {
driver->dci_client_tbl[i].client = current;
+ driver->dci_client_tbl[i].client_id =
+ driver->dci_client_id;
driver->dci_client_tbl[i].list =
dci_params->list;
driver->dci_client_tbl[i].signal_type =
@@ -1043,7 +1045,7 @@
sizeof(struct diag_dci_health_stats)))
return -EFAULT;
mutex_lock(&dci_health_mutex);
- i = diag_dci_find_client_index(current->tgid);
+ i = diag_dci_find_client_index_health(stats.client_id);
if (i != DCI_CLIENT_INDEX_INVALID) {
dci_params = &(driver->dci_client_tbl[i]);
stats.dropped_logs = dci_params->dropped_logs;
@@ -1198,10 +1200,9 @@
for (i = 0; i < driver->buf_tbl_size; i++) {
if (driver->buf_tbl[i].length > 0) {
#ifdef DIAG_DEBUG
- pr_debug("diag: WRITING the buf address "
- "and length is %x , %d\n", (unsigned int)
- (driver->buf_tbl[i].buf),
- driver->buf_tbl[i].length);
+ pr_debug("diag: WRITING the buf address and length is %p , %d\n",
+ driver->buf_tbl[i].buf,
+ driver->buf_tbl[i].length);
#endif
num_data++;
/* Copy the length of data being passed */
@@ -1222,10 +1223,9 @@
ret += driver->buf_tbl[i].length;
drop:
#ifdef DIAG_DEBUG
- pr_debug("diag: DEQUEUE buf address and"
- " length is %x,%d\n", (unsigned int)
- (driver->buf_tbl[i].buf), driver->
- buf_tbl[i].length);
+ pr_debug("diag: DEQUEUE buf address and length is %p, %d\n",
+ driver->buf_tbl[i].buf,
+ driver->buf_tbl[i].length);
#endif
diagmem_free(driver, (unsigned char *)
(driver->buf_tbl[i].buf), POOL_TYPE_HDLC);
diff --git a/drivers/char/diag/diagfwd.c b/drivers/char/diag/diagfwd.c
index 395bea0..028f045 100644
--- a/drivers/char/diag/diagfwd.c
+++ b/drivers/char/diag/diagfwd.c
@@ -825,10 +825,9 @@
driver->buf_tbl[i].length =
driver->used;
#ifdef DIAG_DEBUG
- pr_debug("diag: ENQUEUE buf ptr"
- " and length is %x , %d\n",
- (unsigned int)(driver->buf_
- tbl[i].buf), driver->buf_tbl[i].length);
+ pr_debug("diag: ENQUEUE buf ptr and length is %p , %d\n",
+ driver->buf_tbl[i].buf,
+ driver->buf_tbl[i].length);
#endif
break;
}
@@ -860,9 +859,9 @@
if (foundIndex == -1)
err = -1;
else
- pr_debug("diag: ENQUEUE HSIC buf ptr and length is %x , %d, ch %d\n",
- (unsigned int)buf,
- diag_bridge[index].write_len, index);
+ pr_debug("diag: ENQUEUE HSIC buf ptr and length is %p , %d, ch %d\n",
+ buf, diag_bridge[index].write_len,
+ index);
}
#endif
for (i = 0; i < driver->num_clients; i++)
diff --git a/drivers/cpufreq/cpu-boost.c b/drivers/cpufreq/cpu-boost.c
index 8cd5ef9..f20510d 100644
--- a/drivers/cpufreq/cpu-boost.c
+++ b/drivers/cpufreq/cpu-boost.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2014, 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
@@ -17,6 +17,7 @@
#include <linux/init.h>
#include <linux/notifier.h>
#include <linux/cpufreq.h>
+#include <linux/cpu.h>
#include <linux/sched.h>
#include <linux/jiffies.h>
#include <linux/kthread.h>
@@ -62,6 +63,12 @@
* The CPUFREQ_ADJUST notifier is used to override the current policy min to
* make sure policy min >= boost_min. The cpufreq framework then does the job
* of enforcing the new policy.
+ *
+ * The sync kthread needs to run on the CPU in question to avoid deadlocks in
+ * the wake up code. Achieve this by binding the thread to the respective
+ * CPU. But a CPU going offline unbinds threads from that CPU. So, set it up
+ * again each time the CPU comes back up. We can use CPUFREQ_START to figure
+ * out a CPU is coming online instead of registering for hotplug notifiers.
*/
static int boost_adjust_notify(struct notifier_block *nb, unsigned long val, void *data)
{
@@ -72,22 +79,27 @@
unsigned int ib_min = s->input_boost_min;
unsigned int min;
- if (val != CPUFREQ_ADJUST)
- return NOTIFY_OK;
+ switch (val) {
+ case CPUFREQ_ADJUST:
+ if (!b_min && !ib_min)
+ break;
- if (!b_min && !ib_min)
- return NOTIFY_OK;
+ min = max(b_min, ib_min);
- min = max(b_min, ib_min);
+ pr_debug("CPU%u policy min before boost: %u kHz\n",
+ cpu, policy->min);
+ pr_debug("CPU%u boost min: %u kHz\n", cpu, min);
- pr_debug("CPU%u policy min before boost: %u kHz\n",
- cpu, policy->min);
- pr_debug("CPU%u boost min: %u kHz\n", cpu, min);
+ cpufreq_verify_within_limits(policy, min, UINT_MAX);
- cpufreq_verify_within_limits(policy, min, UINT_MAX);
+ pr_debug("CPU%u policy min after boost: %u kHz\n",
+ cpu, policy->min);
+ break;
- pr_debug("CPU%u policy min after boost: %u kHz\n",
- cpu, policy->min);
+ case CPUFREQ_START:
+ set_cpus_allowed(s->thread, *cpumask_of(cpu));
+ break;
+ }
return NOTIFY_OK;
}
@@ -165,9 +177,15 @@
s->boost_min = src_policy.cur;
}
/* Force policy re-evaluation to trigger adjust notifier. */
- cpufreq_update_policy(dest_cpu);
- queue_delayed_work_on(s->cpu, cpu_boost_wq,
- &s->boost_rem, msecs_to_jiffies(boost_ms));
+ get_online_cpus();
+ if (cpu_online(dest_cpu)) {
+ cpufreq_update_policy(dest_cpu);
+ queue_delayed_work_on(dest_cpu, cpu_boost_wq,
+ &s->boost_rem, msecs_to_jiffies(boost_ms));
+ } else {
+ s->boost_min = 0;
+ }
+ put_online_cpus();
}
return 0;
@@ -202,6 +220,7 @@
struct cpu_sync *i_sync_info;
struct cpufreq_policy policy;
+ get_online_cpus();
for_each_online_cpu(i) {
i_sync_info = &per_cpu(sync_info, i);
@@ -218,6 +237,7 @@
&i_sync_info->input_boost_rem,
msecs_to_jiffies(input_boost_ms));
}
+ put_online_cpus();
}
static void cpuboost_input_event(struct input_handle *handle,
@@ -332,6 +352,7 @@
INIT_DELAYED_WORK(&s->input_boost_rem, do_input_boost_rem);
s->thread = kthread_run(boost_mig_sync_thread, (void *)cpu,
"boost_sync/%d", cpu);
+ set_cpus_allowed(s->thread, *cpumask_of(cpu));
}
atomic_notifier_chain_register(&migration_notifier_head,
&boost_migration_nb);
diff --git a/drivers/gpio/qpnp-pin.c b/drivers/gpio/qpnp-pin.c
index 2753082..8d934df 100644
--- a/drivers/gpio/qpnp-pin.c
+++ b/drivers/gpio/qpnp-pin.c
@@ -55,11 +55,13 @@
#define Q_GPIO_SUBTYPE_GPIOC_8CH 0xD
/* mpp peripheral type and subtype values */
-#define Q_MPP_TYPE 0x11
-#define Q_MPP_SUBTYPE_4CH_NO_ANA_OUT 0x3
-#define Q_MPP_SUBTYPE_4CH_NO_SINK 0x5
-#define Q_MPP_SUBTYPE_4CH_FULL_FUNC 0x7
-#define Q_MPP_SUBTYPE_8CH_FULL_FUNC 0xF
+#define Q_MPP_TYPE 0x11
+#define Q_MPP_SUBTYPE_4CH_NO_ANA_OUT 0x3
+#define Q_MPP_SUBTYPE_ULT_4CH_NO_ANA_OUT 0x4
+#define Q_MPP_SUBTYPE_4CH_NO_SINK 0x5
+#define Q_MPP_SUBTYPE_ULT_4CH_NO_SINK 0x6
+#define Q_MPP_SUBTYPE_4CH_FULL_FUNC 0x7
+#define Q_MPP_SUBTYPE_8CH_FULL_FUNC 0xF
/* control register base address offsets */
#define Q_REG_MODE_CTL 0x40
@@ -235,22 +237,29 @@
static int qpnp_pin_check_config(enum qpnp_pin_param_type idx,
struct qpnp_pin_spec *q_spec, uint32_t val)
{
+ u8 subtype = q_spec->subtype;
+
switch (idx) {
case Q_PIN_CFG_MODE:
if (q_spec->type == Q_GPIO_TYPE &&
val >= QPNP_PIN_GPIO_MODE_INVALID)
return -EINVAL;
- else if (q_spec->type == Q_MPP_TYPE &&
- val >= QPNP_PIN_MPP_MODE_INVALID)
+ else if (q_spec->type == Q_MPP_TYPE) {
+ if (val >= QPNP_PIN_MPP_MODE_INVALID)
return -EINVAL;
+ if ((subtype == Q_MPP_SUBTYPE_ULT_4CH_NO_ANA_OUT ||
+ subtype == Q_MPP_SUBTYPE_ULT_4CH_NO_SINK) &&
+ (val == QPNP_PIN_MODE_BIDIR))
+ return -ENXIO;
+ }
break;
case Q_PIN_CFG_OUTPUT_TYPE:
if (q_spec->type != Q_GPIO_TYPE)
return -ENXIO;
if ((val == QPNP_PIN_OUT_BUF_OPEN_DRAIN_NMOS ||
val == QPNP_PIN_OUT_BUF_OPEN_DRAIN_PMOS) &&
- (q_spec->subtype == Q_GPIO_SUBTYPE_GPIOC_4CH ||
- (q_spec->subtype == Q_GPIO_SUBTYPE_GPIOC_8CH)))
+ (subtype == Q_GPIO_SUBTYPE_GPIOC_4CH ||
+ (subtype == Q_GPIO_SUBTYPE_GPIOC_8CH)))
return -EINVAL;
else if (val >= QPNP_PIN_OUT_BUF_INVALID)
return -EINVAL;
@@ -263,22 +272,28 @@
if (q_spec->type == Q_GPIO_TYPE &&
val >= QPNP_PIN_GPIO_PULL_INVALID)
return -EINVAL;
- if (q_spec->type == Q_MPP_TYPE &&
- val >= QPNP_PIN_MPP_PULL_INVALID)
- return -EINVAL;
+ if (q_spec->type == Q_MPP_TYPE) {
+ if (val >= QPNP_PIN_MPP_PULL_INVALID)
+ return -EINVAL;
+ if (subtype == Q_MPP_SUBTYPE_ULT_4CH_NO_ANA_OUT ||
+ subtype == Q_MPP_SUBTYPE_ULT_4CH_NO_SINK)
+ return -ENXIO;
+ }
break;
case Q_PIN_CFG_VIN_SEL:
if (val >= QPNP_PIN_VIN_8CH_INVALID)
return -EINVAL;
else if (val >= QPNP_PIN_VIN_4CH_INVALID) {
if (q_spec->type == Q_GPIO_TYPE &&
- (q_spec->subtype == Q_GPIO_SUBTYPE_GPIO_4CH ||
- q_spec->subtype == Q_GPIO_SUBTYPE_GPIOC_4CH))
+ (subtype == Q_GPIO_SUBTYPE_GPIO_4CH ||
+ subtype == Q_GPIO_SUBTYPE_GPIOC_4CH))
return -EINVAL;
if (q_spec->type == Q_MPP_TYPE &&
- (q_spec->subtype == Q_MPP_SUBTYPE_4CH_NO_ANA_OUT ||
- q_spec->subtype == Q_MPP_SUBTYPE_4CH_NO_SINK ||
- q_spec->subtype == Q_MPP_SUBTYPE_4CH_FULL_FUNC))
+ (subtype == Q_MPP_SUBTYPE_4CH_NO_ANA_OUT ||
+ subtype == Q_MPP_SUBTYPE_4CH_NO_SINK ||
+ subtype == Q_MPP_SUBTYPE_4CH_FULL_FUNC ||
+ subtype == Q_MPP_SUBTYPE_ULT_4CH_NO_ANA_OUT ||
+ subtype == Q_MPP_SUBTYPE_ULT_4CH_NO_SINK))
return -EINVAL;
}
break;
@@ -304,7 +319,8 @@
case Q_PIN_CFG_AOUT_REF:
if (q_spec->type != Q_MPP_TYPE)
return -ENXIO;
- if (q_spec->subtype == Q_MPP_SUBTYPE_4CH_NO_ANA_OUT)
+ if (subtype == Q_MPP_SUBTYPE_4CH_NO_ANA_OUT ||
+ subtype == Q_MPP_SUBTYPE_ULT_4CH_NO_ANA_OUT)
return -ENXIO;
if (val >= QPNP_PIN_AOUT_REF_INVALID)
return -EINVAL;
@@ -318,7 +334,8 @@
case Q_PIN_CFG_CS_OUT:
if (q_spec->type != Q_MPP_TYPE)
return -ENXIO;
- if (q_spec->subtype == Q_MPP_SUBTYPE_4CH_NO_SINK)
+ if (subtype == Q_MPP_SUBTYPE_4CH_NO_SINK ||
+ subtype == Q_MPP_SUBTYPE_ULT_4CH_NO_SINK)
return -ENXIO;
if (val >= QPNP_PIN_CS_OUT_INVALID)
return -EINVAL;
@@ -410,9 +427,11 @@
else if (q_spec->type == Q_MPP_TYPE)
switch (q_spec->subtype) {
case Q_MPP_SUBTYPE_4CH_NO_SINK:
+ case Q_MPP_SUBTYPE_ULT_4CH_NO_SINK:
q_spec->num_ctl_regs = 12;
break;
case Q_MPP_SUBTYPE_4CH_NO_ANA_OUT:
+ case Q_MPP_SUBTYPE_ULT_4CH_NO_ANA_OUT:
case Q_MPP_SUBTYPE_4CH_FULL_FUNC:
case Q_MPP_SUBTYPE_8CH_FULL_FUNC:
q_spec->num_ctl_regs = 13;
@@ -1144,7 +1163,9 @@
else if (q_spec->type == Q_MPP_TYPE)
switch (q_spec->subtype) {
case Q_MPP_SUBTYPE_4CH_NO_ANA_OUT:
+ case Q_MPP_SUBTYPE_ULT_4CH_NO_ANA_OUT:
case Q_MPP_SUBTYPE_4CH_NO_SINK:
+ case Q_MPP_SUBTYPE_ULT_4CH_NO_SINK:
case Q_MPP_SUBTYPE_4CH_FULL_FUNC:
case Q_MPP_SUBTYPE_8CH_FULL_FUNC:
return 1;
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index 10eaf4e..0d88689 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -2336,15 +2336,33 @@
const char *buf, size_t count)
{
struct adreno_device *adreno_dev = _get_adreno_dev(dev);
- int ret;
+ int ret = 0;
+ unsigned int policy = 0;
if (adreno_dev == NULL)
return 0;
mutex_lock(&adreno_dev->dev.mutex);
- ret = _ft_sysfs_store(buf, count, &adreno_dev->ft_pf_policy);
+
+ /* MMU option changed call function to reset MMU options */
+ if (count != _ft_sysfs_store(buf, count, &policy))
+ ret = -EINVAL;
+
+ if (!ret) {
+ policy &= (KGSL_FT_PAGEFAULT_INT_ENABLE |
+ KGSL_FT_PAGEFAULT_GPUHALT_ENABLE |
+ KGSL_FT_PAGEFAULT_LOG_ONE_PER_PAGE |
+ KGSL_FT_PAGEFAULT_LOG_ONE_PER_INT);
+ ret = kgsl_mmu_set_pagefault_policy(&(adreno_dev->dev.mmu),
+ adreno_dev->ft_pf_policy);
+ if (!ret)
+ adreno_dev->ft_pf_policy = policy;
+ }
mutex_unlock(&adreno_dev->dev.mutex);
- return ret;
+ if (!ret)
+ return count;
+ else
+ return 0;
}
/**
@@ -2635,12 +2653,56 @@
return status;
}
-static int adreno_setproperty(struct kgsl_device *device,
+static int adreno_set_constraint(struct kgsl_device *device,
+ struct kgsl_context *context,
+ struct kgsl_device_constraint *constraint)
+{
+ int status = 0;
+
+ switch (constraint->type) {
+ case KGSL_CONSTRAINT_PWRLEVEL: {
+ struct kgsl_device_constraint_pwrlevel pwr;
+
+ if (constraint->size != sizeof(pwr)) {
+ status = -EINVAL;
+ break;
+ }
+
+ if (copy_from_user(&pwr,
+ (void __user *)constraint->data,
+ sizeof(pwr))) {
+ status = -EFAULT;
+ break;
+ }
+ if (pwr.level >= KGSL_CONSTRAINT_PWR_MAXLEVELS) {
+ status = -EINVAL;
+ break;
+ }
+
+ context->pwr_constraint.type =
+ KGSL_CONSTRAINT_PWRLEVEL;
+ context->pwr_constraint.sub_type = pwr.level;
+ }
+ break;
+ case KGSL_CONSTRAINT_NONE:
+ context->pwr_constraint.type = KGSL_CONSTRAINT_NONE;
+ break;
+
+ default:
+ status = -EINVAL;
+ break;
+ }
+
+ return status;
+}
+
+static int adreno_setproperty(struct kgsl_device_private *dev_priv,
enum kgsl_property_type type,
void *value,
unsigned int sizebytes)
{
int status = -EINVAL;
+ struct kgsl_device *device = dev_priv->device;
struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
switch (type) {
@@ -2678,6 +2740,28 @@
status = 0;
}
break;
+ case KGSL_PROP_PWR_CONSTRAINT: {
+ struct kgsl_device_constraint constraint;
+ struct kgsl_context *context;
+
+ if (sizebytes != sizeof(constraint))
+ break;
+
+ if (copy_from_user(&constraint, value,
+ sizeof(constraint))) {
+ status = -EFAULT;
+ break;
+ }
+
+ context = kgsl_context_get_owner(dev_priv,
+ constraint.context_id);
+ if (context == NULL)
+ break;
+ status = adreno_set_constraint(device, context,
+ &constraint);
+ kgsl_context_put(context);
+ }
+ break;
default:
break;
}
diff --git a/drivers/gpu/msm/adreno_drawctxt.c b/drivers/gpu/msm/adreno_drawctxt.c
index 1b5573f..4db045a 100644
--- a/drivers/gpu/msm/adreno_drawctxt.c
+++ b/drivers/gpu/msm/adreno_drawctxt.c
@@ -271,15 +271,13 @@
}
static int _check_global_timestamp(struct kgsl_device *device,
- unsigned int timestamp)
+ struct adreno_context *drawctxt, unsigned int timestamp)
{
- int ret;
+ /* Stop waiting if the context is invalidated */
+ if (drawctxt->state == ADRENO_CONTEXT_STATE_INVALID)
+ return 1;
- mutex_lock(&device->mutex);
- ret = kgsl_check_timestamp(device, NULL, timestamp);
- mutex_unlock(&device->mutex);
-
- return ret;
+ return kgsl_check_timestamp(device, NULL, timestamp);
}
int adreno_drawctxt_wait_global(struct adreno_device *adreno_dev,
@@ -288,7 +286,7 @@
{
struct kgsl_device *device = &adreno_dev->dev;
struct adreno_context *drawctxt = ADRENO_CONTEXT(context);
- int ret;
+ int ret = 0;
/* Needs to hold the device mutex */
BUG_ON(!mutex_is_locked(&device->mutex));
@@ -298,6 +296,15 @@
goto done;
}
+ /*
+ * If the context is invalid then return immediately - we may end up
+ * waiting for a timestamp that will never come
+ */
+ if (drawctxt->state == ADRENO_CONTEXT_STATE_INVALID) {
+ kgsl_context_put(context);
+ goto done;
+ }
+
trace_adreno_drawctxt_wait_start(KGSL_MEMSTORE_GLOBAL, timestamp);
ret = kgsl_add_event(device, KGSL_MEMSTORE_GLOBAL, timestamp,
@@ -311,7 +318,7 @@
if (timeout) {
ret = (int) wait_event_timeout(drawctxt->waiting,
- _check_global_timestamp(device, timestamp),
+ _check_global_timestamp(device, drawctxt, timestamp),
msecs_to_jiffies(timeout));
if (ret == 0)
@@ -320,7 +327,7 @@
ret = 0;
} else {
wait_event(drawctxt->waiting,
- _check_global_timestamp(device, timestamp));
+ _check_global_timestamp(device, drawctxt, timestamp));
}
mutex_lock(&device->mutex);
@@ -425,7 +432,8 @@
KGSL_CONTEXT_PER_CONTEXT_TS |
KGSL_CONTEXT_USER_GENERATED_TS |
KGSL_CONTEXT_NO_FAULT_TOLERANCE |
- KGSL_CONTEXT_TYPE_MASK);
+ KGSL_CONTEXT_TYPE_MASK |
+ KGSL_CONTEXT_PWR_CONSTRAINT);
/* Always enable per-context timestamps */
drawctxt->base.flags |= KGSL_CONTEXT_PER_CONTEXT_TS;
diff --git a/drivers/gpu/msm/adreno_ringbuffer.c b/drivers/gpu/msm/adreno_ringbuffer.c
index b23d3ab..8d7b803 100644
--- a/drivers/gpu/msm/adreno_ringbuffer.c
+++ b/drivers/gpu/msm/adreno_ringbuffer.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002,2007-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2002,2007-2014, 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
@@ -1132,6 +1132,65 @@
return ret;
}
+unsigned int adreno_ringbuffer_get_constraint(struct kgsl_device *device,
+ struct kgsl_context *context)
+{
+ unsigned int pwrlevel = device->pwrctrl.active_pwrlevel;
+
+ switch (context->pwr_constraint.type) {
+ case KGSL_CONSTRAINT_PWRLEVEL: {
+ switch (context->pwr_constraint.sub_type) {
+ case KGSL_CONSTRAINT_PWR_MAX:
+ pwrlevel = device->pwrctrl.max_pwrlevel;
+ break;
+ case KGSL_CONSTRAINT_PWR_MIN:
+ pwrlevel = device->pwrctrl.min_pwrlevel;
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+
+ }
+
+ return pwrlevel;
+}
+
+void adreno_ringbuffer_set_constraint(struct kgsl_device *device,
+ struct kgsl_cmdbatch *cmdbatch)
+{
+ unsigned int constraint;
+ struct kgsl_context *context = cmdbatch->context;
+ /*
+ * Check if the context has a constraint and constraint flags are
+ * set.
+ */
+ if (context->pwr_constraint.type &&
+ ((context->flags & KGSL_CONTEXT_PWR_CONSTRAINT) ||
+ (cmdbatch->flags & KGSL_CONTEXT_PWR_CONSTRAINT))) {
+
+ constraint = adreno_ringbuffer_get_constraint(device, context);
+
+ /*
+ * If a constraint is already set, set a new
+ * constraint only if it is faster
+ */
+ if ((device->pwrctrl.constraint.type ==
+ KGSL_CONSTRAINT_NONE) || (constraint <
+ device->pwrctrl.constraint.hint.pwrlevel.level)) {
+
+ kgsl_pwrctrl_pwrlevel_change(device, constraint);
+ device->pwrctrl.constraint.type =
+ context->pwr_constraint.type;
+ device->pwrctrl.constraint.hint.
+ pwrlevel.level = constraint;
+ }
+
+ }
+
+}
+
/* adreno_rindbuffer_submitcmd - submit userspace IBs to the GPU */
int adreno_ringbuffer_submitcmd(struct adreno_device *adreno_dev,
struct kgsl_cmdbatch *cmdbatch)
@@ -1242,6 +1301,9 @@
test_bit(ADRENO_DEVICE_PWRON_FIXUP, &adreno_dev->priv))
flags |= KGSL_CMD_FLAGS_PWRON_FIXUP;
+ /* Set the constraints before adding to ringbuffer */
+ adreno_ringbuffer_set_constraint(device, cmdbatch);
+
ret = adreno_ringbuffer_addcmds(&adreno_dev->ringbuffer,
drawctxt,
flags,
diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c
index 1743e4a..11b7429 100644
--- a/drivers/gpu/msm/kgsl.c
+++ b/drivers/gpu/msm/kgsl.c
@@ -1379,8 +1379,8 @@
if (dev_priv->device->ftbl->setproperty)
result = dev_priv->device->ftbl->setproperty(
- dev_priv->device, param->type,
- param->value, param->sizebytes);
+ dev_priv, param->type, param->value,
+ param->sizebytes);
return result;
}
diff --git a/drivers/gpu/msm/kgsl_device.h b/drivers/gpu/msm/kgsl_device.h
index 7fc6fae..7d009ce 100644
--- a/drivers/gpu/msm/kgsl_device.h
+++ b/drivers/gpu/msm/kgsl_device.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002,2007-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2002,2007-2014, 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
@@ -129,7 +129,7 @@
void (*drawctxt_destroy) (struct kgsl_context *context);
long (*ioctl) (struct kgsl_device_private *dev_priv,
unsigned int cmd, void *data);
- int (*setproperty) (struct kgsl_device *device,
+ int (*setproperty) (struct kgsl_device_private *dev_priv,
enum kgsl_property_type type, void *value,
unsigned int sizebytes);
int (*postmortem_dump) (struct kgsl_device *device, int manual);
@@ -349,6 +349,7 @@
* @pagefault_ts: global timestamp of the pagefault, if KGSL_CONTEXT_PAGEFAULT
* is set.
* @flags: flags from userspace controlling the behavior of this context
+ * @pwr_constraint: power constraint from userspace for this context
*/
struct kgsl_context {
struct kref refcount;
@@ -366,6 +367,7 @@
struct list_head events_list;
unsigned int pagefault_ts;
unsigned int flags;
+ struct kgsl_pwr_constraint pwr_constraint;
};
/**
diff --git a/drivers/gpu/msm/kgsl_iommu.c b/drivers/gpu/msm/kgsl_iommu.c
index 8f65705..0a7ba30 100755
--- a/drivers/gpu/msm/kgsl_iommu.c
+++ b/drivers/gpu/msm/kgsl_iommu.c
@@ -2103,6 +2103,72 @@
return iommu->unit_count;
}
+/*
+ * kgsl_iommu_set_pf_policy() - Set the pagefault policy for IOMMU
+ * @mmu: Pointer to mmu structure
+ * @pf_policy: The pagefault polict to set
+ *
+ * Check if the new policy indicated by pf_policy is same as current
+ * policy, if same then return else set the policy
+ */
+static int kgsl_iommu_set_pf_policy(struct kgsl_mmu *mmu,
+ unsigned int pf_policy)
+{
+ int i, j;
+ struct kgsl_iommu *iommu = mmu->priv;
+ struct adreno_device *adreno_dev = ADRENO_DEVICE(mmu->device);
+ int ret = 0;
+ unsigned int sctlr_val;
+
+ if ((adreno_dev->ft_pf_policy & KGSL_FT_PAGEFAULT_GPUHALT_ENABLE) ==
+ (pf_policy & KGSL_FT_PAGEFAULT_GPUHALT_ENABLE))
+ return ret;
+ if (msm_soc_version_supports_iommu_v0())
+ return ret;
+
+ ret = kgsl_iommu_enable_clk(mmu, KGSL_IOMMU_CONTEXT_USER);
+
+ if (ret) {
+ KGSL_DRV_ERR(mmu->device, "Failed to enable iommu clocks\n");
+ return ret;
+ }
+ ret = kgsl_iommu_enable_clk(mmu, KGSL_IOMMU_CONTEXT_PRIV);
+
+ if (ret) {
+ KGSL_DRV_ERR(mmu->device, "Failed to enable iommu clocks\n");
+ kgsl_iommu_disable_clk_on_ts(mmu, 0, false);
+ return ret;
+ }
+ /* Need to idle device before changing options */
+ ret = mmu->device->ftbl->idle(mmu->device);
+ if (ret) {
+ kgsl_iommu_disable_clk_on_ts(mmu, 0, false);
+ return ret;
+ }
+
+ for (i = 0; i < iommu->unit_count; i++) {
+ struct kgsl_iommu_unit *iommu_unit = &iommu->iommu_units[i];
+ for (j = 0; j < iommu_unit->dev_count; j++) {
+ sctlr_val = KGSL_IOMMU_GET_CTX_REG(iommu,
+ iommu_unit,
+ iommu_unit->dev[j].ctx_id,
+ SCTLR);
+ if (pf_policy & KGSL_FT_PAGEFAULT_GPUHALT_ENABLE)
+ sctlr_val &= ~(0x1 <<
+ KGSL_IOMMU_SCTLR_HUPCF_SHIFT);
+ else
+ sctlr_val |= (0x1 <<
+ KGSL_IOMMU_SCTLR_HUPCF_SHIFT);
+ KGSL_IOMMU_SET_CTX_REG(iommu,
+ iommu_unit,
+ iommu_unit->dev[j].ctx_id,
+ SCTLR, sctlr_val);
+ }
+ }
+ kgsl_iommu_disable_clk_on_ts(mmu, 0, false);
+ return ret;
+}
+
struct kgsl_mmu_ops iommu_ops = {
.mmu_init = kgsl_iommu_init,
.mmu_close = kgsl_iommu_close,
@@ -2128,6 +2194,7 @@
.mmu_cleanup_pt = NULL,
.mmu_sync_lock = kgsl_iommu_sync_lock,
.mmu_sync_unlock = kgsl_iommu_sync_unlock,
+ .mmu_set_pf_policy = kgsl_iommu_set_pf_policy,
};
struct kgsl_mmu_pt_ops iommu_pt_ops = {
diff --git a/drivers/gpu/msm/kgsl_mmu.h b/drivers/gpu/msm/kgsl_mmu.h
index 8bc9962..040a3a7 100644
--- a/drivers/gpu/msm/kgsl_mmu.h
+++ b/drivers/gpu/msm/kgsl_mmu.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002,2007-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2002,2007-2014, 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
@@ -173,6 +173,7 @@
unsigned int (*mmu_sync_unlock)
(struct kgsl_mmu *mmu, unsigned int *cmds);
int (*mmu_hw_halt_supported)(struct kgsl_mmu *mmu, int iommu_unit_num);
+ int (*mmu_set_pf_policy)(struct kgsl_mmu *mmu, unsigned int pf_policy);
};
struct kgsl_mmu_pt_ops {
@@ -477,4 +478,13 @@
return 0;
}
+static inline int kgsl_mmu_set_pagefault_policy(struct kgsl_mmu *mmu,
+ unsigned int pf_policy)
+{
+ if (mmu->mmu_ops && mmu->mmu_ops->mmu_set_pf_policy)
+ return mmu->mmu_ops->mmu_set_pf_policy(mmu, pf_policy);
+ else
+ return 0;
+}
+
#endif /* __KGSL_MMU_H */
diff --git a/drivers/gpu/msm/kgsl_pwrctrl.h b/drivers/gpu/msm/kgsl_pwrctrl.h
index 6ec809d..c811b78 100644
--- a/drivers/gpu/msm/kgsl_pwrctrl.h
+++ b/drivers/gpu/msm/kgsl_pwrctrl.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2010-2014, 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
@@ -27,6 +27,9 @@
#define KGSL_MAX_CLKS 6
+/* Only two supported levels, min & max */
+#define KGSL_CONSTRAINT_PWR_MAXLEVELS 2
+
struct platform_device;
struct kgsl_clk_stats {
@@ -40,6 +43,16 @@
unsigned int elapsed_old;
};
+struct kgsl_pwr_constraint {
+ unsigned int type;
+ unsigned int sub_type;
+ union {
+ struct {
+ unsigned int level;
+ } pwrlevel;
+ } hint;
+};
+
/**
* struct kgsl_pwrctrl - Power control settings for a KGSL device
* @interrupt_num - The interrupt number for the device
@@ -67,6 +80,7 @@
* @bus_control - true if the bus calculation is independent
* @bus_index - default bus index into the bus_ib table
* @bus_ib - the set of unique ib requests needed for the bus calculation
+ * @constraint - currently active power constraint
*/
struct kgsl_pwrctrl {
@@ -98,6 +112,7 @@
int bus_mod;
unsigned int bus_index[KGSL_MAX_PWRLEVELS];
uint64_t bus_ib[KGSL_MAX_PWRLEVELS];
+ struct kgsl_pwr_constraint constraint;
};
void kgsl_pwrctrl_irq(struct kgsl_device *device, int state);
diff --git a/drivers/gpu/msm/kgsl_pwrscale.c b/drivers/gpu/msm/kgsl_pwrscale.c
index 52732cf..acee4d4 100644
--- a/drivers/gpu/msm/kgsl_pwrscale.c
+++ b/drivers/gpu/msm/kgsl_pwrscale.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2010-2014, 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
@@ -228,6 +228,10 @@
}
kgsl_pwrctrl_pwrlevel_change(device, level);
+
+ /*Invalidate the constraint set */
+ pwr->constraint.type = KGSL_CONSTRAINT_NONE;
+
*freq = kgsl_pwrctrl_active_freq(pwr);
mutex_unlock(&device->mutex);
diff --git a/drivers/i2c/busses/i2c-qup.c b/drivers/i2c/busses/i2c-qup.c
index d9a332e..1704105 100644
--- a/drivers/i2c/busses/i2c-qup.c
+++ b/drivers/i2c/busses/i2c-qup.c
@@ -22,6 +22,7 @@
#include <linux/err.h>
#include <linux/init.h>
#include <linux/i2c.h>
+#include <linux/i2c/i2c-qup.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
@@ -1853,11 +1854,18 @@
};
/* QUP may be needed to bring up other drivers */
-static int __init
-qup_i2c_init_driver(void)
+int __init qup_i2c_init_driver(void)
{
+ static bool initialized;
+
+ if (initialized)
+ return 0;
+ else
+ initialized = true;
+
return platform_driver_register(&qup_i2c_driver);
}
+EXPORT_SYMBOL(qup_i2c_init_driver);
arch_initcall(qup_i2c_init_driver);
static void __exit qup_i2c_exit_driver(void)
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index 716ea0d..0c22694 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -73,6 +73,16 @@
To compile this driver as a module, choose M here: the
module will be called bma150.
+config INPUT_HBTP_INPUT
+ tristate "HBTP input driver support"
+ help
+ Say Y to enable HBTP input driver.
+
+ To compile this driver as a module, choose M here: the
+ module will be called hbtp_input.
+
+endif
+
config INPUT_PCSPKR
tristate "PC Speaker support"
depends on PCSPKR_PLATFORM
@@ -714,4 +724,3 @@
To compile this driver as a module, choose M here: the
module will be called CM36283.
-endif
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
index c927e0e..c9a65fc 100644
--- a/drivers/input/misc/Makefile
+++ b/drivers/input/misc/Makefile
@@ -26,6 +26,7 @@
obj-$(CONFIG_INPUT_GP2A) += gp2ap002a00f.o
obj-$(CONFIG_INPUT_GPIO_TILT_POLLED) += gpio_tilt_polled.o
obj-$(CONFIG_INPUT_GPIO) += gpio_event.o gpio_matrix.o gpio_input.o gpio_output.o gpio_axis.o
+obj-$(CONFIG_INPUT_HBTP_INPUT) += hbtp_input.o
obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o
obj-$(CONFIG_INPUT_IXP4XX_BEEPER) += ixp4xx-beeper.o
obj-$(CONFIG_INPUT_KEYCHORD) += keychord.o
diff --git a/drivers/input/misc/hbtp_input.c b/drivers/input/misc/hbtp_input.c
new file mode 100644
index 0000000..83ba652
--- /dev/null
+++ b/drivers/input/misc/hbtp_input.c
@@ -0,0 +1,477 @@
+
+/* Copyright (c) 2014, 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/poll.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/miscdevice.h>
+#include <linux/hbtp_input.h>
+#include <linux/input/mt.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+#include "../input-compat.h"
+
+#if defined(CONFIG_FB)
+#include <linux/notifier.h>
+#include <linux/fb.h>
+#endif
+
+#define HBTP_INPUT_NAME "hbtp_input"
+#define HBTP_AFE_LOAD_UA 150000
+#define HBTP_AFE_VTG_MIN_UV 2700000
+#define HBTP_AFE_VTG_MAX_UV 3300000
+
+struct hbtp_data {
+ struct platform_device *pdev;
+ struct input_dev *input_dev;
+ s32 count;
+ bool touch_status[HBTP_MAX_FINGER];
+#if defined(CONFIG_FB)
+ struct notifier_block fb_notif;
+#endif
+ struct regulator *vcc_ana;
+};
+
+static struct hbtp_data *hbtp;
+
+#if defined(CONFIG_FB)
+static int fb_notifier_callback(struct notifier_block *self,
+ unsigned long event, void *data)
+{
+ int blank;
+ struct fb_event *evdata = data;
+ struct hbtp_data *hbtp_data =
+ container_of(self, struct hbtp_data, fb_notif);
+
+ if (evdata && evdata->data && event == FB_EVENT_BLANK &&
+ hbtp_data && hbtp_data->input_dev) {
+ blank = *(int *)(evdata->data);
+ if (blank == FB_BLANK_UNBLANK)
+ kobject_uevent(&hbtp_data->input_dev->dev.kobj,
+ KOBJ_ONLINE);
+ else if (blank == FB_BLANK_POWERDOWN)
+ kobject_uevent(&hbtp_data->input_dev->dev.kobj,
+ KOBJ_OFFLINE);
+ }
+
+ return 0;
+}
+#endif
+
+static int hbtp_input_open(struct inode *inode, struct file *file)
+{
+ if (hbtp->count) {
+ pr_err("%s is busy\n", HBTP_INPUT_NAME);
+ return -EBUSY;
+ }
+ hbtp->count++;
+
+ return 0;
+}
+
+static int hbtp_input_release(struct inode *inode, struct file *file)
+{
+ if (!hbtp->count) {
+ pr_err("%s wasn't opened\n", HBTP_INPUT_NAME);
+ return -ENOTTY;
+ }
+ hbtp->count--;
+
+ return 0;
+}
+
+static int hbtp_input_create_input_dev(struct hbtp_input_absinfo *absinfo)
+{
+ struct input_dev *input_dev;
+ struct hbtp_input_absinfo *abs;
+ int error;
+ int i;
+
+ input_dev = input_allocate_device();
+ if (!input_dev) {
+ pr_err("%s: input_allocate_device failed\n", __func__);
+ return -ENOMEM;
+ }
+
+ kfree(input_dev->name);
+ input_dev->name = kstrndup(HBTP_INPUT_NAME, sizeof(HBTP_INPUT_NAME),
+ GFP_KERNEL);
+ __set_bit(EV_ABS, input_dev->evbit);
+ __set_bit(EV_KEY, input_dev->evbit);
+ __set_bit(BTN_TOUCH, input_dev->keybit);
+ __set_bit(INPUT_PROP_DIRECT, input_dev->propbit);
+
+ /* For multi touch */
+ input_mt_init_slots(input_dev, HBTP_MAX_FINGER);
+ for (i = 0; i <= ABS_MT_LAST - ABS_MT_FIRST; i++) {
+ abs = absinfo + i;
+ if (abs->active)
+ input_set_abs_params(input_dev, abs->code,
+ abs->minimum, abs->maximum, 0, 0);
+ }
+
+ error = input_register_device(input_dev);
+ if (error) {
+ pr_err("%s: input_register_device failed\n", __func__);
+ goto err_input_reg_dev;
+ }
+
+ hbtp->input_dev = input_dev;
+ return 0;
+
+err_input_reg_dev:
+ input_free_device(input_dev);
+
+ return error;
+}
+
+static int hbtp_input_report_events(struct hbtp_data *hbtp_data,
+ struct hbtp_input_mt *mt_data)
+{
+ int i;
+ struct hbtp_input_touch *tch;
+
+ for (i = 0; i < HBTP_MAX_FINGER; i++) {
+ tch = &(mt_data->touches[i]);
+ if (tch->active || hbtp_data->touch_status[i]) {
+ input_mt_slot(hbtp_data->input_dev, i);
+ input_mt_report_slot_state(hbtp_data->input_dev,
+ MT_TOOL_FINGER, tch->active);
+
+ if (tch->active) {
+ input_report_abs(hbtp_data->input_dev,
+ ABS_MT_TOOL_TYPE,
+ tch->tool);
+ input_report_abs(hbtp_data->input_dev,
+ ABS_MT_TOUCH_MAJOR,
+ tch->major);
+ input_report_abs(hbtp_data->input_dev,
+ ABS_MT_TOUCH_MINOR,
+ tch->minor);
+ input_report_abs(hbtp_data->input_dev,
+ ABS_MT_ORIENTATION,
+ tch->orientation);
+ input_report_abs(hbtp_data->input_dev,
+ ABS_MT_PRESSURE,
+ tch->pressure);
+ input_report_abs(hbtp_data->input_dev,
+ ABS_MT_POSITION_X,
+ tch->x);
+ input_report_abs(hbtp_data->input_dev,
+ ABS_MT_POSITION_Y,
+ tch->y);
+ }
+ hbtp_data->touch_status[i] = tch->active;
+ }
+ }
+
+ input_report_key(hbtp->input_dev, BTN_TOUCH, mt_data->num_touches > 0);
+ input_sync(hbtp->input_dev);
+
+ return 0;
+}
+
+static int reg_set_optimum_mode_check(struct regulator *reg, int load_uA)
+{
+ return (regulator_count_voltages(reg) > 0) ?
+ regulator_set_optimum_mode(reg, load_uA) : 0;
+}
+
+static int hbtp_pdev_power_on(struct hbtp_data *hbtp, bool on)
+{
+ int ret, error;
+
+ if (!hbtp->vcc_ana) {
+ pr_err("%s: regulator is not available\n", __func__);
+ return -EINVAL;
+ }
+
+ if (!on)
+ goto reg_off;
+
+ ret = reg_set_optimum_mode_check(hbtp->vcc_ana, HBTP_AFE_LOAD_UA);
+ if (ret < 0) {
+ pr_err("%s: Regulator vcc_ana set_opt failed rc=%d\n",
+ __func__, ret);
+ return -EINVAL;
+ }
+
+ ret = regulator_enable(hbtp->vcc_ana);
+ if (ret) {
+ pr_err("%s: Regulator vcc_ana enable failed rc=%d\n",
+ __func__, ret);
+ error = -EINVAL;
+ goto error_reg_en_vcc_ana;
+ }
+
+ return 0;
+
+error_reg_en_vcc_ana:
+ reg_set_optimum_mode_check(hbtp->vcc_ana, 0);
+ return error;
+
+reg_off:
+ reg_set_optimum_mode_check(hbtp->vcc_ana, 0);
+ regulator_disable(hbtp->vcc_ana);
+ return 0;
+}
+
+static long hbtp_input_ioctl_handler(struct file *file, unsigned int cmd,
+ unsigned long arg, void __user *p)
+{
+ int error;
+ struct hbtp_input_mt mt_data;
+ struct hbtp_input_absinfo absinfo[ABS_MT_LAST - ABS_MT_FIRST + 1];
+ enum hbtp_afe_power_cmd power_cmd;
+
+ switch (cmd) {
+ case HBTP_SET_ABSPARAM:
+ if (hbtp && hbtp->input_dev) {
+ pr_err("%s: The input device is already created\n",
+ __func__);
+ return 0;
+ }
+
+ if (copy_from_user(absinfo, (void *)arg,
+ sizeof(struct hbtp_input_absinfo) *
+ (ABS_MT_LAST - ABS_MT_FIRST + 1))) {
+ pr_err("%s: Error copying data for ABS param\n",
+ __func__);
+ return -EFAULT;
+ }
+
+ error = hbtp_input_create_input_dev(absinfo);
+ if (error)
+ pr_err("%s, hbtp_input_create_input_dev failed (%d)\n",
+ __func__, error);
+ break;
+
+ case HBTP_SET_TOUCHDATA:
+ if (!hbtp || !hbtp->input_dev) {
+ pr_err("%s: The input device hasn't been created\n",
+ __func__);
+ return -EFAULT;
+ }
+
+ if (copy_from_user(&mt_data, (void *)arg,
+ sizeof(struct hbtp_input_mt))) {
+ pr_err("%s: Error copying data\n", __func__);
+ return -EFAULT;
+ }
+
+ hbtp_input_report_events(hbtp, &mt_data);
+ error = 0;
+ break;
+
+ case HBTP_SET_POWERSTATE:
+ if (!hbtp || !hbtp->input_dev) {
+ pr_err("%s: The input device hasn't been created\n",
+ __func__);
+ return -EFAULT;
+ }
+
+ if (copy_from_user(&power_cmd, (void *)arg,
+ sizeof(enum hbtp_afe_power_cmd))) {
+ pr_err("%s: Error copying data\n", __func__);
+ return -EFAULT;
+ }
+
+ switch (power_cmd) {
+ case HBTP_AFE_POWER_ON:
+ error = hbtp_pdev_power_on(hbtp, true);
+ if (error)
+ pr_err("%s: failed to power on\n", __func__);
+ break;
+ case HBTP_AFE_POWER_OFF:
+ error = hbtp_pdev_power_on(hbtp, false);
+ if (error)
+ pr_err("%s: failed to power off\n", __func__);
+ break;
+ default:
+ pr_err("%s: Unsupported command for power state, %d\n",
+ __func__, power_cmd);
+ return -EINVAL;
+ }
+ break;
+
+ default:
+ pr_err("%s: Unsupported ioctl command %u\n", __func__, cmd);
+ error = -EINVAL;
+ break;
+ }
+
+ return error;
+}
+
+static long hbtp_input_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ return hbtp_input_ioctl_handler(file, cmd, arg, (void __user *)arg);
+}
+
+#ifdef CONFIG_COMPAT
+static long hbtp_input_compat_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ return hbtp_input_ioctl_handler(file, cmd, arg, compat_ptr(arg));
+}
+#endif
+
+static const struct file_operations hbtp_input_fops = {
+ .owner = THIS_MODULE,
+ .open = hbtp_input_open,
+ .release = hbtp_input_release,
+ .unlocked_ioctl = hbtp_input_ioctl,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = hbtp_input_compat_ioctl,
+#endif
+};
+
+static struct miscdevice hbtp_input_misc = {
+ .fops = &hbtp_input_fops,
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = HBTP_INPUT_NAME,
+};
+MODULE_ALIAS_MISCDEV(MISC_DYNAMIC_MINOR);
+MODULE_ALIAS("devname:" HBTP_INPUT_NAME);
+
+static int __devinit hbtp_pdev_probe(struct platform_device *pdev)
+{
+ int ret, error;
+ struct regulator *vcc_ana;
+
+ vcc_ana = regulator_get(&pdev->dev, "vcc_ana");
+ if (IS_ERR(vcc_ana)) {
+ ret = PTR_ERR(vcc_ana);
+ pr_err("%s: Regulator get failed vcc_ana rc=%d\n",
+ __func__, ret);
+ return -EINVAL;
+ }
+
+ if (regulator_count_voltages(vcc_ana) > 0) {
+ ret = regulator_set_voltage(vcc_ana,
+ HBTP_AFE_VTG_MIN_UV, HBTP_AFE_VTG_MAX_UV);
+ if (ret) {
+ pr_err("%s: regulator set_vtg failed rc=%d\n",
+ __func__, ret);
+ error = -EINVAL;
+ goto error_set_vtg_vcc_ana;
+ }
+ }
+
+ hbtp->vcc_ana = vcc_ana;
+ hbtp->pdev = pdev;
+ return 0;
+
+error_set_vtg_vcc_ana:
+ regulator_put(vcc_ana);
+
+ return error;
+};
+
+static int __devexit hbtp_pdev_remove(struct platform_device *pdev)
+{
+ if (hbtp->vcc_ana) {
+ hbtp_pdev_power_on(hbtp, false);
+ regulator_put(hbtp->vcc_ana);
+ }
+
+ return 0;
+}
+
+#ifdef CONFIG_OF
+static struct of_device_id hbtp_match_table[] = {
+ { .compatible = "qcom,hbtp",},
+ { },
+};
+#else
+#define hbtp_match_table NULL
+#endif
+
+static struct platform_driver hbtp_pdev_driver = {
+ .probe = hbtp_pdev_probe,
+ .remove = __devexit_p(hbtp_pdev_remove),
+ .driver = {
+ .name = "hbtp",
+ .owner = THIS_MODULE,
+ .of_match_table = hbtp_match_table,
+ },
+};
+
+static int __init hbtp_init(void)
+{
+ int error;
+
+ hbtp = kzalloc(sizeof(struct hbtp_data), GFP_KERNEL);
+ if (!hbtp)
+ return -ENOMEM;
+
+ error = misc_register(&hbtp_input_misc);
+ if (error) {
+ pr_err("%s: misc_register failed\n", HBTP_INPUT_NAME);
+ goto err_misc_reg;
+ }
+
+#if defined(CONFIG_FB)
+ hbtp->fb_notif.notifier_call = fb_notifier_callback;
+ error = fb_register_client(&hbtp->fb_notif);
+ if (error) {
+ pr_err("%s: Unable to register fb_notifier: %d\n",
+ HBTP_INPUT_NAME, error);
+ goto err_fb_reg;
+ }
+#endif
+
+ error = platform_driver_register(&hbtp_pdev_driver);
+ if (error) {
+ pr_err("Failed to register platform driver: %d\n", error);
+ goto err_platform_drv_reg;
+ }
+
+ return 0;
+
+err_platform_drv_reg:
+#if defined(CONFIG_FB)
+ fb_unregister_client(&hbtp->fb_notif);
+err_fb_reg:
+#endif
+ misc_deregister(&hbtp_input_misc);
+err_misc_reg:
+ kfree(hbtp);
+
+ return error;
+}
+
+static void __exit hbtp_exit(void)
+{
+ misc_deregister(&hbtp_input_misc);
+ if (hbtp->input_dev)
+ input_unregister_device(hbtp->input_dev);
+
+#if defined(CONFIG_FB)
+ fb_unregister_client(&hbtp->fb_notif);
+#endif
+
+ platform_driver_unregister(&hbtp_pdev_driver);
+
+ kfree(hbtp);
+}
+
+MODULE_DESCRIPTION("Kernel driver to support host based touch processing");
+MODULE_LICENSE("GPLv2");
+
+module_init(hbtp_init);
+module_exit(hbtp_exit);
diff --git a/drivers/input/touchscreen/gt9xx/gt9xx.c b/drivers/input/touchscreen/gt9xx/gt9xx.c
index 912d87c..91d787f 100644
--- a/drivers/input/touchscreen/gt9xx/gt9xx.c
+++ b/drivers/input/touchscreen/gt9xx/gt9xx.c
@@ -1542,15 +1542,14 @@
const char *buf, size_t size)
{
struct goodix_ts_data *ts = dev_get_drvdata(dev);
- unsigned long val;
+ unsigned int val;
int ret;
if (size > 2)
return -EINVAL;
- ret = kstrtoul(buf, 10, &val);
- if (ret != 0)
- return ret;
+ if (sscanf(buf, "%u", &val) != 1);
+ return -EINVAL;
if (ts->gtp_is_suspend) {
dev_err(&ts->client->dev,
@@ -1576,16 +1575,60 @@
return size;
}
+static ssize_t gtp_force_fw_upgrade_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ struct goodix_ts_data *ts = dev_get_drvdata(dev);
+ unsigned int val;
+ int ret;
+
+ if (size > 2)
+ return -EINVAL;
+
+ if (sscanf(buf, "%u", &val) != 1);
+ return -EINVAL;
+
+ if (ts->gtp_is_suspend) {
+ dev_err(&ts->client->dev,
+ "Can't start fw upgrade. Device is in suspend state.");
+ return -EBUSY;
+ }
+
+ mutex_lock(&ts->input_dev->mutex);
+ if (!ts->fw_loading && val) {
+ disable_irq(ts->client->irq);
+ ts->fw_loading = true;
+ ts->force_update = true;
+ if (config_enabled(CONFIG_GT9XX_TOUCHPANEL_UPDATE)) {
+ ret = gup_update_proc(NULL);
+ if (ret == FAIL)
+ dev_err(&ts->client->dev,
+ "Fail to force update GTP firmware.\n");
+ }
+ ts->force_update = false;
+ ts->fw_loading = false;
+ enable_irq(ts->client->irq);
+ }
+ mutex_unlock(&ts->input_dev->mutex);
+
+ return size;
+}
+
static DEVICE_ATTR(fw_name, (S_IRUGO | S_IWUSR | S_IWGRP),
gtp_fw_name_show,
gtp_fw_name_store);
static DEVICE_ATTR(fw_upgrade, (S_IRUGO | S_IWUSR | S_IWGRP),
gtp_fw_upgrade_show,
gtp_fw_upgrade_store);
+static DEVICE_ATTR(force_fw_upgrade, (S_IRUGO | S_IWUSR | S_IWGRP),
+ gtp_fw_upgrade_show,
+ gtp_force_fw_upgrade_store);
static struct attribute *gtp_attrs[] = {
&dev_attr_fw_name.attr,
&dev_attr_fw_upgrade.attr,
+ &dev_attr_force_fw_upgrade.attr,
NULL
};
@@ -1802,8 +1845,8 @@
pdata->i2c_pull_up = of_property_read_bool(np,
"goodix,i2c-pull-up");
- pdata->no_force_update = of_property_read_bool(np,
- "goodix,no-force-update");
+ pdata->force_update = of_property_read_bool(np,
+ "goodix,force-update");
pdata->enable_power_off = of_property_read_bool(np,
"goodix,enable-power-off");
@@ -1971,6 +2014,9 @@
goto exit_power_off;
}
+ if (pdata->force_update)
+ ts->force_update = true;
+
if (pdata->fw_name)
strlcpy(ts->fw_name, pdata->fw_name,
strlen(pdata->fw_name) + 1);
diff --git a/drivers/input/touchscreen/gt9xx/gt9xx.h b/drivers/input/touchscreen/gt9xx/gt9xx.h
index 7a1af23..0ba6895 100644
--- a/drivers/input/touchscreen/gt9xx/gt9xx.h
+++ b/drivers/input/touchscreen/gt9xx/gt9xx.h
@@ -56,7 +56,7 @@
u32 panel_miny;
u32 panel_maxx;
u32 panel_maxy;
- bool no_force_update;
+ bool force_update;
bool i2c_pull_up;
bool enable_power_off;
size_t config_data_len[GOODIX_MAX_CFG_GROUP];
@@ -94,6 +94,7 @@
bool power_on;
struct mutex lock;
bool fw_loading;
+ bool force_update;
struct regulator *avdd;
struct regulator *vdd;
struct regulator *vcc_i2c;
diff --git a/drivers/input/touchscreen/gt9xx/gt9xx_update.c b/drivers/input/touchscreen/gt9xx/gt9xx_update.c
index 71e8a55..af80eef 100644
--- a/drivers/input/touchscreen/gt9xx/gt9xx_update.c
+++ b/drivers/input/touchscreen/gt9xx/gt9xx_update.c
@@ -1,7 +1,7 @@
/* drivers/input/touchscreen/gt9xx_update.c
*
* 2010 - 2012 Goodix Technology.
- * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2014, 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 as published by
@@ -1432,10 +1432,15 @@
goto file_fail;
}
- ret = gup_enter_update_judge(ts->client, &fw_head);
- if (ret == FAIL) {
- pr_err("Check *.bin file fail.");
- goto file_fail;
+ if (ts->force_update) {
+ dev_dbg(&ts->client->dev, "Enter force update.");
+ } else {
+ ret = gup_enter_update_judge(ts->client, &fw_head);
+ if (ret == FAIL) {
+ dev_err(&ts->client->dev,
+ "Check *.bin file fail.");
+ goto file_fail;
+ }
}
ts->enter_update = 1;
diff --git a/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_hw.c b/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_hw.c
index 44a4014..cd35eb6 100644
--- a/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_hw.c
+++ b/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_hw.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2014, 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
@@ -328,7 +328,7 @@
int msm_jpeg_hw_exec_cmds(struct msm_jpeg_hw_cmd *hw_cmd_p, uint32_t m_cmds,
uint32_t max_size, void *base)
{
- int is_copy_to_user = -1;
+ int is_copy_to_user = 0;
uint32_t data;
while (m_cmds--) {
diff --git a/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_sync.c b/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_sync.c
index 4331f95..5c0dc22 100644
--- a/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_sync.c
+++ b/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_sync.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2014, 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
@@ -722,6 +722,9 @@
kfree(hw_cmds_p);
return -EFAULT;
}
+ } else {
+ kfree(hw_cmds_p);
+ return is_copy_to_user;
}
kfree(hw_cmds_p);
return 0;
@@ -765,11 +768,12 @@
for (i = 0; i < 2; i++)
kfree(buf_out_free[i]);
+ pgmn_dev->state = MSM_JPEG_EXECUTING;
JPEG_DBG_HIGH("%s:%d] START\n", __func__, __LINE__);
wmb();
rc = msm_jpeg_ioctl_hw_cmds(pgmn_dev, arg);
wmb();
- pgmn_dev->state = MSM_JPEG_EXECUTING;
+
JPEG_DBG("%s:%d]", __func__, __LINE__);
return rc;
}
diff --git a/drivers/media/platform/msm/vidc/hfi_packetization.c b/drivers/media/platform/msm/vidc/hfi_packetization.c
index 4da0f6f..4b7a3be 100644
--- a/drivers/media/platform/msm/vidc/hfi_packetization.c
+++ b/drivers/media/platform/msm/vidc/hfi_packetization.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2014, 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
@@ -360,6 +360,18 @@
case HAL_EXTRADATA_MPEG2_SEQDISP:
ret = HFI_PROPERTY_PARAM_VDEC_MPEG2_SEQDISP_EXTRADATA;
break;
+ case HAL_EXTRADATA_FRAME_QP:
+ ret = HFI_PROPERTY_PARAM_VDEC_FRAME_QP_EXTRADATA;
+ break;
+ case HAL_EXTRADATA_FRAME_BITS_INFO:
+ ret = HFI_PROPERTY_PARAM_VDEC_FRAME_BITS_INFO_EXTRADATA;
+ break;
+ case HAL_EXTRADATA_LTR_INFO:
+ ret = HFI_PROPERTY_PARAM_VENC_LTR_INFO;
+ break;
+ case HAL_EXTRADATA_METADATA_MBI:
+ ret = HFI_PROPERTY_PARAM_VENC_MBI_DUMPING;
+ break;
default:
dprintk(VIDC_WARN, "Extradata index not found: %d\n", index);
break;
@@ -389,6 +401,28 @@
return buf_mode;
}
+static u32 get_hfi_ltr_mode(enum ltr_mode ltr_mode_type)
+{
+ u32 ltrmode;
+ switch (ltr_mode_type) {
+ case HAL_LTR_MODE_DISABLE:
+ ltrmode = HFI_LTR_MODE_DISABLE;
+ break;
+ case HAL_LTR_MODE_MANUAL:
+ ltrmode = HFI_LTR_MODE_MANUAL;
+ break;
+ case HAL_LTR_MODE_PERIODIC:
+ ltrmode = HFI_LTR_MODE_PERIODIC;
+ break;
+ default:
+ dprintk(VIDC_ERR, "Invalid ltr mode :0x%x\n",
+ ltr_mode_type);
+ ltrmode = HFI_LTR_MODE_DISABLE;
+ break;
+ }
+ return ltrmode;
+}
+
int create_pkt_cmd_session_set_buffers(
struct hfi_cmd_session_set_buffers_packet *pkt,
u32 session_id,
@@ -1405,6 +1439,54 @@
pkt->size += sizeof(u32) + sizeof(struct hfi_enable);
break;
}
+ case HAL_PARAM_VENC_LTRMODE:
+ {
+ struct hfi_ltrmode *hfi;
+ struct hal_ltrmode *hal = pdata;
+ pkt->rg_property_data[0] =
+ HFI_PROPERTY_PARAM_VENC_LTRMODE;
+ hfi = (struct hfi_ltrmode *) &pkt->rg_property_data[1];
+ hfi->ltrmode = get_hfi_ltr_mode(hal->ltrmode);
+ hfi->ltrcount = hal->ltrcount;
+ hfi->trustmode = hal->trustmode;
+ pkt->size += sizeof(u32) + sizeof(struct hfi_ltrmode);
+ pr_err("SET LTR\n");
+ break;
+ }
+ case HAL_CONFIG_VENC_USELTRFRAME:
+ {
+ struct hfi_ltruse *hfi;
+ struct hal_ltruse *hal = pdata;
+ pkt->rg_property_data[0] =
+ HFI_PROPERTY_CONFIG_VENC_USELTRFRAME;
+ hfi = (struct hfi_ltruse *) &pkt->rg_property_data[1];
+ hfi->frames = hal->frames;
+ hfi->refltr = hal->refltr;
+ hfi->useconstrnt = hal->useconstrnt;
+ pkt->size += sizeof(u32) + sizeof(struct hfi_ltruse);
+ pr_err("USE LTR\n");
+ break;
+ }
+ case HAL_CONFIG_VENC_MARKLTRFRAME:
+ {
+ struct hfi_ltrmark *hfi;
+ struct hal_ltrmark *hal = pdata;
+ pkt->rg_property_data[0] =
+ HFI_PROPERTY_CONFIG_VENC_MARKLTRFRAME;
+ hfi = (struct hfi_ltrmark *) &pkt->rg_property_data[1];
+ hfi->markframe = hal->markframe;
+ pkt->size += sizeof(u32) + sizeof(struct hfi_ltrmark);
+ pr_err("MARK LTR\n");
+ break;
+ }
+ case HAL_PARAM_VENC_HIER_P_NUM_FRAMES:
+ {
+ pkt->rg_property_data[0] =
+ HFI_PROPERTY_PARAM_VENC_HIER_P_NUM_ENH_LAYER;
+ pkt->rg_property_data[1] = *(u32 *)pdata;
+ pkt->size += sizeof(u32) * 2;
+ break;
+ }
/* FOLLOWING PROPERTIES ARE NOT IMPLEMENTED IN CORE YET */
case HAL_CONFIG_BUFFER_REQUIREMENTS:
case HAL_CONFIG_PRIORITY:
@@ -1432,7 +1514,7 @@
case HAL_CONFIG_VENC_TIMESTAMP_SCALE:
case HAL_PARAM_VENC_LOW_LATENCY:
default:
- dprintk(VIDC_ERR, "DEFAULT: Calling 0x%x", ptype);
+ dprintk(VIDC_ERR, "DEFAULT: Calling 0x%x\n", ptype);
rc = -ENOTSUPP;
break;
}
diff --git a/drivers/media/platform/msm/vidc/hfi_response_handler.c b/drivers/media/platform/msm/vidc/hfi_response_handler.c
index 189fca0..f4ad985 100644
--- a/drivers/media/platform/msm/vidc/hfi_response_handler.c
+++ b/drivers/media/platform/msm/vidc/hfi_response_handler.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2014, 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
@@ -388,6 +388,10 @@
struct vidc_hal_session_init_done *sess_init_done)
{
struct hal_capability_supported *out = NULL;
+ if (!in) {
+ dprintk(VIDC_ERR, "Invalid input for supported capabilties\n");
+ return;
+ }
switch (in->capability_type) {
case HFI_CAPABILITY_FRAME_WIDTH:
out = &sess_init_done->width;
@@ -420,9 +424,17 @@
case HFI_CAPABILITY_BITRATE:
out = &sess_init_done->bitrate;
break;
+
+ case HFI_CAPABILITY_ENC_LTR_COUNT:
+ out = &sess_init_done->ltr_count;
+ break;
+
+ case HFI_CAPABILITY_HIER_P_NUM_ENH_LAYERS:
+ out = &sess_init_done->hier_p;
+ break;
}
- if (in && out) {
+ if (out) {
out->capability_type =
(enum hal_capability)in->capability_type;
out->min = in->min;
diff --git a/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c b/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c
index 5e3699d..176c612 100644
--- a/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c
+++ b/drivers/media/platform/msm/vidc/msm_v4l2_vidc.c
@@ -120,6 +120,13 @@
return msm_vidc_g_ctrl((void *)vidc_inst, a);
}
+int msm_v4l2_s_ext_ctrl(struct file *file, void *fh,
+ struct v4l2_ext_controls *a)
+{
+ struct msm_vidc_inst *vidc_inst = get_vidc_inst(file, fh);
+ return msm_vidc_s_ext_ctrl((void *)vidc_inst, a);
+}
+
int msm_v4l2_reqbufs(struct file *file, void *fh,
struct v4l2_requestbuffers *b)
{
@@ -242,6 +249,7 @@
.vidioc_streamoff = msm_v4l2_streamoff,
.vidioc_s_ctrl = msm_v4l2_s_ctrl,
.vidioc_g_ctrl = msm_v4l2_g_ctrl,
+ .vidioc_s_ext_ctrls = msm_v4l2_s_ext_ctrl,
.vidioc_subscribe_event = msm_v4l2_subscribe_event,
.vidioc_unsubscribe_event = msm_v4l2_unsubscribe_event,
.vidioc_decoder_cmd = msm_v4l2_decoder_cmd,
diff --git a/drivers/media/platform/msm/vidc/msm_vdec.c b/drivers/media/platform/msm/vidc/msm_vdec.c
index 5c735d6..71ad080 100644
--- a/drivers/media/platform/msm/vidc/msm_vdec.c
+++ b/drivers/media/platform/msm/vidc/msm_vdec.c
@@ -220,7 +220,7 @@
.name = "Extradata Type",
.type = V4L2_CTRL_TYPE_MENU,
.minimum = V4L2_MPEG_VIDC_EXTRADATA_NONE,
- .maximum = V4L2_MPEG_VIDC_EXTRADATA_MPEG2_SEQDISP,
+ .maximum = V4L2_MPEG_VIDC_EXTRADATA_FRAME_BITS_INFO,
.default_value = V4L2_MPEG_VIDC_EXTRADATA_NONE,
.menu_skip_mask = ~(
(1 << V4L2_MPEG_VIDC_EXTRADATA_NONE) |
@@ -241,7 +241,9 @@
(1 << V4L2_MPEG_VIDC_INDEX_EXTRADATA_INPUT_CROP) |
(1 << V4L2_MPEG_VIDC_INDEX_EXTRADATA_DIGITAL_ZOOM) |
(1 << V4L2_MPEG_VIDC_INDEX_EXTRADATA_ASPECT_RATIO) |
- (1 << V4L2_MPEG_VIDC_EXTRADATA_MPEG2_SEQDISP)
+ (1 << V4L2_MPEG_VIDC_EXTRADATA_MPEG2_SEQDISP) |
+ (1 << V4L2_MPEG_VIDC_EXTRADATA_FRAME_QP) |
+ (1 << V4L2_MPEG_VIDC_EXTRADATA_FRAME_BITS_INFO)
),
.qmenu = mpeg_video_vidc_extradata,
.step = 0,
@@ -574,15 +576,7 @@
core);
goto exit;
}
- if (!inst->in_reconfig) {
- rc = msm_comm_try_state(inst, MSM_VIDC_RELEASE_RESOURCES_DONE);
- if (rc) {
- dprintk(VIDC_ERR,
- "Failed to move inst: %p to relase res done\n",
- inst);
- goto exit;
- }
- }
+
switch (b->type) {
case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
break;
diff --git a/drivers/media/platform/msm/vidc/msm_venc.c b/drivers/media/platform/msm/vidc/msm_venc.c
index de59e81..b01a507 100644
--- a/drivers/media/platform/msm/vidc/msm_venc.c
+++ b/drivers/media/platform/msm/vidc/msm_venc.c
@@ -37,6 +37,8 @@
#define B_FRAME_QP 30
#define MAX_INTRA_REFRESH_MBS 300
#define MAX_NUM_B_FRAMES 4
+#define MAX_LTR_FRAME_COUNT 10
+
#define L_MODE V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY
#define CODING V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_CODING_EFFICIENCY
@@ -114,6 +116,7 @@
"Extradata input crop",
"Extradata digital zoom",
"Extradata aspect ratio",
+ "Extradata macroblock metadata",
};
static const char *const perf_level[] = {
@@ -135,7 +138,8 @@
MSM_VENC_CTRL_CLUSTER_TIMING = 1 << 9,
MSM_VENC_CTRL_CLUSTER_VP8_PROFILE_LEVEL = 1 << 10,
MSM_VENC_CTRL_CLUSTER_DEINTERLACE = 1 << 11,
- MSM_VENC_CTRL_CLUSTER_MAX = 1 << 12,
+ MSM_VENC_CTRL_CLUSTER_USE_LTRFRAME = 1 << 12,
+ MSM_VENC_CTRL_CLUSTER_MAX = 1 << 13,
};
static struct msm_vidc_ctrl msm_venc_ctrls[] = {
@@ -651,7 +655,7 @@
.name = "Extradata Type",
.type = V4L2_CTRL_TYPE_MENU,
.minimum = V4L2_MPEG_VIDC_EXTRADATA_NONE,
- .maximum = V4L2_MPEG_VIDC_INDEX_EXTRADATA_ASPECT_RATIO,
+ .maximum = V4L2_MPEG_VIDC_EXTRADATA_METADATA_MBI,
.default_value = V4L2_MPEG_VIDC_EXTRADATA_NONE,
.menu_skip_mask = ~(
(1 << V4L2_MPEG_VIDC_EXTRADATA_NONE) |
@@ -671,7 +675,9 @@
(1 << V4L2_MPEG_VIDC_EXTRADATA_METADATA_FILLER) |
(1 << V4L2_MPEG_VIDC_INDEX_EXTRADATA_INPUT_CROP) |
(1 << V4L2_MPEG_VIDC_INDEX_EXTRADATA_DIGITAL_ZOOM) |
- (1 << V4L2_MPEG_VIDC_INDEX_EXTRADATA_ASPECT_RATIO)
+ (1 << V4L2_MPEG_VIDC_INDEX_EXTRADATA_ASPECT_RATIO) |
+ (1 << V4L2_MPEG_VIDC_EXTRADATA_LTR) |
+ (1 << V4L2_MPEG_VIDC_EXTRADATA_METADATA_MBI)
),
.qmenu = mpeg_video_vidc_extradata,
.step = 0,
@@ -729,6 +735,61 @@
.default_value = V4L2_CID_MPEG_VIDC_VIDEO_DEINTERLACE_DISABLED,
.step = 1,
.cluster = MSM_VENC_CTRL_CLUSTER_DEINTERLACE,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDC_VIDEO_USELTRFRAME,
+ .name = "H264 Use LTR",
+ .type = V4L2_CTRL_TYPE_BUTTON,
+ .minimum = 0,
+ .maximum = (MAX_LTR_FRAME_COUNT - 1),
+ .default_value = 0,
+ .step = 1,
+ .qmenu = NULL,
+ .cluster = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDC_VIDEO_LTRCOUNT,
+ .name = "Ltr Count",
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .minimum = 0,
+ .maximum = MAX_LTR_FRAME_COUNT,
+ .default_value = 0,
+ .step = 1,
+ .qmenu = NULL,
+ .cluster = MSM_VENC_CTRL_CLUSTER_USE_LTRFRAME,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDC_VIDEO_LTRMODE,
+ .name = "Ltr Mode",
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .minimum = V4L2_MPEG_VIDC_VIDEO_LTR_MODE_DISABLE,
+ .maximum = V4L2_MPEG_VIDC_VIDEO_LTR_MODE_PERIODIC,
+ .default_value = V4L2_MPEG_VIDC_VIDEO_LTR_MODE_DISABLE,
+ .step = 1,
+ .qmenu = NULL,
+ .cluster = MSM_VENC_CTRL_CLUSTER_USE_LTRFRAME,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDC_VIDEO_MARKLTRFRAME,
+ .name = "H264 Mark LTR",
+ .type = V4L2_CTRL_TYPE_BUTTON,
+ .minimum = 0,
+ .maximum = (MAX_LTR_FRAME_COUNT - 1),
+ .default_value = 0,
+ .step = 1,
+ .qmenu = NULL,
+ .cluster = 0,
+ },
+ {
+ .id = V4L2_CID_MPEG_VIDC_VIDEO_HIER_P_NUM_LAYERS,
+ .name = "Set Hier P num layers",
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .minimum = 0,
+ .maximum = 3,
+ .default_value = 0,
+ .step = 1,
+ .qmenu = NULL,
+ .cluster = 0,
}
};
@@ -836,28 +897,33 @@
*num_buffers = buff_req->buffer_count_actual =
max(*num_buffers, buff_req->buffer_count_actual);
}
- if (*num_buffers < MIN_NUM_CAPTURE_BUFFERS)
- *num_buffers = MIN_NUM_CAPTURE_BUFFERS;
- if (*num_buffers > VIDEO_MAX_FRAME) {
- dprintk(VIDC_ERR,
- "Changing buffers requested, from %d to max"\
- " supported (%d) best effort encoding\n",
- *num_buffers, VIDEO_MAX_FRAME);
- *num_buffers = VIDEO_MAX_FRAME;
+ if (*num_buffers < MIN_NUM_CAPTURE_BUFFERS ||
+ *num_buffers > VIDEO_MAX_FRAME) {
+ int temp = *num_buffers;
+
+ *num_buffers = clamp_val(*num_buffers,
+ MIN_NUM_CAPTURE_BUFFERS,
+ VIDEO_MAX_FRAME);
+ dprintk(VIDC_INFO,
+ "Changing buffer count on CAPTURE_MPLANE from %d to %d for best effort encoding\n",
+ temp, *num_buffers);
}
+
ctrl = v4l2_ctrl_find(&inst->ctrl_handler,
V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA);
if (ctrl)
extradata = v4l2_ctrl_g_ctrl(ctrl);
- if (extradata)
+ if (extradata != V4L2_MPEG_VIDC_EXTRADATA_NONE)
*num_planes = *num_planes + 1;
inst->fmts[CAPTURE_PORT]->num_planes = *num_planes;
+
for (i = 0; i < *num_planes; i++) {
sizes[i] = inst->fmts[CAPTURE_PORT]->get_frame_size(
i, inst->prop.height[CAPTURE_PORT],
inst->prop.width[CAPTURE_PORT]);
}
+
property_id = HAL_PARAM_BUFFER_COUNT_ACTUAL;
new_buf_count.buffer_type = HAL_BUFFER_OUTPUT;
new_buf_count.buffer_count_actual = *num_buffers;
@@ -1273,6 +1339,9 @@
struct v4l2_ctrl *temp_ctrl = NULL;
struct hfi_device *hdev;
struct hal_extradata_enable extra;
+ struct hal_ltruse useltr;
+ struct hal_ltrmark markltr;
+ u32 hier_p_layers;
if (!inst || !inst->core || !inst->core->device) {
dprintk(VIDC_ERR, "%s invalid parameters", __func__);
@@ -1970,7 +2039,33 @@
pdata = &enable;
break;
}
+ case V4L2_CID_MPEG_VIDC_VIDEO_USELTRFRAME:
+ property_id = HAL_CONFIG_VENC_USELTRFRAME;
+ useltr.refltr = ctrl->val;
+ useltr.useconstrnt = false;
+ useltr.frames = 0;
+ pdata = &useltr;
+ break;
+ case V4L2_CID_MPEG_VIDC_VIDEO_MARKLTRFRAME:
+ property_id = HAL_CONFIG_VENC_MARKLTRFRAME;
+ markltr.markframe = ctrl->val;
+ pdata = &markltr;
+ break;
+ case V4L2_CID_MPEG_VIDC_VIDEO_HIER_P_NUM_LAYERS:
+ property_id = HAL_PARAM_VENC_HIER_P_NUM_FRAMES;
+ hier_p_layers = ctrl->val;
+ if (hier_p_layers > (inst->capability.hier_p.max - 1)) {
+ dprintk(VIDC_ERR,
+ "Error setting hier p num layers = %d max supported by f/w = %d\n",
+ hier_p_layers,
+ inst->capability.hier_p.max - 1);
+ rc = -ENOTSUPP;
+ break;
+ }
+ pdata = &hier_p_layers;
+ break;
default:
+ dprintk(VIDC_ERR, "Unsupported index: %x\n", ctrl->id);
rc = -ENOTSUPP;
break;
}
@@ -1987,6 +2082,89 @@
return rc;
}
+static struct v4l2_ctrl *get_cluster_from_id(int id)
+{
+ int c;
+ for (c = 0; c < ARRAY_SIZE(msm_venc_ctrls); ++c)
+ if (msm_venc_ctrls[c].id == id)
+ return (struct v4l2_ctrl *)msm_venc_ctrls[c].priv;
+ return NULL;
+}
+
+static int try_set_ext_ctrl(struct msm_vidc_inst *inst,
+ struct v4l2_ext_controls *ctrl)
+{
+ int rc = 0, i;
+ struct v4l2_ext_control *control;
+ struct hfi_device *hdev;
+ struct hal_ltrmode ltrmode;
+ struct v4l2_ctrl *cluster;
+ u32 property_id = 0;
+ void *pdata = NULL;
+ struct msm_vidc_core_capability *cap = NULL;
+
+ if (!inst || !inst->core || !inst->core->device || !ctrl) {
+ dprintk(VIDC_ERR, "%s invalid parameters\n", __func__);
+ return -EINVAL;
+ }
+
+ cluster = get_cluster_from_id(ctrl->controls[0].id);
+
+ if (!cluster) {
+ dprintk(VIDC_ERR, "Invalid Ctrl returned for id: %x\n",
+ ctrl->controls[0].id);
+ return -EINVAL;
+ }
+
+ hdev = inst->core->device;
+ cap = &inst->capability;
+
+ control = ctrl->controls;
+ for (i = 0; i < ctrl->count; i++) {
+ switch (control[i].id) {
+ case V4L2_CID_MPEG_VIDC_VIDEO_LTRMODE:
+ ltrmode.ltrmode = control[i].value;
+ ltrmode.trustmode = 1;
+ property_id = HAL_PARAM_VENC_LTRMODE;
+ pdata = <rmode;
+ break;
+ case V4L2_CID_MPEG_VIDC_VIDEO_LTRCOUNT:
+ ltrmode.ltrcount = control[i].value;
+ if (ltrmode.ltrcount > cap->ltr_count.max) {
+ dprintk(VIDC_ERR,
+ "Invalid LTR count %d. Supported max: %d\n",
+ ltrmode.ltrcount,
+ cap->ltr_count.max);
+ /*
+ * FIXME: Return an error (-EINVALID)
+ * here once VP8 supports LTR count
+ * capability
+ */
+ ltrmode.ltrcount = 1;
+ }
+ ltrmode.trustmode = 1;
+ property_id = HAL_PARAM_VENC_LTRMODE;
+ pdata = <rmode;
+ break;
+ default:
+ dprintk(VIDC_ERR, "Invalid id set: %d\n",
+ control[i].id);
+ rc = -ENOTSUPP;
+ break;
+ }
+ if (rc)
+ break;
+ }
+
+ if (!rc && property_id) {
+ dprintk(VIDC_DBG, "Control: HAL property=%x\n", property_id);
+ rc = call_hfi_op(hdev, session_set_property,
+ (void *)inst->session, property_id, pdata);
+ }
+ pr_err("Returning from %s\n", __func__);
+ return rc;
+}
+
static int msm_venc_op_s_ctrl(struct v4l2_ctrl *ctrl)
{
@@ -2072,6 +2250,22 @@
return v4l2_g_ctrl(&inst->ctrl_handler, ctrl);
}
+int msm_venc_s_ext_ctrl(struct msm_vidc_inst *inst,
+ struct v4l2_ext_controls *ctrl)
+{
+ int rc = 0;
+ if (ctrl->ctrl_class != V4L2_CTRL_CLASS_MPEG) {
+ dprintk(VIDC_ERR, "Invalid Class set for extended control\n");
+ return -EINVAL;
+ }
+ rc = try_set_ext_ctrl(inst, ctrl);
+ if (rc) {
+ dprintk(VIDC_ERR, "Error setting extended control\n");
+ return rc;
+ }
+ return rc;
+}
+
int msm_venc_cmd(struct msm_vidc_inst *inst, struct v4l2_encoder_cmd *enc)
{
int rc = 0;
diff --git a/drivers/media/platform/msm/vidc/msm_venc.h b/drivers/media/platform/msm/vidc/msm_venc.h
index 9020167..5965d39 100644
--- a/drivers/media/platform/msm/vidc/msm_venc.h
+++ b/drivers/media/platform/msm/vidc/msm_venc.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012, 2014, 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
@@ -25,6 +25,7 @@
int msm_venc_g_fmt(void *instance, struct v4l2_format *f);
int msm_venc_s_ctrl(void *instance, struct v4l2_control *a);
int msm_venc_g_ctrl(void *instance, struct v4l2_control *a);
+int msm_venc_s_ext_ctrl(void *instance, struct v4l2_ext_controls *a);
int msm_venc_reqbufs(void *instance, struct v4l2_requestbuffers *b);
int msm_venc_prepare_buf(struct msm_vidc_inst *inst, struct v4l2_buffer *b);
int msm_venc_release_buf(struct msm_vidc_inst *inst, struct v4l2_buffer *b);
diff --git a/drivers/media/platform/msm/vidc/msm_vidc.c b/drivers/media/platform/msm/vidc/msm_vidc.c
index 9774c3c..59a1ec0 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc.c
@@ -185,6 +185,15 @@
return msm_venc_g_ctrl(instance, control);
return -EINVAL;
}
+int msm_vidc_s_ext_ctrl(void *instance, struct v4l2_ext_controls *control)
+{
+ struct msm_vidc_inst *inst = instance;
+ if (!inst || !control)
+ return -EINVAL;
+ if (inst->session_type == MSM_VIDC_ENCODER)
+ return msm_venc_s_ext_ctrl(instance, control);
+ return -EINVAL;
+}
int msm_vidc_reqbufs(void *instance, struct v4l2_requestbuffers *b)
{
struct msm_vidc_inst *inst = instance;
@@ -718,6 +727,26 @@
if (!inst)
return -EINVAL;
+ if (!inst->in_reconfig) {
+ rc = msm_comm_try_state(inst, MSM_VIDC_RELEASE_RESOURCES_DONE);
+ if (rc) {
+ dprintk(VIDC_ERR,
+ "Failed to move inst: %p to release res done\n",
+ inst);
+ }
+ }
+
+ /*
+ * In dynamic buffer mode, driver needs to release resources,
+ * but not call release buffers on firmware, as the buffers
+ * were never registered with firmware.
+ */
+ if ((buffer_type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) &&
+ (inst->buffer_mode_set[CAPTURE_PORT] ==
+ HAL_BUFFER_MODE_DYNAMIC)) {
+ goto free_and_unmap;
+ }
+
list_for_each_safe(ptr, next, &inst->registered_bufs) {
bool release_buf = false;
mutex_lock(&inst->lock);
@@ -756,6 +785,8 @@
buffer_info.m.planes[0].reserved[1],
buffer_info.m.planes[0].length);
}
+
+free_and_unmap:
mutex_lock(&inst->lock);
list_for_each_safe(ptr, next, &inst->registered_bufs) {
bi = list_entry(ptr, struct buffer_info, list);
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.c b/drivers/media/platform/msm/vidc/msm_vidc_common.c
index 7ae2cb5..95afa2a 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_common.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_common.c
@@ -463,6 +463,9 @@
session_init_done->frame_rate;
inst->capability.scale_x = session_init_done->scale_x;
inst->capability.scale_y = session_init_done->scale_y;
+ inst->capability.ltr_count =
+ session_init_done->ltr_count;
+ inst->capability.hier_p = session_init_done->hier_p;
inst->capability.pixelprocess_capabilities =
call_hfi_op(hdev, get_core_capabilities);
inst->capability.capability_set = true;
@@ -1117,6 +1120,7 @@
struct vidc_hal_fbd *fill_buf_done;
enum hal_buffer buffer_type;
int64_t time_usec = 0;
+ int extra_idx = 0;
if (!response) {
dprintk(VIDC_ERR, "Invalid response from vidc_hal\n");
@@ -1163,6 +1167,15 @@
ns_to_timeval(time_usec * NSEC_PER_USEC);
}
vb->v4l2_buf.flags = 0;
+ extra_idx =
+ EXTRADATA_IDX(inst->fmts[CAPTURE_PORT]->num_planes);
+ if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
+ vb->v4l2_planes[extra_idx].m.userptr =
+ (unsigned long)fill_buf_done->extra_data_buffer;
+ vb->v4l2_planes[extra_idx].bytesused =
+ vb->v4l2_planes[extra_idx].length;
+ vb->v4l2_planes[extra_idx].data_offset = 0;
+ }
handle_dynamic_buffer(inst, (u32)fill_buf_done->packet_buffer1,
fill_buf_done->flags1);
@@ -1217,6 +1230,13 @@
fill_buf_done->start_y_coord, fill_buf_done->frame_width,
fill_buf_done->frame_height, fill_buf_done->picture_type);
+ if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
+ dprintk(VIDC_DBG,
+ "extradata: userptr = %p; bytesused = %d; length = %d\n",
+ (u8 *)vb->v4l2_planes[extra_idx].m.userptr,
+ vb->v4l2_planes[extra_idx].bytesused,
+ vb->v4l2_planes[extra_idx].length);
+ }
mutex_lock(&inst->bufq[CAPTURE_PORT].lock);
vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
mutex_unlock(&inst->bufq[CAPTURE_PORT].lock);
@@ -3121,6 +3141,18 @@
case V4L2_MPEG_VIDC_EXTRADATA_MPEG2_SEQDISP:
ret = HAL_EXTRADATA_MPEG2_SEQDISP;
break;
+ case V4L2_MPEG_VIDC_EXTRADATA_FRAME_QP:
+ ret = HAL_EXTRADATA_FRAME_QP;
+ break;
+ case V4L2_MPEG_VIDC_EXTRADATA_FRAME_BITS_INFO:
+ ret = HAL_EXTRADATA_FRAME_BITS_INFO;
+ break;
+ case V4L2_MPEG_VIDC_EXTRADATA_LTR:
+ ret = HAL_EXTRADATA_LTR_INFO;
+ break;
+ case V4L2_MPEG_VIDC_EXTRADATA_METADATA_MBI:
+ ret = HAL_EXTRADATA_METADATA_MBI;
+ break;
default:
dprintk(VIDC_WARN, "Extradata not found: %d\n", index);
break;
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_internal.h b/drivers/media/platform/msm/vidc/msm_vidc_internal.h
index e4f920f..06181dd 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_internal.h
+++ b/drivers/media/platform/msm/vidc/msm_vidc_internal.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2014, 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
@@ -190,6 +190,8 @@
u32 pixelprocess_capabilities;
struct hal_capability_supported scale_x;
struct hal_capability_supported scale_y;
+ struct hal_capability_supported ltr_count;
+ struct hal_capability_supported hier_p;
u32 capability_set;
enum buffer_mode_type buffer_mode[MAX_PORT_NUM];
};
diff --git a/drivers/media/platform/msm/vidc/venus_hfi.c b/drivers/media/platform/msm/vidc/venus_hfi.c
index 9e77299..694335b 100644
--- a/drivers/media/platform/msm/vidc/venus_hfi.c
+++ b/drivers/media/platform/msm/vidc/venus_hfi.c
@@ -3114,14 +3114,14 @@
return -EINVAL;
}
ocmem_buffer = device->resources.ocmem.buf;
- if (!ocmem_buffer ||
- ocmem_buffer->len < size) {
+ if (!ocmem_buffer || ocmem_buffer->len < size) {
ocmem_buffer = ocmem_allocate(OCMEM_VIDEO, size);
if (IS_ERR_OR_NULL(ocmem_buffer)) {
dprintk(VIDC_ERR,
"ocmem_allocate_nb failed: %d\n",
(u32) ocmem_buffer);
rc = -ENOMEM;
+ goto ocmem_set_failed;
}
device->resources.ocmem.buf = ocmem_buffer;
rc = venus_hfi_set_ocmem(device, ocmem_buffer);
diff --git a/drivers/media/platform/msm/vidc/vidc_hfi.h b/drivers/media/platform/msm/vidc/vidc_hfi.h
index 70b93ff0..75f583f 100644
--- a/drivers/media/platform/msm/vidc/vidc_hfi.h
+++ b/drivers/media/platform/msm/vidc/vidc_hfi.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2014, 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
@@ -19,6 +19,7 @@
#define HFI_EVENT_SESSION_SEQUENCE_CHANGED (HFI_OX_BASE + 0x3)
#define HFI_EVENT_SESSION_PROPERTY_CHANGED (HFI_OX_BASE + 0x4)
+#define HFI_EVENT_SESSION_LTRUSE_FAILED (HFI_OX_BASE + 0x5)
#define HFI_EVENT_RELEASE_BUFFER_REFERENCE (HFI_OX_BASE + 0x6)
#define HFI_EVENT_DATA_SEQUENCE_CHANGED_SUFFICIENT_BUFFER_RESOURCES \
@@ -81,9 +82,12 @@
#define HFI_EXTRADATA_CLOSED_CAPTION_UD 0x0000000A
#define HFI_EXTRADATA_AFD_UD 0x0000000B
#define HFI_EXTRADATA_MPEG2_SEQDISP 0x0000000D
+#define HFI_EXTRADATA_FRAME_QP 0x0000000F
+#define HFI_EXTRADATA_FRAME_BITS_INFO 0x00000010
#define HFI_EXTRADATA_MULTISLICE_INFO 0x7F100000
#define HFI_EXTRADATA_NUM_CONCEALED_MB 0x7F100001
#define HFI_EXTRADATA_INDEX 0x7F100002
+#define HFI_EXTRADATA_METADATA_LTR 0x7F100004
#define HFI_EXTRADATA_METADATA_FILLER 0x7FE00002
#define HFI_INDEX_EXTRADATA_INPUT_CROP 0x0700000E
@@ -202,6 +206,10 @@
(HFI_PROPERTY_PARAM_VDEC_OX_START + 0x015)
#define HFI_PROPERTY_PARAM_VDEC_MPEG2_SEQDISP_EXTRADATA \
(HFI_PROPERTY_PARAM_VDEC_OX_START + 0x016)
+#define HFI_PROPERTY_PARAM_VDEC_FRAME_QP_EXTRADATA \
+ (HFI_PROPERTY_PARAM_VDEC_OX_START + 0x018)
+#define HFI_PROPERTY_PARAM_VDEC_FRAME_BITS_INFO_EXTRADATA \
+ (HFI_PROPERTY_PARAM_VDEC_OX_START + 0x019)
#define HFI_PROPERTY_CONFIG_VDEC_OX_START \
(HFI_DOMAIN_BASE_VDEC + HFI_ARCH_OX_OFFSET + 0x0000)
@@ -218,6 +226,10 @@
(HFI_PROPERTY_PARAM_VENC_OX_START + 0x001)
#define HFI_PROPERTY_PARAM_VENC_H264_IDR_S3D_FRAME_PACKING_NAL \
(HFI_PROPERTY_PARAM_VENC_OX_START + 0x002)
+#define HFI_PROPERTY_PARAM_VENC_LTR_INFO \
+ (HFI_PROPERTY_PARAM_VENC_OX_START + 0x003)
+#define HFI_PROPERTY_PARAM_VENC_MBI_DUMPING \
+ (HFI_PROPERTY_PARAM_VENC_OX_START + 0x005)
#define HFI_PROPERTY_CONFIG_VENC_OX_START \
(HFI_DOMAIN_BASE_VENC + HFI_ARCH_OX_OFFSET + 0x6000)
diff --git a/drivers/media/platform/msm/vidc/vidc_hfi_api.h b/drivers/media/platform/msm/vidc/vidc_hfi_api.h
index 846171e..c764758 100644
--- a/drivers/media/platform/msm/vidc/vidc_hfi_api.h
+++ b/drivers/media/platform/msm/vidc/vidc_hfi_api.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2014, 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
@@ -97,7 +97,11 @@
HAL_EXTRADATA_NUM_CONCEALED_MB,
HAL_EXTRADATA_METADATA_FILLER,
HAL_EXTRADATA_ASPECT_RATIO,
- HAL_EXTRADATA_MPEG2_SEQDISP
+ HAL_EXTRADATA_MPEG2_SEQDISP,
+ HAL_EXTRADATA_FRAME_QP,
+ HAL_EXTRADATA_FRAME_BITS_INFO,
+ HAL_EXTRADATA_LTR_INFO,
+ HAL_EXTRADATA_METADATA_MBI,
};
enum hal_property {
@@ -177,6 +181,11 @@
HAL_PARAM_BUFFER_ALLOC_MODE,
HAL_PARAM_VDEC_FRAME_ASSEMBLY,
HAL_PARAM_VDEC_CONCEAL_COLOR,
+ HAL_PARAM_VENC_LTRMODE,
+ HAL_CONFIG_VENC_MARKLTRFRAME,
+ HAL_CONFIG_VENC_USELTRFRAME,
+ HAL_CONFIG_VENC_LTRPERIOD,
+ HAL_PARAM_VENC_HIER_P_NUM_FRAMES,
};
enum hal_domain {
@@ -896,6 +905,27 @@
enum buffer_mode_type buffer_mode;
};
+enum ltr_mode {
+ HAL_LTR_MODE_DISABLE,
+ HAL_LTR_MODE_MANUAL,
+ HAL_LTR_MODE_PERIODIC,
+};
+
+struct hal_ltrmode {
+ enum ltr_mode ltrmode;
+ u32 ltrcount;
+ u32 trustmode;
+};
+
+struct hal_ltruse {
+ u32 refltr;
+ u32 useconstrnt;
+ u32 frames;
+};
+
+struct hal_ltrmark {
+ u32 markframe;
+};
/* HAL Response */
enum command_response {
@@ -1032,6 +1062,8 @@
struct hal_capability_supported scale_x;
struct hal_capability_supported scale_y;
struct hal_capability_supported bitrate;
+ struct hal_capability_supported ltr_count;
+ struct hal_capability_supported hier_p;
struct hal_uncompressed_format_supported uncomp_format;
struct hal_interlace_format_supported HAL_format;
struct hal_nal_stream_format_supported nal_stream_format;
diff --git a/drivers/media/platform/msm/vidc/vidc_hfi_helper.h b/drivers/media/platform/msm/vidc/vidc_hfi_helper.h
index 1916e9f..5117266 100644
--- a/drivers/media/platform/msm/vidc/vidc_hfi_helper.h
+++ b/drivers/media/platform/msm/vidc/vidc_hfi_helper.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2014, 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
@@ -309,7 +309,7 @@
(HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x01A)
#define HFI_PROPERTY_PARAM_VENC_H264_NAL_SVC_EXT \
(HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x01B)
-#define HFI_PROPERTY_PARAM_VENC_H264_LTRMODE \
+#define HFI_PROPERTY_PARAM_VENC_LTRMODE \
(HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x01C)
#define HFI_PROPERTY_PARAM_VENC_VIDEO_FULL_RANGE \
(HFI_PROPERTY_PARAM_VENC_COMMON_START + 0x01D)
@@ -338,7 +338,12 @@
(HFI_DOMAIN_BASE_VPE + HFI_ARCH_COMMON_OFFSET + 0x7000)
#define HFI_PROPERTY_CONFIG_VENC_SYNC_FRAME_SEQUENCE_HEADER \
(HFI_PROPERTY_CONFIG_VENC_COMMON_START + 0x008)
-
+#define HFI_PROPERTY_CONFIG_VENC_MARKLTRFRAME \
+ (HFI_PROPERTY_CONFIG_VENC_COMMON_START + 0x009)
+#define HFI_PROPERTY_CONFIG_VENC_USELTRFRAME \
+ (HFI_PROPERTY_CONFIG_VENC_COMMON_START + 0x00A)
+#define HFI_PROPERTY_CONFIG_VENC_LTRPERIOD \
+ (HFI_PROPERTY_CONFIG_VENC_COMMON_START + 0x00C)
#define HFI_PROPERTY_CONFIG_VPE_COMMON_START \
(HFI_DOMAIN_BASE_VPE + HFI_ARCH_COMMON_OFFSET + 0x8000)
#define HFI_PROPERTY_CONFIG_VPE_DEINTERLACE \
@@ -361,6 +366,7 @@
#define HFI_CAPABILITY_BITRATE (HFI_COMMON_BASE + 0x8)
#define HFI_CAPABILITY_BFRAME (HFI_COMMON_BASE + 0x9)
#define HFI_CAPABILITY_HIER_P_NUM_ENH_LAYERS (HFI_COMMON_BASE + 0x10)
+#define HFI_CAPABILITY_ENC_LTR_COUNT (HFI_COMMON_BASE + 0x11)
struct hfi_capability_supported {
u32 capability_type;
@@ -531,6 +537,26 @@
u32 layer_id;
};
+#define HFI_LTR_MODE_DISABLE 0x0
+#define HFI_LTR_MODE_MANUAL 0x1
+#define HFI_LTR_MODE_PERIODIC 0x2
+
+struct hfi_ltrmode {
+ u32 ltrmode;
+ u32 ltrcount;
+ u32 trustmode;
+};
+
+struct hfi_ltruse {
+ u32 refltr;
+ u32 useconstrnt;
+ u32 frames;
+};
+
+struct hfi_ltrmark {
+ u32 markframe;
+};
+
struct hfi_frame_size {
u32 buffer_type;
u32 width;
diff --git a/drivers/mfd/wcd9xxx-core.c b/drivers/mfd/wcd9xxx-core.c
index 1c42431..5eb359e 100644
--- a/drivers/mfd/wcd9xxx-core.c
+++ b/drivers/mfd/wcd9xxx-core.c
@@ -555,7 +555,6 @@
{WCD9XXX_IRQ_EAR_PA_OCPL_FAULT, false},
{WCD9XXX_IRQ_HPH_L_PA_STARTUP, false},
{WCD9XXX_IRQ_HPH_R_PA_STARTUP, false},
- {WCD9320_IRQ_EAR_PA_STARTUP, false},
{WCD9XXX_IRQ_RESERVED_0, false},
{WCD9XXX_IRQ_RESERVED_1, false},
{WCD9XXX_IRQ_MAD_AUDIO, false},
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index f4493a1..3eedc32 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -2670,7 +2670,8 @@
*/
if ((!req && !(mq->flags & MMC_QUEUE_NEW_REQUEST)) ||
((mq->flags & MMC_QUEUE_URGENT_REQUEST) &&
- !(mq->mqrq_cur->req->cmd_flags & REQ_URGENT))) {
+ !(mq->mqrq_cur->req->cmd_flags &
+ MMC_REQ_NOREINSERT_MASK))) {
if (mmc_card_need_bkops(card))
mmc_start_bkops(card, false);
/* release host only when there are no more requests */
@@ -3270,4 +3271,3 @@
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Multimedia Card (MMC) block device driver");
-
diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c
index cef1a41..fa3dcdc 100644
--- a/drivers/mmc/card/queue.c
+++ b/drivers/mmc/card/queue.c
@@ -79,7 +79,8 @@
continue; /* fetch again */
} else if ((mq->flags & MMC_QUEUE_URGENT_REQUEST) &&
(mq->mqrq_cur->req &&
- !(mq->mqrq_cur->req->cmd_flags & REQ_URGENT))) {
+ !(mq->mqrq_cur->req->cmd_flags &
+ MMC_REQ_NOREINSERT_MASK))) {
/*
* clean current request when urgent request
* processing in progress and current request is
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 94a13f9..cd94960 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -895,9 +895,8 @@
mmc_post_req(host, host->areq->mrq, 0);
host->areq = NULL;
if (areq) {
- if (!(areq->cmd_flags & (REQ_URGENT
- | REQ_FUA
- | REQ_FLUSH))) {
+ if (!(areq->cmd_flags &
+ MMC_REQ_NOREINSERT_MASK)) {
areq->reinsert_req(areq);
mmc_post_req(host, areq->mrq, 0);
} else {
diff --git a/drivers/nfc/nfc-nci.c b/drivers/nfc/nfc-nci.c
index b808f97..c6192ed 100644
--- a/drivers/nfc/nfc-nci.c
+++ b/drivers/nfc/nfc-nci.c
@@ -30,8 +30,10 @@
struct qca199x_platform_data {
unsigned int irq_gpio;
+ unsigned int irq_gpio_clk_req;
+ unsigned int clk_req_irq_num;
unsigned int dis_gpio;
- unsigned int ven_gpio;
+ unsigned int clkreq_gpio;
unsigned int reg;
const char *clk_src_name;
unsigned int clk_src_gpio;
@@ -52,32 +54,48 @@
#define MAX_PACKET_SIZE (PACKET_HEADER_SIZE_NCI + 255)
#define MAX_QCA_REG (116)
/* will timeout in approx. 100ms as 10us steps */
+#define NFC_RF_CLK_FREQ (19200000)
#define NTF_TIMEOUT (10000)
#define CORE_RESET_RSP_GID (0x60)
#define CORE_RESET_OID (0x00)
#define CORE_RST_NTF_LENGTH (0x02)
+static void clk_req_update(struct work_struct *work);
struct qca199x_dev {
wait_queue_head_t read_wq;
- struct mutex read_mutex;
- struct i2c_client *client;
- struct miscdevice qca199x_device;
- unsigned int irq_gpio;
- unsigned int dis_gpio;
- unsigned int ven_gpio;
- bool irq_enabled;
- bool sent_first_nci_write;
- spinlock_t irq_enabled_lock;
- unsigned int count_irq;
+ struct mutex read_mutex;
+ struct i2c_client *client;
+ struct miscdevice qca199x_device;
+ /* NFC_IRQ new NCI data available */
+ unsigned int irq_gpio;
+ /* CLK_REQ IRQ to signal the state has changed */
+ unsigned int irq_gpio_clk_req;
+ /* Actual IRQ no. assigned to CLK_REQ */
+ unsigned int clk_req_irq_num;
+ unsigned int dis_gpio;
+ unsigned int clkreq_gpio;
+ /* NFC_IRQ state */
+ bool irq_enabled;
+ bool sent_first_nci_write;
+ spinlock_t irq_enabled_lock;
+ unsigned int count_irq;
+ /* CLK_REQ IRQ state */
+ bool irq_enabled_clk_req;
+ spinlock_t irq_enabled_lock_clk_req;
+ unsigned int count_irq_clk_req;
enum nfcc_state state;
- unsigned int clk_src_gpio;
- const char *clk_src_name;
- struct clk *s_clk;
- bool clk_run;
+ /* CLK control */
+ unsigned int clk_src_gpio;
+ const char *clk_src_name;
+ struct clk *s_clk;
+ bool clk_run;
+ struct work_struct msm_clock_controll_work;
+ struct workqueue_struct *my_wq;
};
static int nfc_i2c_write(struct i2c_client *client, u8 *buf, int len);
+static int nfcc_hw_check(struct i2c_client *client, unsigned short curr_addr);
static int nfcc_initialise(struct i2c_client *client, unsigned short curr_addr);
static int qca199x_clock_select(struct qca199x_dev *qca199x_dev);
static int qca199x_clock_deselect(struct qca199x_dev *qca199x_dev);
@@ -92,9 +110,10 @@
/*
* FTM-RAW-I2C RD/WR MODE
*/
-static struct devicemode device_mode;
-static int ftm_raw_write_mode;
-static int ftm_werr_code;
+static struct devicemode device_mode;
+static int ftm_raw_write_mode;
+static int ftm_werr_code;
+
static void qca199x_init_stat(struct qca199x_dev *qca199x_dev)
{
@@ -156,6 +175,95 @@
return mask;
}
+/* Handlers for CLK_REQ */
+static void qca199x_disable_irq_clk_req(struct qca199x_dev *qca199x_dev)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&qca199x_dev->irq_enabled_lock_clk_req, flags);
+ if (qca199x_dev->irq_enabled_clk_req) {
+ disable_irq_nosync(qca199x_dev->clk_req_irq_num);
+ qca199x_dev->irq_enabled_clk_req = false;
+ }
+ spin_unlock_irqrestore(&qca199x_dev->irq_enabled_lock_clk_req, flags);
+}
+
+
+static void qca199x_enable_irq_clk_req(struct qca199x_dev *qca199x_dev)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&qca199x_dev->irq_enabled_lock_clk_req, flags);
+ if (!qca199x_dev->irq_enabled_clk_req) {
+ qca199x_dev->irq_enabled_clk_req = true;
+ enable_irq(qca199x_dev->clk_req_irq_num);
+ }
+ spin_unlock_irqrestore(&qca199x_dev->irq_enabled_lock_clk_req, flags);
+}
+
+
+static irqreturn_t qca199x_dev_irq_handler_clk_req(int irq, void *dev_id)
+{
+ struct qca199x_dev *qca199x_dev = dev_id;
+ unsigned long flags;
+
+ spin_lock_irqsave(&qca199x_dev->irq_enabled_lock_clk_req, flags);
+ qca199x_dev->count_irq_clk_req++;
+ spin_unlock_irqrestore(&qca199x_dev->irq_enabled_lock_clk_req, flags);
+
+ queue_work(qca199x_dev->my_wq, &qca199x_dev->msm_clock_controll_work);
+
+ return IRQ_HANDLED;
+}
+
+
+static struct gpiomux_setting nfc_clk_on = {
+ .func = GPIOMUX_FUNC_2,
+ .drv = GPIOMUX_DRV_2MA,
+ .pull = GPIOMUX_PULL_NONE,
+};
+static struct gpiomux_setting nfc_clk_on_suspend = {
+ .func = GPIOMUX_FUNC_2,
+ .drv = GPIOMUX_DRV_2MA,
+ .pull = GPIOMUX_PULL_DOWN,
+};
+static struct gpiomux_setting nfc_clk_off = {
+ .func = GPIOMUX_FUNC_GPIO,
+ .drv = GPIOMUX_DRV_2MA,
+ .pull = GPIOMUX_PULL_DOWN,
+};
+
+static void clk_req_update(struct work_struct *work)
+{
+ struct i2c_client *client;
+ struct qca199x_dev *qca199x_dev;
+ int gpio_clk_req_level = 0;
+
+ qca199x_dev = container_of(work, struct qca199x_dev,
+ msm_clock_controll_work);
+ client = qca199x_dev->client;
+
+ /* Read status level of CLK_REQ from NFC Controller, QCA199_x */
+ gpio_clk_req_level = gpio_get_value(qca199x_dev->irq_gpio_clk_req);
+ if (gpio_clk_req_level == 1) {
+ if (qca199x_dev->clk_run == false) {
+ msm_gpiomux_write(qca199x_dev->clk_src_gpio,
+ GPIOMUX_ACTIVE, &nfc_clk_on, NULL);
+ msm_gpiomux_write(qca199x_dev->clk_src_gpio,
+ GPIOMUX_SUSPENDED, &nfc_clk_on_suspend, NULL);
+ qca199x_dev->clk_run = true;
+ }
+ } else{
+ if (qca199x_dev->clk_run == true) {
+ msm_gpiomux_write(qca199x_dev->clk_src_gpio,
+ GPIOMUX_ACTIVE, &nfc_clk_off, NULL);
+ msm_gpiomux_write(qca199x_dev->clk_src_gpio,
+ GPIOMUX_SUSPENDED, &nfc_clk_off, NULL);
+ qca199x_dev->clk_run = false;
+ }
+ }
+}
+
/*
* ONLY for FTM-RAW-I2C Mode
* Required to instigate a read, which comes from DT layer. This means we need
@@ -396,7 +504,14 @@
filp->private_data = qca199x_dev;
qca199x_init_stat(qca199x_dev);
+ /* Enable interrupts from NFCC NFC_INT new NCI data available */
qca199x_enable_irq(qca199x_dev);
+
+ if ((!strcmp(qca199x_dev->clk_src_name, "GPCLK")) ||
+ (!strcmp(qca199x_dev->clk_src_name, "GPCLK2"))) {
+ /* Enable interrupts from NFCC CLK_REQ */
+ qca199x_enable_irq_clk_req(qca199x_dev);
+ }
dev_dbg(&qca199x_dev->client->dev,
"%d,%d\n", imajor(inode), iminor(inode));
return ret;
@@ -759,6 +874,33 @@
return r;
}
+/* Check for availability of qca199x_ NFC controller hardware */
+static int nfcc_hw_check(struct i2c_client *client, unsigned short curr_addr)
+{
+ int r = 0;
+ unsigned char buf = 0;
+
+ client->addr = curr_addr;
+ /* Set-up Addr 0. No data written */
+ r = i2c_master_send(client, &buf, 1);
+ if (r < 0)
+ goto err_presence_check;
+ buf = 0;
+ /* Read back from Addr 0 */
+ r = i2c_master_recv(client, &buf, 1);
+ if (r < 0)
+ goto err_presence_check;
+
+ r = 0;
+ return r;
+
+err_presence_check:
+ r = -ENXIO;
+ dev_err(&client->dev,
+ "nfc-nci nfcc_presence check - no NFCC available\n");
+ return r;
+}
+/* Initialise qca199x_ NFC controller hardware */
static int nfcc_initialise(struct i2c_client *client, unsigned short curr_addr)
{
int r = 0;
@@ -949,6 +1091,14 @@
goto err_invalid_dis_gpio;
}
if (qca199x_dev->clk_run == false) {
+ /* Set clock rate */
+ if ((!strcmp(qca199x_dev->clk_src_name, "GPCLK")) ||
+ (!strcmp(qca199x_dev->clk_src_name, "GPCLK2"))) {
+ r = clk_set_rate(qca199x_dev->s_clk, NFC_RF_CLK_FREQ);
+ if (r)
+ goto err_invalid_clk;
+ }
+
r = clk_prepare_enable(qca199x_dev->s_clk);
if (r)
goto err_invalid_clk;
@@ -990,10 +1140,6 @@
if (r)
return -EINVAL;
- r = of_property_read_u32(np, "qcom,clk-gpio", &pdata->ven_gpio);
- if (r)
- return -EINVAL;
-
pdata->dis_gpio = of_get_named_gpio(np, "qcom,dis-gpio", 0);
if ((!gpio_is_valid(pdata->dis_gpio)))
return -EINVAL;
@@ -1004,11 +1150,24 @@
r = of_property_read_string(np, "qcom,clk-src", &pdata->clk_src_name);
- if ((!strcmp(pdata->clk_src_name, "GPCLK")) ||
- (!strcmp(pdata->clk_src_name, "GPCLK2")))
- pdata->clk_src_gpio = of_get_named_gpio(np,
- "qcom,clk-en-gpio", 0);
+ if (strcmp(pdata->clk_src_name, "GPCLK2")) {
+ r = of_property_read_u32(np, "qcom,clk-gpio",
+ &pdata->clkreq_gpio);
+ if (r)
+ return -EINVAL;
+ }
+ if ((!strcmp(pdata->clk_src_name, "GPCLK")) ||
+ (!strcmp(pdata->clk_src_name, "GPCLK2"))) {
+ pdata->clk_src_gpio = of_get_named_gpio(np,
+ "qcom,clk-src-gpio", 0);
+ if ((!gpio_is_valid(pdata->clk_src_gpio)))
+ return -EINVAL;
+ pdata->irq_gpio_clk_req = of_get_named_gpio(np,
+ "qcom,clk-req-gpio", 0);
+ if ((!gpio_is_valid(pdata->irq_gpio_clk_req)))
+ return -EINVAL;
+ }
if (r)
return -EINVAL;
return r;
@@ -1057,40 +1216,23 @@
return -ENOMEM;
}
qca199x_dev->client = client;
- if (gpio_is_valid(platform_data->irq_gpio)) {
- r = gpio_request(platform_data->irq_gpio, "nfc_irq_gpio");
- if (r) {
- dev_err(&client->dev, "unable to request gpio [%d]\n",
- platform_data->irq_gpio);
- goto err_free_dev;
- }
- r = gpio_direction_input(platform_data->irq_gpio);
- if (r) {
- dev_err(&client->dev,
- "unable to set direction for gpio [%d]\n",
- platform_data->irq_gpio);
- goto err_irq;
- }
- gpio_to_irq(0);
- irqn = gpio_to_irq(platform_data->irq_gpio);
- if (irqn < 0) {
- r = irqn;
- goto err_irq;
- }
- client->irq = irqn;
+ /*
+ * To be efficient we need to test whether nfcc hardware is physically
+ * present before attempting further hardware initialisation.
+ * For this we need to be sure the device is in ULPM state by
+ * setting disable line low early on.
+ *
+ */
- } else {
- dev_err(&client->dev, "irq gpio not provided\n");
- goto err_free_dev;
- }
+
if (gpio_is_valid(platform_data->dis_gpio)) {
r = gpio_request(platform_data->dis_gpio, "nfc_reset_gpio");
if (r) {
dev_err(&client->dev,
"NFC: unable to request gpio [%d]\n",
platform_data->dis_gpio);
- goto err_irq;
+ goto err_free_dev;
}
r = gpio_direction_output(platform_data->dis_gpio, 1);
if (r) {
@@ -1101,7 +1243,75 @@
}
} else {
dev_err(&client->dev, "dis gpio not provided\n");
- goto err_irq;
+ goto err_free_dev;
+ }
+
+ /* Put device in ULPM */
+ gpio_set_value(platform_data->dis_gpio, 0);
+ r = nfcc_hw_check(client, platform_data->reg);
+ if (r) {
+ /* We don't think there is hardware but just in case HPD */
+ gpio_set_value(platform_data->dis_gpio, 1);
+ goto err_dis_gpio;
+ }
+
+ if (gpio_is_valid(platform_data->irq_gpio)) {
+ r = gpio_request(platform_data->irq_gpio, "nfc_irq_gpio");
+ if (r) {
+ dev_err(&client->dev, "unable to request gpio [%d]\n",
+ platform_data->irq_gpio);
+ goto err_dis_gpio;
+ }
+ r = gpio_direction_input(platform_data->irq_gpio);
+ if (r) {
+
+ dev_err(&client->dev,
+ "unable to set direction for gpio [%d]\n",
+ platform_data->irq_gpio);
+ goto err_irq;
+ }
+ irqn = gpio_to_irq(platform_data->irq_gpio);
+ if (irqn < 0) {
+ r = irqn;
+ goto err_irq;
+ }
+ client->irq = irqn;
+
+ } else {
+ dev_err(&client->dev, "irq gpio not provided\n");
+ goto err_dis_gpio;
+ }
+ /* Interrupt from NFCC CLK_REQ to handle REF_CLK
+ o/p gating/selection */
+ if ((!strcmp(platform_data->clk_src_name, "GPCLK")) ||
+ (!strcmp(platform_data->clk_src_name, "GPCLK2"))) {
+ if (gpio_is_valid(platform_data->irq_gpio_clk_req)) {
+ r = gpio_request(platform_data->irq_gpio_clk_req,
+ "nfc_irq_gpio_clk_en");
+ if (r) {
+ dev_err(&client->dev, "unable to request CLK_EN gpio [%d]\n",
+ platform_data->irq_gpio_clk_req);
+ goto err_irq;
+ }
+ r = gpio_direction_input(
+ platform_data->irq_gpio_clk_req);
+ if (r) {
+ dev_err(&client->dev,
+ "unable to set direction for CLK_EN gpio [%d]\n",
+ platform_data->irq_gpio_clk_req);
+ goto err_irq_clk;
+ }
+ gpio_to_irq(0);
+ irqn = gpio_to_irq(platform_data->irq_gpio_clk_req);
+ if (irqn < 0) {
+ r = irqn;
+ goto err_irq_clk;
+ }
+ platform_data->clk_req_irq_num = irqn;
+ } else {
+ dev_err(&client->dev, "irq CLK_EN gpio not provided\n");
+ goto err_irq;
+ }
}
/* Get the clock source name and gpio from from Device Tree */
qca199x_dev->clk_src_name = platform_data->clk_src_name;
@@ -1112,37 +1322,49 @@
if (r == -1)
goto err_clk;
else
- goto err_dis_gpio;
+ goto err_irq_clk;
}
- platform_data->ven_gpio = of_get_named_gpio(node,
- "qcom,clk-gpio", 0);
- if (gpio_is_valid(platform_data->ven_gpio)) {
- r = gpio_request(platform_data->ven_gpio, "nfc_ven_gpio");
- if (r) {
- dev_err(&client->dev, "unable to request gpio [%d]\n",
- platform_data->ven_gpio);
- goto err_ven_gpio;
+ if (strcmp(platform_data->clk_src_name, "GPCLK2")) {
+ platform_data->clkreq_gpio =
+ of_get_named_gpio(node, "qcom,clk-gpio", 0);
+
+ if (gpio_is_valid(platform_data->clkreq_gpio)) {
+ r = gpio_request(platform_data->clkreq_gpio,
+ "nfc_clkreq_gpio");
+ if (r) {
+ dev_err(&client->dev, "unable to request gpio [%d]\n",
+ platform_data->clkreq_gpio);
+ goto err_clkreq_gpio;
+ }
+ r = gpio_direction_input(platform_data->clkreq_gpio);
+ if (r) {
+ dev_err(&client->dev,
+ "unable to set direction for gpio [%d]\n",
+ platform_data->clkreq_gpio);
+ goto err_clkreq_gpio;
+ }
+ } else {
+ dev_err(&client->dev, "clkreq gpio not provided\n");
+ goto err_clk;
}
- r = gpio_direction_input(platform_data->ven_gpio);
- if (r) {
- dev_err(&client->dev,
- "unable to set direction for gpio [%d]\n",
- platform_data->ven_gpio);
- goto err_ven_gpio;
- }
- } else {
- dev_err(&client->dev, "ven gpio not provided\n");
- goto err_clk;
+ qca199x_dev->clkreq_gpio = platform_data->clkreq_gpio;
}
qca199x_dev->dis_gpio = platform_data->dis_gpio;
qca199x_dev->irq_gpio = platform_data->irq_gpio;
- qca199x_dev->ven_gpio = platform_data->ven_gpio;
+ if ((!strcmp(platform_data->clk_src_name, "GPCLK")) ||
+ (!strcmp(platform_data->clk_src_name, "GPCLK2"))) {
+ qca199x_dev->irq_gpio_clk_req =
+ platform_data->irq_gpio_clk_req;
+ qca199x_dev->clk_req_irq_num =
+ platform_data->clk_req_irq_num;
+ }
/* init mutex and queues */
init_waitqueue_head(&qca199x_dev->read_wq);
mutex_init(&qca199x_dev->read_mutex);
spin_lock_init(&qca199x_dev->irq_enabled_lock);
+ spin_lock_init(&qca199x_dev->irq_enabled_lock_clk_req);
qca199x_dev->qca199x_device.minor = MISC_DYNAMIC_MINOR;
qca199x_dev->qca199x_device.name = "nfc-nci";
@@ -1154,6 +1376,27 @@
goto err_misc_register;
}
+
+ /*
+ * Reboot the NFCC now that all resources are ready
+ *
+ * The NFCC takes time to transition between power states.
+ * We wait 20uS for the NFCC to shutdown. (HPD)
+ * We wait 100uS for the NFCC to boot into ULPM.
+ */
+ gpio_set_value(platform_data->dis_gpio, 1);/* HPD */
+ msleep(20);
+ gpio_set_value(platform_data->dis_gpio, 0);/* ULPM */
+ msleep(100);
+
+
+ /* Here we perform a second presence check. */
+ r = nfcc_hw_check(client, platform_data->reg);
+ if (r) {
+ /* We don't think there is hardware but just in case HPD */
+ gpio_set_value(platform_data->dis_gpio, 1);
+ goto err_nfcc_not_present;
+ }
regulators.regulator = regulator_get(&client->dev, regulators.name);
if (IS_ERR(regulators.regulator)) {
r = PTR_ERR(regulators.regulator);
@@ -1172,6 +1415,7 @@
* for reading. It is cleared when all data has been read.
*/
device_mode.handle_flavour = UNSOLICITED_MODE;
+ /* NFC_INT IRQ */
qca199x_dev->irq_enabled = true;
r = request_irq(client->irq, qca199x_dev_irq_handler,
IRQF_TRIGGER_RISING, client->name, qca199x_dev);
@@ -1180,6 +1424,31 @@
goto err_request_irq_failed;
}
qca199x_disable_irq(qca199x_dev);
+ /* CLK_REQ IRQ */
+ if ((!strcmp(platform_data->clk_src_name, "GPCLK")) ||
+ (!strcmp(platform_data->clk_src_name, "GPCLK2"))) {
+ r = request_irq(qca199x_dev->clk_req_irq_num,
+ qca199x_dev_irq_handler_clk_req,
+ (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING),
+ client->name, qca199x_dev);
+ if (r) {
+ dev_err(&client->dev,
+ "nfc-nci probe: request_irq failed. irq no = %d\n, main irq = %d",
+ qca199x_dev->clk_req_irq_num, client->irq);
+ goto err_request_irq_failed;
+ }
+ qca199x_dev->irq_enabled_clk_req = true;
+ qca199x_disable_irq_clk_req(qca199x_dev);
+
+
+ qca199x_dev->my_wq =
+ create_singlethread_workqueue("qca1990x_CLK_REQ_queue");
+ if (!qca199x_dev->my_wq)
+ goto err_create_workq;
+
+ INIT_WORK(&qca199x_dev->msm_clock_controll_work,
+ clk_req_update);
+ }
i2c_set_clientdata(client, qca199x_dev);
gpio_set_value(platform_data->dis_gpio, 1);
dev_dbg(&client->dev,
@@ -1187,28 +1456,33 @@
__func__);
return 0;
+err_create_workq:
+ dev_err(&client->dev,
+ "nfc-nci probe: %s, work_queue creation failure\n",
+ __func__);
+ free_irq(client->irq, qca199x_dev);
+err_nfcc_not_present:
err_request_irq_failed:
misc_deregister(&qca199x_dev->qca199x_device);
err_misc_register:
mutex_destroy(&qca199x_dev->read_mutex);
-err_ven_gpio:
- gpio_free(platform_data->ven_gpio);
+err_clkreq_gpio:
+ if (strcmp(platform_data->clk_src_name, "GPCLK2"))
+ gpio_free(platform_data->clkreq_gpio);
err_clk:
qca199x_clock_deselect(qca199x_dev);
-err_dis_gpio:
- r = gpio_direction_input(platform_data->dis_gpio);
- if (r)
- dev_err(&client->dev, "nfc-nci probe: Unable to set direction\n");
+err_irq_clk:
if ((!strcmp(platform_data->clk_src_name, "GPCLK")) ||
- (!strcmp(platform_data->clk_src_name, "GPCLK2"))) {
- r = gpio_direction_input(platform_data->clk_src_gpio);
+ (!strcmp(platform_data->clk_src_name, "GPCLK2"))) {
+ r = gpio_direction_input(platform_data->irq_gpio_clk_req);
if (r)
dev_err(&client->dev, "nfc-nci probe: Unable to set direction\n");
- gpio_free(platform_data->clk_src_gpio);
+ gpio_free(platform_data->irq_gpio_clk_req);
}
- gpio_free(platform_data->dis_gpio);
err_irq:
gpio_free(platform_data->irq_gpio);
+err_dis_gpio:
+ gpio_free(platform_data->dis_gpio);
err_free_dev:
kfree(qca199x_dev);
return r;
@@ -1223,8 +1497,13 @@
misc_deregister(&qca199x_dev->qca199x_device);
mutex_destroy(&qca199x_dev->read_mutex);
gpio_free(qca199x_dev->irq_gpio);
+ if ((!strcmp(qca199x_dev->clk_src_name, "GPCLK")) ||
+ (!strcmp(qca199x_dev->clk_src_name, "GPCLK2"))) {
+ gpio_free(qca199x_dev->irq_gpio_clk_req);
+ }
gpio_free(qca199x_dev->dis_gpio);
- gpio_free(qca199x_dev->ven_gpio);
+ if (strcmp(qca199x_dev->clk_src_name, "GPCLK2"))
+ gpio_free(qca199x_dev->clkreq_gpio);
kfree(qca199x_dev);
return 0;
diff --git a/drivers/platform/msm/ipa/teth_bridge.c b/drivers/platform/msm/ipa/teth_bridge.c
index 79ec0c0..d08ac64 100644
--- a/drivers/platform/msm/ipa/teth_bridge.c
+++ b/drivers/platform/msm/ipa/teth_bridge.c
@@ -22,7 +22,6 @@
#include <linux/mutex.h>
#include <linux/skbuff.h>
#include <linux/types.h>
-#include <mach/bam_dmux.h>
#include <mach/ipa.h>
#include <mach/sps.h>
#include "ipa_i.h"
diff --git a/drivers/power/qpnp-bms.c b/drivers/power/qpnp-bms.c
index 6cac572..2559ff9 100644
--- a/drivers/power/qpnp-bms.c
+++ b/drivers/power/qpnp-bms.c
@@ -407,6 +407,14 @@
}
}
+static void disable_bms_irq_nosync(struct bms_irq *irq)
+{
+ if (!__test_and_set_bit(0, &irq->disabled)) {
+ disable_irq_nosync(irq->irq);
+ pr_debug("disabled irq %d\n", irq->irq);
+ }
+}
+
#define HOLD_OREG_DATA BIT(0)
static int lock_output_data(struct qpnp_bms_chip *chip)
{
@@ -3562,7 +3570,7 @@
struct qpnp_bms_chip *chip = _chip;
pr_debug("sw_cc_thr irq triggered\n");
- disable_bms_irq(&chip->sw_cc_thr_irq);
+ disable_bms_irq_nosync(&chip->sw_cc_thr_irq);
bms_stay_awake(&chip->soc_wake_source);
schedule_work(&chip->recalc_work);
return IRQ_HANDLED;
diff --git a/drivers/power/qpnp-charger.c b/drivers/power/qpnp-charger.c
index 1223fe0..40c5568 100644
--- a/drivers/power/qpnp-charger.c
+++ b/drivers/power/qpnp-charger.c
@@ -113,6 +113,7 @@
#define USB_OCP_THR 0x52
#define USB_OCP_CLR 0x53
#define BAT_IF_TEMP_STATUS 0x09
+#define BOOST_ILIM 0x78
#define REG_OFFSET_PERP_SUBTYPE 0x05
@@ -217,6 +218,7 @@
struct qpnp_chg_irq {
int irq;
unsigned long disabled;
+ unsigned long wake_enable;
};
struct qpnp_chg_regulator {
@@ -364,6 +366,7 @@
struct work_struct soc_check_work;
struct delayed_work aicl_check_work;
struct work_struct insertion_ocv_work;
+ struct work_struct ocp_clear_work;
struct qpnp_chg_regulator otg_vreg;
struct qpnp_chg_regulator boost_vreg;
struct qpnp_chg_regulator batfet_vreg;
@@ -531,6 +534,24 @@
}
}
+static void
+qpnp_chg_irq_wake_enable(struct qpnp_chg_irq *irq)
+{
+ if (!__test_and_set_bit(0, &irq->wake_enable)) {
+ pr_debug("number = %d\n", irq->irq);
+ enable_irq_wake(irq->irq);
+ }
+}
+
+static void
+qpnp_chg_irq_wake_disable(struct qpnp_chg_irq *irq)
+{
+ if (__test_and_clear_bit(0, &irq->wake_enable)) {
+ pr_debug("number = %d\n", irq->irq);
+ disable_irq_wake(irq->irq);
+ }
+}
+
#define USB_OTG_EN_BIT BIT(0)
static int
qpnp_chg_is_otg_en_set(struct qpnp_chg_chip *chip)
@@ -1215,10 +1236,36 @@
qpnp_chg_usb_usb_ocp_irq_handler(int irq, void *_chip)
{
struct qpnp_chg_chip *chip = _chip;
- int rc;
pr_debug("usb-ocp triggered\n");
+ schedule_work(&chip->ocp_clear_work);
+
+ return IRQ_HANDLED;
+}
+
+#define BOOST_ILIMIT_MIN 0x07
+#define BOOST_ILIMIT_DEF 0x02
+#define BOOST_ILIMT_MASK 0xFF
+static void
+qpnp_chg_ocp_clear_work(struct work_struct *work)
+{
+ int rc;
+ u8 usb_sts;
+ struct qpnp_chg_chip *chip = container_of(work,
+ struct qpnp_chg_chip, ocp_clear_work);
+
+ if (chip->type == SMBBP) {
+ rc = qpnp_chg_masked_write(chip,
+ chip->boost_base + BOOST_ILIM,
+ BOOST_ILIMT_MASK,
+ BOOST_ILIMIT_MIN, 1);
+ if (rc) {
+ pr_err("Failed to turn configure ilim rc = %d\n", rc);
+ return;
+ }
+ }
+
rc = qpnp_chg_masked_write(chip,
chip->usb_chgpth_base + USB_OCP_CLR,
OCP_CLR_BIT,
@@ -1234,7 +1281,29 @@
if (rc)
pr_err("Failed to turn off usb ovp rc = %d\n", rc);
- return IRQ_HANDLED;
+ if (chip->type == SMBBP) {
+ /* Wait for OCP circuitry to be powered up */
+ msleep(100);
+ rc = qpnp_chg_read(chip, &usb_sts,
+ INT_RT_STS(chip->usb_chgpth_base), 1);
+ if (rc) {
+ pr_err("failed to read interrupt sts %d\n", rc);
+ return;
+ }
+
+ if (usb_sts & COARSE_DET_USB_IRQ) {
+ rc = qpnp_chg_masked_write(chip,
+ chip->boost_base + BOOST_ILIM,
+ BOOST_ILIMT_MASK,
+ BOOST_ILIMIT_DEF, 1);
+ if (rc) {
+ pr_err("Failed to set ilim rc = %d\n", rc);
+ return;
+ }
+ } else {
+ pr_warn_ratelimited("USB short to GND detected!\n");
+ }
+ }
}
#define QPNP_CHG_VDDMAX_MIN 3400
@@ -1678,6 +1747,8 @@
u8 chgr_sts;
int rc;
+ qpnp_chg_irq_wake_disable(&chip->chg_fastchg);
+
rc = qpnp_chg_read(chip, &chgr_sts, INT_RT_STS(chip->chgr_base), 1);
if (rc)
pr_err("failed to read interrupt sts %d\n", rc);
@@ -1781,6 +1852,17 @@
if (!qpnp_chg_is_otg_en_set(chip))
return 0;
+ if (chip->type == SMBBP) {
+ rc = qpnp_chg_masked_write(chip,
+ chip->boost_base + BOOST_ILIM,
+ BOOST_ILIMT_MASK,
+ BOOST_ILIMIT_DEF, 1);
+ if (rc) {
+ pr_err("Failed to set ilim rc = %d\n", rc);
+ return rc;
+ }
+ }
+
/* enable usb ovp fet */
rc = qpnp_chg_masked_write(chip,
chip->usb_chgpth_base + CHGR_USB_USB_OTG_CTL,
@@ -1804,11 +1886,23 @@
switch_usb_to_host_mode(struct qpnp_chg_chip *chip)
{
int rc;
+ u8 usb_sts;
pr_debug("switch to host mode\n");
if (qpnp_chg_is_otg_en_set(chip))
return 0;
+ if (chip->type == SMBBP) {
+ rc = qpnp_chg_masked_write(chip,
+ chip->boost_base + BOOST_ILIM,
+ BOOST_ILIMT_MASK,
+ BOOST_ILIMIT_MIN, 1);
+ if (rc) {
+ pr_err("Failed to turn configure ilim rc = %d\n", rc);
+ return rc;
+ }
+ }
+
if (!qpnp_chg_is_dc_chg_plugged_in(chip)) {
rc = qpnp_chg_force_run_on_batt(chip, 1);
if (rc) {
@@ -1827,6 +1921,30 @@
return rc;
}
+ if (chip->type == SMBBP) {
+ /* Wait for OCP circuitry to be powered up */
+ msleep(100);
+ rc = qpnp_chg_read(chip, &usb_sts,
+ INT_RT_STS(chip->usb_chgpth_base), 1);
+ if (rc) {
+ pr_err("failed to read interrupt sts %d\n", rc);
+ return rc;
+ }
+
+ if (usb_sts & COARSE_DET_USB_IRQ) {
+ rc = qpnp_chg_masked_write(chip,
+ chip->boost_base + BOOST_ILIM,
+ BOOST_ILIMT_MASK,
+ BOOST_ILIMIT_DEF, 1);
+ if (rc) {
+ pr_err("Failed to set ilim rc = %d\n", rc);
+ return rc;
+ }
+ } else {
+ pr_warn_ratelimited("USB short to GND detected!\n");
+ }
+ }
+
return 0;
}
@@ -2148,6 +2266,7 @@
&& soc <= chip->soc_resume_limit) {
pr_debug("resuming charging at %d%% soc\n", soc);
chip->resuming_charging = true;
+ qpnp_chg_irq_wake_enable(&chip->chg_fastchg);
qpnp_chg_set_appropriate_vbatdet(chip);
qpnp_chg_charge_en(chip, !chip->charging_disabled);
}
@@ -3848,10 +3967,10 @@
return rc;
}
- enable_irq_wake(chip->chg_trklchg.irq);
- enable_irq_wake(chip->chg_failed.irq);
+ qpnp_chg_irq_wake_enable(&chip->chg_trklchg);
+ qpnp_chg_irq_wake_enable(&chip->chg_failed);
qpnp_chg_disable_irq(&chip->chg_vbatdet_lo);
- enable_irq_wake(chip->chg_vbatdet_lo.irq);
+ qpnp_chg_irq_wake_enable(&chip->chg_vbatdet_lo);
break;
case SMBB_BAT_IF_SUBTYPE:
@@ -3874,7 +3993,7 @@
return rc;
}
- enable_irq_wake(chip->batt_pres.irq);
+ qpnp_chg_irq_wake_enable(&chip->batt_pres);
chip->batt_temp_ok.irq = spmi_get_irq_byname(spmi,
spmi_resource, "bat-temp-ok");
@@ -3893,7 +4012,7 @@
}
qpnp_chg_bat_if_batt_temp_irq_handler(0, chip);
- enable_irq_wake(chip->batt_temp_ok.irq);
+ qpnp_chg_irq_wake_enable(&chip->batt_temp_ok);
break;
case SMBB_BUCK_SUBTYPE:
@@ -3975,11 +4094,11 @@
return rc;
}
- enable_irq_wake(chip->usb_ocp.irq);
+ qpnp_chg_irq_wake_enable(&chip->usb_ocp);
}
- enable_irq_wake(chip->usbin_valid.irq);
- enable_irq_wake(chip->chg_gone.irq);
+ qpnp_chg_irq_wake_enable(&chip->usbin_valid);
+ qpnp_chg_irq_wake_enable(&chip->chg_gone);
break;
case SMBB_DC_CHGPTH_SUBTYPE:
chip->dcin_valid.irq = spmi_get_irq_byname(spmi,
@@ -3998,7 +4117,7 @@
return rc;
}
- enable_irq_wake(chip->dcin_valid.irq);
+ qpnp_chg_irq_wake_enable(&chip->dcin_valid);
break;
}
}
@@ -4527,6 +4646,8 @@
INIT_WORK(&chip->reduce_power_stage_work,
qpnp_chg_reduce_power_stage_work);
mutex_init(&chip->batfet_vreg_lock);
+ INIT_WORK(&chip->ocp_clear_work,
+ qpnp_chg_ocp_clear_work);
INIT_WORK(&chip->batfet_lcl_work,
qpnp_chg_batfet_lcl_work);
INIT_WORK(&chip->insertion_ocv_work,
diff --git a/drivers/regulator/onsemi-ncp6335d.c b/drivers/regulator/onsemi-ncp6335d.c
index 71702b2..3d4dd04 100644
--- a/drivers/regulator/onsemi-ncp6335d.c
+++ b/drivers/regulator/onsemi-ncp6335d.c
@@ -24,6 +24,8 @@
#include <linux/of_gpio.h>
#include <linux/regmap.h>
#include <linux/regulator/onsemi-ncp6335d.h>
+#include <linux/string.h>
+#include <mach/gpiomux.h>
/* registers */
#define REG_NCP6335D_PID 0x03
@@ -36,6 +38,7 @@
/* constraints */
#define NCP6335D_MIN_VOLTAGE_UV 600000
#define NCP6335D_STEP_VOLTAGE_UV 6250
+#define NCP6335D_VOLTAGE_STEPS 128
#define NCP6335D_MIN_SLEW_NS 166
#define NCP6335D_MAX_SLEW_NS 1333
@@ -169,6 +172,17 @@
return rc;
}
+static int ncp6335d_list_voltage(struct regulator_dev *rdev,
+ unsigned selector)
+{
+ struct ncp6335d_info *dd = rdev_get_drvdata(rdev);
+
+ if (selector >= NCP6335D_VOLTAGE_STEPS)
+ return 0;
+
+ return selector * dd->step_size + dd->min_voltage;
+}
+
static int ncp6335d_set_mode(struct regulator_dev *rdev,
unsigned int mode)
{
@@ -223,6 +237,7 @@
static struct regulator_ops ncp6335d_ops = {
.set_voltage = ncp6335d_set_voltage,
.get_voltage = ncp6335d_get_voltage,
+ .list_voltage = ncp6335d_list_voltage,
.enable = ncp6335d_enable,
.disable = ncp6335d_disable,
.set_mode = ncp6335d_set_mode,
@@ -232,7 +247,7 @@
static struct regulator_desc rdesc = {
.name = "ncp6335d",
.owner = THIS_MODULE,
- .n_voltages = 128,
+ .n_voltages = NCP6335D_VOLTAGE_STEPS,
.ops = &ncp6335d_ops,
};
@@ -297,6 +312,31 @@
return ret;
}
+
+static int ncp6335d_parse_tlmm(struct device_node *node,
+ struct ncp6335d_info *dd)
+{
+ int val, ret = 0;
+ u32 tmp[2];
+
+ if (!of_find_property(node, "onnn,tlmm-config", NULL))
+ return ret;
+
+ ret = of_property_read_u32_array(node, "onnn,tlmm-config", tmp, 2);
+ if (ret) {
+ dev_err(dd->dev, "onnn,tlmm-config is misconfigured, ret = %d",
+ ret);
+ return ret;
+ }
+
+ val = msm_tlmm_misc_reg_read(TLMM_SPARE_REG);
+ val &= ~tmp[0];
+ val |= tmp[1] & tmp[0];
+ msm_tlmm_misc_reg_write(TLMM_SPARE_REG, val);
+
+ return ret;
+}
+
static int __devinit ncp6335d_init(struct i2c_client *client,
struct ncp6335d_info *dd,
const struct ncp6335d_platform_data *pdata)
@@ -330,6 +370,10 @@
if (rc)
return rc;
+ rc = ncp6335d_parse_tlmm(client->dev.of_node, dd);
+ if (rc)
+ return rc;
+
/* get the current programmed voltage */
rc = regmap_read(dd->regmap, dd->vsel_reg, &val);
if (rc) {
@@ -426,6 +470,7 @@
{
struct ncp6335d_platform_data *pdata = NULL;
struct regulator_init_data *init_data;
+ const char *mode_name;
int rc;
init_data = of_get_regulator_init_data(&client->dev,
@@ -474,7 +519,23 @@
init_data->constraints.valid_modes_mask =
REGULATOR_MODE_NORMAL |
REGULATOR_MODE_FAST;
- init_data->constraints.initial_mode = REGULATOR_MODE_NORMAL;
+
+ rc = of_property_read_string(client->dev.of_node, "onnn,mode",
+ &mode_name);
+ if (!rc) {
+ if (strcmp("pwm", mode_name) == 0) {
+ init_data->constraints.initial_mode =
+ REGULATOR_MODE_FAST;
+ } else if (strcmp("auto", mode_name) == 0) {
+ init_data->constraints.initial_mode =
+ REGULATOR_MODE_NORMAL;
+ } else {
+ dev_err(&client->dev, "onnn,mode, unknown regulator mode: %s\n",
+ mode_name);
+ return NULL;
+ }
+ }
+
return pdata;
}
diff --git a/drivers/tty/serial/msm_serial_hs.c b/drivers/tty/serial/msm_serial_hs.c
index ecfacc0..066419f 100644
--- a/drivers/tty/serial/msm_serial_hs.c
+++ b/drivers/tty/serial/msm_serial_hs.c
@@ -551,6 +551,25 @@
writel_relaxed(value, uport->membase + offset);
}
+static int sps_rx_disconnect(struct sps_pipe *sps_pipe_handler)
+{
+ struct sps_connect config;
+ int ret;
+
+ ret = sps_get_config(sps_pipe_handler, &config);
+ if (ret) {
+ pr_err("%s: sps_get_config() failed ret %d\n", __func__, ret);
+ return ret;
+ }
+ config.options |= SPS_O_POLL;
+ ret = sps_set_config(sps_pipe_handler, &config);
+ if (ret) {
+ pr_err("%s: sps_set_config() failed ret %d\n", __func__, ret);
+ return ret;
+ }
+ return sps_disconnect(sps_pipe_handler);
+}
+
static void hex_dump_ipc(char *prefix, char *string, int size)
{
char linebuf[512];
@@ -1191,7 +1210,7 @@
ret = wait_event_timeout(msm_uport->rx.wait,
msm_uport->rx_bam_inprogress == false,
RX_FLUSH_COMPLETE_TIMEOUT);
- ret = sps_disconnect(sps_pipe_handle);
+ ret = sps_rx_disconnect(sps_pipe_handle);
if (ret)
MSM_HS_ERR("%s(): sps_disconnect failed\n",
__func__);
@@ -1275,7 +1294,7 @@
struct sps_pipe *sps_pipe_handle = rx->prod.pipe_handle;
int ret = 0;
- ret = sps_disconnect(sps_pipe_handle);
+ ret = sps_rx_disconnect(sps_pipe_handle);
if (ret)
MSM_HS_ERR("%s(): sps_disconnect failed\n", __func__);
@@ -2529,6 +2548,8 @@
/* Initialize the tx */
tx->tx_ready_int_en = 0;
tx->dma_in_flight = 0;
+ msm_uport->tty_flush_receive = false;
+ MSM_HS_DBG("%s: Setting tty_flush_receive to false\n", __func__);
if (!is_blsp_uart(msm_uport)) {
tx->xfer.complete_func = msm_hs_dmov_tx_callback;
diff --git a/drivers/usb/dwc3/debugfs.c b/drivers/usb/dwc3/debugfs.c
index a2580fc..a192398 100644
--- a/drivers/usb/dwc3/debugfs.c
+++ b/drivers/usb/dwc3/debugfs.c
@@ -794,9 +794,9 @@
.release = single_release,
};
-static unsigned int ep_addr_rxdbg_mask;
+static unsigned int ep_addr_rxdbg_mask = 1;
module_param(ep_addr_rxdbg_mask, uint, S_IRUGO | S_IWUSR);
-static unsigned int ep_addr_txdbg_mask;
+static unsigned int ep_addr_txdbg_mask = 1;
module_param(ep_addr_txdbg_mask, uint, S_IRUGO | S_IWUSR);
/* Maximum debug message length */
diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
index 0cfd515..c07f18c 100644
--- a/drivers/usb/dwc3/ep0.c
+++ b/drivers/usb/dwc3/ep0.c
@@ -291,6 +291,7 @@
struct dwc3_ep *dep = to_dwc3_ep(ep);
struct dwc3 *dwc = dep->dwc;
+ dbg_event(dep->number, "EP0STAL", value);
dwc3_ep0_stall_and_restart(dwc);
return 0;
@@ -752,8 +753,10 @@
dwc->delayed_status = true;
out:
- if (ret < 0)
+ if (ret < 0) {
+ dbg_event(0x0, "ERRSTAL", ret);
dwc3_ep0_stall_and_restart(dwc);
+ }
}
bool zlp_required;
@@ -819,7 +822,7 @@
if ((epnum & 1) && ur->actual < ur->length) {
/* for some reason we did not get everything out */
-
+ dbg_event(epnum, "INDATSTAL", 0);
dwc3_ep0_stall_and_restart(dwc);
} else {
/*
@@ -855,6 +858,7 @@
if (ret < 0) {
dev_dbg(dwc->dev, "Invalid Test #%d\n",
dwc->test_mode_nr);
+ dbg_event(0x00, "INVALTEST", ret);
dwc3_ep0_stall_and_restart(dwc);
return;
}
@@ -1034,6 +1038,7 @@
dev_vdbg(dwc->dev, "Wrong direction for Data phase\n");
dwc3_ep0_end_control_data(dwc, dep);
+ dbg_event(epnum, "WRONGDR", 0);
dwc3_ep0_stall_and_restart(dwc);
return;
}
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 7439c45..4be032a 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -2204,6 +2204,7 @@
return;
}
+ dbg_event(dep->number, "XFRCOMP", 0);
dwc3_endpoint_transfer_complete(dwc, dep, event, 1);
break;
case DWC3_DEPEVT_XFERINPROGRESS:
@@ -2213,9 +2214,11 @@
return;
}
+ dbg_event(dep->number, "XFRPROG", 0);
dwc3_endpoint_transfer_complete(dwc, dep, event, 0);
break;
case DWC3_DEPEVT_XFERNOTREADY:
+ dbg_event(dep->number, "XFRNRDY", 0);
if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) {
dwc3_gadget_start_isoc(dwc, dep, event);
} else {
diff --git a/drivers/usb/gadget/f_mbim.c b/drivers/usb/gadget/f_mbim.c
index 15f20ca..88a7bde 100644
--- a/drivers/usb/gadget/f_mbim.c
+++ b/drivers/usb/gadget/f_mbim.c
@@ -1710,8 +1710,10 @@
return -EIO;
}
+ spin_lock(&dev->lock);
while (list_empty(&dev->cpkt_req_q)) {
pr_debug("Requests list is empty. Wait.\n");
+ spin_unlock(&dev->lock);
ret = wait_event_interruptible(dev->read_wq,
!list_empty(&dev->cpkt_req_q));
if (ret < 0) {
@@ -1720,11 +1722,13 @@
return -ERESTARTSYS;
}
pr_debug("Received request packet\n");
+ spin_lock(&dev->lock);
}
cpkt = list_first_entry(&dev->cpkt_req_q, struct ctrl_pkt,
list);
if (cpkt->len > count) {
+ spin_unlock(&dev->lock);
mbim_unlock(&dev->read_excl);
pr_err("cpkt size too big:%d > buf size:%d\n",
cpkt->len, count);
@@ -1734,6 +1738,7 @@
pr_debug("cpkt size:%d\n", cpkt->len);
list_del(&cpkt->list);
+ spin_unlock(&dev->lock);
mbim_unlock(&dev->read_excl);
ret = copy_to_user(buf, cpkt->buf, cpkt->len);
diff --git a/drivers/video/msm/mdss/dsi_host_v2.c b/drivers/video/msm/mdss/dsi_host_v2.c
index 53b6fc6..ca7f199 100644
--- a/drivers/video/msm/mdss/dsi_host_v2.c
+++ b/drivers/video/msm/mdss/dsi_host_v2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2014, 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
@@ -524,8 +524,11 @@
if (readl_poll_timeout((ctrl_base + DSI_STATUS),
status,
((status & 0x02) == 0),
- DSI_POLL_SLEEP_US, DSI_POLL_TIMEOUT_US))
+ DSI_POLL_SLEEP_US, DSI_POLL_TIMEOUT_US)) {
pr_err("%s: DSI status=%x failed\n", __func__, status);
+ pr_err("%s: Doing sw reset\n", __func__);
+ msm_dsi_sw_reset();
+ }
/* Check for x_HS_FIFO_EMPTY */
if (readl_poll_timeout((ctrl_base + DSI_FIFO_STATUS),
diff --git a/drivers/video/msm/mdss/mdp3_ppp.c b/drivers/video/msm/mdss/mdp3_ppp.c
index 270c096..8cc29da8 100644
--- a/drivers/video/msm/mdss/mdp3_ppp.c
+++ b/drivers/video/msm/mdss/mdp3_ppp.c
@@ -99,6 +99,7 @@
struct timer_list free_bw_timer;
struct work_struct free_bw_work;
bool bw_on;
+ bool bw_optimal;
};
static struct ppp_status *ppp_stat;
@@ -335,21 +336,54 @@
mdp3_irq_disable(MDP3_PPP_DONE);
}
+int mdp3_ppp_vote_update(struct msm_fb_data_type *mfd)
+{
+ struct mdss_panel_info *panel_info = mfd->panel_info;
+ uint64_t req_bw = 0, ab = 0, ib = 0;
+ int rate = 0;
+ int rc = 0;
+ if (!ppp_stat->bw_on)
+ pr_err("%s: PPP vote update in wrong state\n", __func__);
+
+ rate = MDP_BLIT_CLK_RATE;
+ req_bw = panel_info->xres * panel_info->yres *
+ panel_info->mipi.frame_rate *
+ MDP_PPP_MAX_BPP *
+ MDP_PPP_DYNAMIC_FACTOR *
+ MDP_PPP_MAX_READ_WRITE;
+ ib = (req_bw * 3) / 2;
+
+ if (ppp_stat->bw_optimal)
+ ab = ib / 2;
+ else
+ ab = req_bw;
+ rc = mdp3_bus_scale_set_quota(MDP3_CLIENT_PPP, ab, ib);
+ if (rc < 0) {
+ pr_err("%s: scale_set_quota failed\n", __func__);
+ return rc;
+ }
+ return rc;
+}
+
int mdp3_ppp_turnon(struct msm_fb_data_type *mfd, int on_off)
{
struct mdss_panel_info *panel_info = mfd->panel_info;
- uint64_t ab = 0, ib = 0;
+ uint64_t req_bw = 0, ab = 0, ib = 0;
int rate = 0;
int rc;
if (on_off) {
rate = MDP_BLIT_CLK_RATE;
- ab = panel_info->xres * panel_info->yres *
+ req_bw = panel_info->xres * panel_info->yres *
panel_info->mipi.frame_rate *
MDP_PPP_MAX_BPP *
MDP_PPP_DYNAMIC_FACTOR *
MDP_PPP_MAX_READ_WRITE;
- ib = (ab * 3) / 2;
+ ib = (req_bw * 3) / 2;
+ if (ppp_stat->bw_optimal)
+ ab = ib / 2;
+ else
+ ab = req_bw;
}
mdp3_clk_set_rate(MDP3_CLK_CORE, rate, MDP3_CLIENT_PPP);
rc = mdp3_clk_enable(on_off, 0);
@@ -367,6 +401,13 @@
return 0;
}
+bool mdp3_optimal_bw(int req_cnt)
+{
+ if (req_cnt == 1 && ppp_stat->req_q.count == 1)
+ return true;
+ return false;
+}
+
void mdp3_start_ppp(struct ppp_blit_op *blit_op)
{
/* Wait for the pipe to clear */
@@ -1030,6 +1071,7 @@
pr_err("%s: mdp3_iommu_enable failed\n", __func__);
return;
}
+ ppp_stat->bw_optimal = mdp3_optimal_bw(req->count);
mdp3_ppp_turnon(mfd, 1);
if (rc < 0) {
mdp3_iommu_disable(MDP3_CLIENT_PPP);
@@ -1063,6 +1105,10 @@
if (ppp_stat->wait_for_pop)
complete(&ppp_stat->pop_q_comp);
mutex_unlock(&ppp_stat->req_mutex);
+ if (req && (ppp_stat->bw_optimal != mdp3_optimal_bw(req->count))) {
+ ppp_stat->bw_optimal = !ppp_stat->bw_optimal;
+ mdp3_ppp_vote_update(mfd);
+ }
}
mod_timer(&ppp_stat->free_bw_timer, jiffies +
msecs_to_jiffies(MDP_RELEASE_BW_TIMEOUT));
diff --git a/drivers/video/msm/mdss/mdss.h b/drivers/video/msm/mdss/mdss.h
index 8c2ac09..ada1281 100644
--- a/drivers/video/msm/mdss/mdss.h
+++ b/drivers/video/msm/mdss/mdss.h
@@ -119,6 +119,7 @@
u8 has_wfd_blk;
u8 has_wb_ad;
+ u32 rotator_ot_limit;
u32 mdp_irq_mask;
u32 mdp_hist_irq_mask;
diff --git a/drivers/video/msm/mdss/mdss_mdp.c b/drivers/video/msm/mdss/mdss_mdp.c
index bc9a2a9..088472f 100644
--- a/drivers/video/msm/mdss/mdss_mdp.c
+++ b/drivers/video/msm/mdss/mdss_mdp.c
@@ -2109,6 +2109,10 @@
&data);
mdata->rot_block_size = (!rc ? data : 128);
+ rc = of_property_read_u32(pdev->dev.of_node,
+ "qcom,mdss-rotator-ot-limit", &data);
+ mdata->rotator_ot_limit = (!rc ? data : 0);
+
mdata->has_bwc = of_property_read_bool(pdev->dev.of_node,
"qcom,mdss-has-bwc");
mdata->has_decimation = of_property_read_bool(pdev->dev.of_node,
diff --git a/drivers/video/msm/mdss/mdss_mdp_intf_writeback.c b/drivers/video/msm/mdss/mdss_mdp_intf_writeback.c
index ff55c57..27a7707 100644
--- a/drivers/video/msm/mdss/mdss_mdp_intf_writeback.c
+++ b/drivers/video/msm/mdss/mdss_mdp_intf_writeback.c
@@ -17,6 +17,9 @@
#include "mdss_mdp_rotator.h"
#include "mdss_panel.h"
+#define VBIF_WR_LIM_CONF 0xC0
+#define MDSS_DEFAULT_OT_SETTING 0x10
+
enum mdss_mdp_writeback_type {
MDSS_MDP_WRITEBACK_TYPE_ROTATOR,
MDSS_MDP_WRITEBACK_TYPE_LINE,
@@ -34,6 +37,9 @@
u32 intr_type;
u32 intf_num;
+ u32 xin_id;
+ u32 wr_lim;
+
u32 opmode;
struct mdss_mdp_format_params *dst_fmt;
u16 width;
@@ -55,26 +61,31 @@
.type = MDSS_MDP_WRITEBACK_TYPE_ROTATOR,
.intr_type = MDSS_MDP_IRQ_WB_ROT_COMP,
.intf_num = 0,
+ .xin_id = 3,
},
{
.type = MDSS_MDP_WRITEBACK_TYPE_ROTATOR,
.intr_type = MDSS_MDP_IRQ_WB_ROT_COMP,
.intf_num = 1,
+ .xin_id = 11,
},
{
.type = MDSS_MDP_WRITEBACK_TYPE_LINE,
.intr_type = MDSS_MDP_IRQ_WB_ROT_COMP,
.intf_num = 0,
+ .xin_id = 3,
},
{
.type = MDSS_MDP_WRITEBACK_TYPE_LINE,
.intr_type = MDSS_MDP_IRQ_WB_ROT_COMP,
.intf_num = 1,
+ .xin_id = 11,
},
{
.type = MDSS_MDP_WRITEBACK_TYPE_WFD,
.intr_type = MDSS_MDP_IRQ_WB_WFD,
.intf_num = 0,
+ .xin_id = 6,
},
};
@@ -438,9 +449,12 @@
{
struct mdss_mdp_writeback_ctx *ctx;
struct mdss_mdp_writeback_arg *wb_args;
- u32 flush_bits;
+ u32 flush_bits, val, off;
int ret;
+ if (!ctl || !ctl->mdata)
+ return -ENODEV;
+
ctx = (struct mdss_mdp_writeback_ctx *) ctl->priv_data;
if (!ctx)
return -ENODEV;
@@ -451,6 +465,18 @@
return -EPERM;
}
+ if (ctl->mdata->rotator_ot_limit) {
+ if (ctx->type == MDSS_MDP_WRITEBACK_TYPE_ROTATOR)
+ ctx->wr_lim = ctl->mdata->rotator_ot_limit;
+ else
+ ctx->wr_lim = MDSS_DEFAULT_OT_SETTING;
+ off = (ctx->xin_id % 4) * 8;
+ val = readl_relaxed(ctl->mdata->vbif_base + VBIF_WR_LIM_CONF);
+ val &= ~(0xFF << off);
+ val |= (ctx->wr_lim) << off;
+ writel_relaxed(val, ctl->mdata->vbif_base + VBIF_WR_LIM_CONF);
+ }
+
wb_args = (struct mdss_mdp_writeback_arg *) arg;
if (!wb_args)
return -ENOENT;
diff --git a/fs/fat/cache.c b/fs/fat/cache.c
index 1cc7038..bab81ca 100644
--- a/fs/fat/cache.c
+++ b/fs/fat/cache.c
@@ -294,8 +294,9 @@
if (ret < 0)
return ret;
else if (ret == FAT_ENT_EOF) {
- fat_fs_error(sb, "%s: request beyond EOF (i_pos %lld)",
- __func__, MSDOS_I(inode)->i_pos);
+ fat_fs_error_ratelimit(sb,
+ "%s: request beyond EOF (i_pos %lld)",
+ __func__, MSDOS_I(inode)->i_pos);
return -EIO;
}
return dclus;
diff --git a/include/linux/Kbuild b/include/linux/Kbuild
index 4640d3b..6d18d0f 100755
--- a/include/linux/Kbuild
+++ b/include/linux/Kbuild
@@ -146,6 +146,7 @@
header-y += genetlink.h
header-y += gfs2_ondisk.h
header-y += gigaset_dev.h
+header-y += hbtp_input.h
header-y += hdlc.h
header-y += hdlcdrv.h
header-y += hdreg.h
diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h
index 130d0fd..ac750ea 100644
--- a/include/linux/blk_types.h
+++ b/include/linux/blk_types.h
@@ -176,6 +176,8 @@
REQ_SANITIZE)
#define REQ_CLONE_MASK REQ_COMMON_MASK
+#define MMC_REQ_NOREINSERT_MASK (REQ_URGENT | REQ_FUA | REQ_FLUSH)
+
#define REQ_RAHEAD (1 << __REQ_RAHEAD)
#define REQ_THROTTLED (1 << __REQ_THROTTLED)
diff --git a/include/linux/diagchar.h b/include/linux/diagchar.h
index d525e84..f78d418 100644
--- a/include/linux/diagchar.h
+++ b/include/linux/diagchar.h
@@ -119,10 +119,10 @@
/* This needs to be modified manually now, when we add
a new RANGE of SSIDs to the msg_mask_tbl */
#define MSG_MASK_TBL_CNT 24
-#define EVENT_LAST_ID 0x09CB
+#define EVENT_LAST_ID 0x09F6
#define MSG_SSID_0 0
-#define MSG_SSID_0_LAST 97
+#define MSG_SSID_0_LAST 101
#define MSG_SSID_1 500
#define MSG_SSID_1_LAST 506
#define MSG_SSID_2 1000
@@ -138,7 +138,7 @@
#define MSG_SSID_7 4600
#define MSG_SSID_7_LAST 4614
#define MSG_SSID_8 5000
-#define MSG_SSID_8_LAST 5030
+#define MSG_SSID_8_LAST 5031
#define MSG_SSID_9 5500
#define MSG_SSID_9_LAST 5516
#define MSG_SSID_10 6000
@@ -154,7 +154,7 @@
#define MSG_SSID_15 8000
#define MSG_SSID_15_LAST 8000
#define MSG_SSID_16 8500
-#define MSG_SSID_16_LAST 8523
+#define MSG_SSID_16_LAST 8524
#define MSG_SSID_17 9000
#define MSG_SSID_17_LAST 9008
#define MSG_SSID_18 9500
@@ -166,7 +166,7 @@
#define MSG_SSID_21 10300
#define MSG_SSID_21_LAST 10300
#define MSG_SSID_22 10350
-#define MSG_SSID_22_LAST 10374
+#define MSG_SSID_22_LAST 10377
#define MSG_SSID_23 0xC000
#define MSG_SSID_23_LAST 0xC063
@@ -182,6 +182,7 @@
MSG_LVL_LOW,
MSG_LVL_ERROR,
MSG_LVL_LOW,
+ MSG_LVL_LOW,
MSG_LVL_MED,
MSG_LVL_MED,
MSG_LVL_HIGH,
@@ -280,7 +281,7 @@
MSG_LVL_LOW,
MSG_LVL_LOW,
MSG_LVL_LOW|MSG_LVL_MED|MSG_LVL_HIGH|MSG_LVL_ERROR|MSG_LVL_FATAL,
- MSG_LVL_MED,
+ MSG_LVL_LOW,
MSG_LVL_LOW|MSG_LVL_MED|MSG_LVL_HIGH|MSG_LVL_ERROR|MSG_LVL_FATAL,
MSG_LVL_LOW,
MSG_LVL_MED,
@@ -292,6 +293,10 @@
MSG_LVL_LOW,
MSG_LVL_LOW|MSG_LVL_MED|MSG_LVL_HIGH|MSG_LVL_ERROR|MSG_LVL_FATAL,
MSG_LVL_MED,
+ MSG_LVL_HIGH,
+ MSG_LVL_LOW,
+ MSG_LVL_HIGH,
+ MSG_LVL_HIGH
};
static const uint32_t msg_bld_masks_1[] = {
@@ -321,7 +326,8 @@
MSG_LVL_MED,
MSG_LVL_MED,
MSG_LVL_MED,
- MSG_LVL_MED,
+ MSG_LVL_MED|MSG_MASK_5|MSG_MASK_6|MSG_MASK_7|
+ MSG_MASK_8|MSG_MASK_9|MSG_MASK_10,
MSG_LVL_MED,
MSG_LVL_MED,
MSG_LVL_MED
@@ -439,6 +445,7 @@
MSG_LVL_MED,
MSG_LVL_MED,
MSG_LVL_MED,
+ MSG_LVL_MED,
MSG_LVL_MED
};
@@ -632,6 +639,7 @@
MSG_LVL_LOW,
MSG_LVL_LOW,
MSG_LVL_LOW,
+ MSG_LVL_LOW,
};
static const uint32_t msg_bld_masks_17[] = {
@@ -722,13 +730,16 @@
MSG_LVL_LOW,
MSG_LVL_LOW,
MSG_LVL_LOW,
+ MSG_LVL_LOW,
+ MSG_LVL_LOW,
+ MSG_LVL_LOW,
MSG_LVL_LOW
};
/* LOG CODES */
static const uint32_t log_code_last_tbl[] = {
0x0, /* EQUIP ID 0 */
- 0x182F, /* EQUIP ID 1 */
+ 0x184A, /* EQUIP ID 1 */
0x0, /* EQUIP ID 2 */
0x0, /* EQUIP ID 3 */
0x4910, /* EQUIP ID 4 */
diff --git a/include/linux/hbtp_input.h b/include/linux/hbtp_input.h
new file mode 100644
index 0000000..2c3798e
--- /dev/null
+++ b/include/linux/hbtp_input.h
@@ -0,0 +1,46 @@
+#ifndef _HBTP_INPUT_H
+#define _HBTP_INPUT_H
+
+#include <linux/input.h>
+
+#define HBTP_MAX_FINGER 10
+
+struct hbtp_input_touch {
+ bool active;
+ __s32 tool;
+ __s32 x;
+ __s32 y;
+ __s32 pressure;
+ __s32 major;
+ __s32 minor;
+ __s32 orientation;
+};
+
+struct hbtp_input_mt {
+ __s32 num_touches;
+ struct hbtp_input_touch touches[HBTP_MAX_FINGER];
+};
+
+struct hbtp_input_absinfo {
+ bool active;
+ __u16 code;
+ __s32 minimum;
+ __s32 maximum;
+};
+
+enum hbtp_afe_power_cmd {
+ HBTP_AFE_POWER_ON,
+ HBTP_AFE_POWER_OFF,
+};
+
+/* ioctl */
+#define HBTP_INPUT_IOCTL_BASE 'T'
+#define HBTP_SET_ABSPARAM _IOW(HBTP_INPUT_IOCTL_BASE, 201, \
+ struct hbtp_input_absinfo *)
+#define HBTP_SET_TOUCHDATA _IOW(HBTP_INPUT_IOCTL_BASE, 202, \
+ struct hbtp_input_mt)
+#define HBTP_SET_POWERSTATE _IOW(HBTP_INPUT_IOCTL_BASE, 203, \
+ enum hbtp_afe_power_cmd)
+
+#endif /* _HBTP_INPUT_H */
+
diff --git a/arch/arm/boot/dts/msm8926-qrd-skug.dts b/include/linux/i2c/i2c-qup.h
similarity index 62%
copy from arch/arm/boot/dts/msm8926-qrd-skug.dts
copy to include/linux/i2c/i2c-qup.h
index 4aab4f9..a950864 100644
--- a/arch/arm/boot/dts/msm8926-qrd-skug.dts
+++ b/include/linux/i2c/i2c-qup.h
@@ -1,4 +1,5 @@
-/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+/*
+ * Copyright (c) 2014, 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
@@ -10,12 +11,13 @@
* GNU General Public License for more details.
*/
-/dts-v1/;
-/include/ "msm8926-qrd-skug.dtsi"
+#ifndef __I2C_QUP_H__
+#define __I2C_QUP_H__
-/ {
- model = "Qualcomm MSM 8926 QRD SKUG";
- compatible = "qcom,msm8926-qrd", "qcom,msm8926", "qcom,qrd";
- qcom,board-id = <11 5>;
-};
+#ifdef CONFIG_I2C_QUP
+int __init qup_i2c_init_driver(void);
+#else
+static inline int __init qup_i2c_init_driver(void) { return 0; }
+#endif
+#endif /* __I2C_QUP_H__ */
diff --git a/include/linux/msm_kgsl.h b/include/linux/msm_kgsl.h
index f74fcbe..17986b5 100644
--- a/include/linux/msm_kgsl.h
+++ b/include/linux/msm_kgsl.h
@@ -24,6 +24,7 @@
#define KGSL_CONTEXT_NO_FAULT_TOLERANCE 0x00000200
#define KGSL_CONTEXT_SYNC 0x00000400
+#define KGSL_CONTEXT_PWR_CONSTRAINT 0x00000800
/* bits [12:15] are reserved for future use */
#define KGSL_CONTEXT_TYPE_MASK 0x01F00000
#define KGSL_CONTEXT_TYPE_SHIFT 20
@@ -197,6 +198,7 @@
KGSL_PROP_VERSION = 0x00000008,
KGSL_PROP_GPU_RESET_STAT = 0x00000009,
KGSL_PROP_PWRCTRL = 0x0000000E,
+ KGSL_PROP_PWR_CONSTRAINT = 0x00000012,
};
struct kgsl_shadowprop {
@@ -882,6 +884,34 @@
#define IOCTL_KGSL_SUBMIT_COMMANDS \
_IOWR(KGSL_IOC_TYPE, 0x3D, struct kgsl_submit_commands)
+/**
+ * struct kgsl_device_constraint - device constraint argument
+ * @context_id: KGSL context ID
+ * @type: type of constraint i.e pwrlevel/none
+ * @data: constraint data
+ * @size: size of the constraint data
+ */
+struct kgsl_device_constraint {
+ unsigned int type;
+ unsigned int context_id;
+ void __user *data;
+ size_t size;
+};
+
+/* Constraint Type*/
+#define KGSL_CONSTRAINT_NONE 0
+#define KGSL_CONSTRAINT_PWRLEVEL 1
+
+/* PWRLEVEL constraint level*/
+/* set to min frequency */
+#define KGSL_CONSTRAINT_PWR_MIN 0
+/* set to max frequency */
+#define KGSL_CONSTRAINT_PWR_MAX 1
+
+struct kgsl_device_constraint_pwrlevel {
+ unsigned int level;
+};
+
#ifdef __KERNEL__
#ifdef CONFIG_MSM_KGSL_DRM
int kgsl_gem_obj_addr(int drm_fd, int handle, unsigned long *start,
diff --git a/include/linux/msm_vidc_enc.h b/include/linux/msm_vidc_enc.h
index dcc2353..4ce3db1 100644
--- a/include/linux/msm_vidc_enc.h
+++ b/include/linux/msm_vidc_enc.h
@@ -59,6 +59,7 @@
#define VEN_EXTRADATA_QCOMFILLER 0x002
#define VEN_EXTRADATA_SLICEINFO 0x100
#define VEN_EXTRADATA_LTRINFO 0x200
+#define VEN_EXTRADATA_MBINFO 0x400
/*ENCODER CONFIGURATION CONSTANTS*/
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index 51ca67d..81d5b9c 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -1841,7 +1841,11 @@
V4L2_MPEG_VIDC_INDEX_EXTRADATA_INPUT_CROP,
V4L2_MPEG_VIDC_INDEX_EXTRADATA_DIGITAL_ZOOM,
V4L2_MPEG_VIDC_INDEX_EXTRADATA_ASPECT_RATIO,
- V4L2_MPEG_VIDC_EXTRADATA_MPEG2_SEQDISP
+ V4L2_MPEG_VIDC_EXTRADATA_MPEG2_SEQDISP,
+ V4L2_MPEG_VIDC_EXTRADATA_FRAME_QP,
+ V4L2_MPEG_VIDC_EXTRADATA_FRAME_BITS_INFO,
+ V4L2_MPEG_VIDC_EXTRADATA_LTR,
+ V4L2_MPEG_VIDC_EXTRADATA_METADATA_MBI,
};
#define V4L2_CID_MPEG_VIDC_SET_PERF_LEVEL (V4L2_CID_MPEG_MSM_VIDC_BASE + 26)
@@ -1909,6 +1913,27 @@
#define V4L2_CID_MPEG_VIDC_VIDEO_CONCEAL_COLOR \
(V4L2_CID_MPEG_MSM_VIDC_BASE + 38)
+#define V4L2_CID_MPEG_VIDC_VIDEO_LTRMODE \
+ (V4L2_CID_MPEG_MSM_VIDC_BASE + 39)
+
+enum v4l2_mpeg_vidc_video_ltrmode {
+ V4L2_MPEG_VIDC_VIDEO_LTR_MODE_DISABLE = 0,
+ V4L2_MPEG_VIDC_VIDEO_LTR_MODE_MANUAL = 1,
+ V4L2_MPEG_VIDC_VIDEO_LTR_MODE_PERIODIC = 2
+};
+
+#define V4L2_CID_MPEG_VIDC_VIDEO_LTRCOUNT \
+ (V4L2_CID_MPEG_MSM_VIDC_BASE + 40)
+
+#define V4L2_CID_MPEG_VIDC_VIDEO_USELTRFRAME \
+ (V4L2_CID_MPEG_MSM_VIDC_BASE + 41)
+
+#define V4L2_CID_MPEG_VIDC_VIDEO_MARKLTRFRAME \
+ (V4L2_CID_MPEG_MSM_VIDC_BASE + 42)
+
+#define V4L2_CID_MPEG_VIDC_VIDEO_HIER_P_NUM_LAYERS \
+ (V4L2_CID_MPEG_MSM_VIDC_BASE + 43)
+
/* Camera class control IDs */
#define V4L2_CID_CAMERA_CLASS_BASE (V4L2_CTRL_CLASS_CAMERA | 0x900)
#define V4L2_CID_CAMERA_CLASS (V4L2_CTRL_CLASS_CAMERA | 1)
diff --git a/include/media/msm_vidc.h b/include/media/msm_vidc.h
index 81db11a..9028b1a 100644
--- a/include/media/msm_vidc.h
+++ b/include/media/msm_vidc.h
@@ -60,6 +60,7 @@
int msm_vidc_s_fmt(void *instance, struct v4l2_format *f);
int msm_vidc_g_fmt(void *instance, struct v4l2_format *f);
int msm_vidc_s_ctrl(void *instance, struct v4l2_control *a);
+int msm_vidc_s_ext_ctrl(void *instance, struct v4l2_ext_controls *a);
int msm_vidc_g_ctrl(void *instance, struct v4l2_control *a);
int msm_vidc_reqbufs(void *instance, struct v4l2_requestbuffers *b);
int msm_vidc_prepare_buf(void *instance, struct v4l2_buffer *b);
@@ -95,6 +96,16 @@
int *domain_num, int *partition_num);
void *msm_vidc_smem_get_client(void *instance);
#endif
+
+struct msm_vidc_extradata_header {
+ unsigned int size;
+ unsigned int:32; /** Keeping binary compatibility */
+ unsigned int:32; /* with firmware and OpenMAX IL **/
+ unsigned int type; /* msm_vidc_extradata_type */
+ unsigned int data_size;
+ unsigned char data[1];
+};
+
struct msm_vidc_interlace_payload {
unsigned int format;
};
@@ -160,6 +171,13 @@
unsigned int fpa_repetition_period;
unsigned int fpa_extension_flag;
};
+struct msm_vidc_frame_qp_payload {
+ unsigned int frame_qp;
+};
+struct msm_vidc_frame_bits_info_payload {
+ unsigned int frame_bits;
+ unsigned int header_bits;
+};
enum msm_vidc_extradata_type {
EXTRADATA_NONE = 0x00000000,
@@ -173,11 +191,15 @@
EXTRADATA_PANSCAN_WINDOW = 0x00000008,
EXTRADATA_RECOVERY_POINT_SEI = 0x00000009,
EXTRADATA_MPEG2_SEQDISP = 0x0000000D,
+ EXTRADATA_FRAME_QP = 0x0000000F,
+ EXTRADATA_FRAME_BITS_INFO = 0x00000010,
EXTRADATA_MULTISLICE_INFO = 0x7F100000,
EXTRADATA_NUM_CONCEALED_MB = 0x7F100001,
EXTRADATA_INDEX = 0x7F100002,
EXTRADATA_ASPECT_RATIO = 0x7F100003,
EXTRADATA_METADATA_FILLER = 0x7FE00002,
+ MSM_VIDC_EXTRADATA_METADATA_LTR = 0x7F100004,
+ EXTRADATA_METADATA_MBI = 0x7F100005,
};
enum msm_vidc_interlace_type {
INTERLACE_FRAME_PROGRESSIVE = 0x01,
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 954a8c4..d9e1f1d 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -1682,9 +1682,12 @@
{
struct rq *rq = task_rq(p);
- if (WARN_ON(rq != this_rq()) ||
- WARN_ON(p == current))
+ if (rq != this_rq() || p == current) {
+ printk_sched("%s: Failed to wakeup task %d (%s), rq = %p, this_rq = %p, p = %p, current = %p\n",
+ __func__, task_pid_nr(p), p->comm, rq,
+ this_rq(), p, current);
return;
+ }
lockdep_assert_held(&rq->lock);
@@ -6947,6 +6950,7 @@
#ifdef CONFIG_CGROUP_SCHED
struct task_group root_task_group;
+LIST_HEAD(task_groups);
#endif
DECLARE_PER_CPU(cpumask_var_t, load_balance_tmpmask);
diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
index c0288a6..34fe64f 100644
--- a/kernel/sched/sched.h
+++ b/kernel/sched/sched.h
@@ -80,7 +80,7 @@
struct cfs_rq;
struct rt_rq;
-static LIST_HEAD(task_groups);
+extern struct list_head task_groups;
struct cfs_bandwidth {
#ifdef CONFIG_CFS_BANDWIDTH
diff --git a/mm/page-writeback.c b/mm/page-writeback.c
index a5e8dc2..d012c75 100644
--- a/mm/page-writeback.c
+++ b/mm/page-writeback.c
@@ -190,6 +190,18 @@
zone_reclaimable_pages(z) - z->dirty_balance_reserve;
}
/*
+ * Unreclaimable memory (kernel memory or anonymous memory
+ * without swap) can bring down the dirtyable pages below
+ * the zone's dirty balance reserve and the above calculation
+ * will underflow. However we still want to add in nodes
+ * which are below threshold (negative values) to get a more
+ * accurate calculation but make sure that the total never
+ * underflows.
+ */
+ if ((long)x < 0)
+ x = 0;
+
+ /*
* Make sure that the number of highmem pages is never larger
* than the number of the total dirtyable memory. This can only
* occur in very strange VM situations but we want to make sure
@@ -211,8 +223,8 @@
{
unsigned long x;
- x = global_page_state(NR_FREE_PAGES) + global_reclaimable_pages() -
- dirty_balance_reserve;
+ x = global_page_state(NR_FREE_PAGES) + global_reclaimable_pages();
+ x -= min(x, dirty_balance_reserve);
if (!vm_highmem_is_dirtyable)
x -= highmem_dirtyable_memory(x);
@@ -279,9 +291,12 @@
* highmem zone can hold its share of dirty pages, so we don't
* care about vm_highmem_is_dirtyable here.
*/
- return zone_page_state(zone, NR_FREE_PAGES) +
- zone_reclaimable_pages(zone) -
- zone->dirty_balance_reserve;
+ unsigned long nr_pages = zone_page_state(zone, NR_FREE_PAGES) +
+ zone_reclaimable_pages(zone);
+
+ /* don't allow this to underflow */
+ nr_pages -= min(nr_pages, zone->dirty_balance_reserve);
+ return nr_pages;
}
/**
diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c
index a225089..f378b38 100644
--- a/net/core/flow_dissector.c
+++ b/net/core/flow_dissector.c
@@ -35,7 +35,7 @@
struct iphdr _iph;
ip:
iph = skb_header_pointer(skb, nhoff, sizeof(_iph), &_iph);
- if (!iph)
+ if (!iph || iph->ihl < 5)
return false;
if (ip_is_fragment(iph))
diff --git a/sound/soc/codecs/wcd9xxx-mbhc.c b/sound/soc/codecs/wcd9xxx-mbhc.c
index 32ca0c6..f37b86c 100644
--- a/sound/soc/codecs/wcd9xxx-mbhc.c
+++ b/sound/soc/codecs/wcd9xxx-mbhc.c
@@ -2906,16 +2906,15 @@
if (wcd9xxx_cancel_btn_work(mbhc))
pr_debug("%s: button press is canceled\n", __func__);
- /* cancel detect plug */
- wcd9xxx_cancel_hs_detect_plug(mbhc,
- &mbhc->correct_plug_swch);
-
insert = !wcd9xxx_swch_level_remove(mbhc);
pr_debug("%s: Current plug type %d, insert %d\n", __func__,
mbhc->current_plug, insert);
if ((mbhc->current_plug == PLUG_TYPE_NONE) && insert) {
mbhc->lpi_enabled = false;
wmb();
+ /* cancel detect plug */
+ wcd9xxx_cancel_hs_detect_plug(mbhc,
+ &mbhc->correct_plug_swch);
if ((mbhc->current_plug != PLUG_TYPE_NONE) &&
!(snd_soc_read(codec, WCD9XXX_A_MBHC_INSERT_DETECT) &
@@ -2930,6 +2929,9 @@
} else if ((mbhc->current_plug != PLUG_TYPE_NONE) && !insert) {
mbhc->lpi_enabled = false;
wmb();
+ /* cancel detect plug */
+ wcd9xxx_cancel_hs_detect_plug(mbhc,
+ &mbhc->correct_plug_swch);
if (mbhc->current_plug == PLUG_TYPE_HEADPHONE) {
wcd9xxx_report_plug(mbhc, 0, SND_JACK_HEADPHONE);
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
index 91c0744..2c001fa 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
@@ -2784,6 +2784,7 @@
int msm_routing_get_rms_value_control(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol) {
int rc = 0;
+ int be_idx = 0;
char *param_value;
int *update_param_value;
uint32_t param_length = sizeof(uint32_t);
@@ -2793,21 +2794,26 @@
pr_err("%s, param memory alloc failed\n", __func__);
return -ENOMEM;
}
- rc = adm_get_params(SLIMBUS_0_TX,
- RMS_MODULEID_APPI_PASSTHRU,
- RMS_PARAM_FIRST_SAMPLE,
- param_length + param_payload_len,
- param_value);
- if (rc) {
- pr_err("%s: get parameters failed\n", __func__);
- kfree(param_value);
- return -EINVAL;
- }
- update_param_value = (int *)param_value;
- ucontrol->value.integer.value[0] = update_param_value[0];
+ for (be_idx = 0; be_idx < MSM_BACKEND_DAI_MAX; be_idx++)
+ if (msm_bedais[be_idx].port_id == SLIMBUS_0_TX)
+ break;
+ if ((be_idx < MSM_BACKEND_DAI_MAX) && msm_bedais[be_idx].active) {
+ rc = adm_get_params(SLIMBUS_0_TX,
+ RMS_MODULEID_APPI_PASSTHRU,
+ RMS_PARAM_FIRST_SAMPLE,
+ param_length + param_payload_len,
+ param_value);
+ if (rc) {
+ pr_err("%s: get parameters failed\n", __func__);
+ kfree(param_value);
+ return -EINVAL;
+ }
+ update_param_value = (int *)param_value;
+ ucontrol->value.integer.value[0] = update_param_value[0];
- pr_debug("%s: FROM DSP value[0] 0x%x\n",
- __func__, update_param_value[0]);
+ pr_debug("%s: FROM DSP value[0] 0x%x\n",
+ __func__, update_param_value[0]);
+ }
kfree(param_value);
return 0;
}
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-voip-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-voip-v2.c
index 97c7b5d..e3c8944 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-voip-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-voip-v2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2014, 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
@@ -86,6 +86,10 @@
struct voip_frame_hdr {
uint32_t timestamp;
union {
+ /*
+ * Bits 0-15: Frame type
+ * Bits 16-31: Frame rate
+ */
uint32_t frame_type;
uint32_t packet_rate;
};
@@ -162,8 +166,6 @@
struct snd_ctl_elem_value *ucontrol);
static int msm_voip_rate_config_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol);
-static int msm_voip_rate_config_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol);
static int msm_voip_evrc_min_max_rate_config_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol);
static int msm_voip_evrc_min_max_rate_config_get(struct snd_kcontrol *kcontrol,
@@ -277,7 +279,7 @@
SOC_SINGLE_EXT("Voip Mode Config", SND_SOC_NOPM, 0, VOIP_MODE_MAX, 0,
msm_voip_mode_config_get, msm_voip_mode_config_put),
SOC_SINGLE_EXT("Voip Rate Config", SND_SOC_NOPM, 0, VOIP_RATE_MAX, 0,
- msm_voip_rate_config_get, msm_voip_rate_config_put),
+ NULL, msm_voip_rate_config_put),
SOC_SINGLE_MULTI_EXT("Voip Evrc Min Max Rate Config", SND_SOC_NOPM,
0, VOC_1_RATE, 0, 2, msm_voip_evrc_min_max_rate_config_get,
msm_voip_evrc_min_max_rate_config_put),
@@ -385,6 +387,8 @@
struct voip_buf_node *buf_node = NULL;
struct voip_drv_info *prtd = private_data;
unsigned long dsp_flags;
+ uint32_t rate_type;
+ uint32_t frame_rate;
if (prtd->playback_substream == NULL)
return;
@@ -408,7 +412,19 @@
* Bits 4-7: Frame type
*/
*voc_pkt = ((buf_node->frame.frm_hdr.frame_type &
- 0x0F) << 4) | (prtd->rate_type & 0x0F);
+ 0x0F) << 4);
+ frame_rate = (buf_node->frame.frm_hdr.frame_type &
+ 0xFFFF0000) >> 16;
+ if (frame_rate) {
+ if (voip_get_rate_type(prtd->mode, frame_rate,
+ &rate_type)) {
+ pr_err("%s(): fail at getting rate_type \n",
+ __func__);
+ } else
+ prtd->rate_type = rate_type;
+ }
+ *voc_pkt |= prtd->rate_type & 0x0F;
+
voc_pkt = voc_pkt + DSP_FRAME_HDR_LEN;
memcpy(voc_pkt,
&buf_node->frame.voc_pkt[0],
@@ -1087,30 +1103,43 @@
return 0;
}
-static int msm_voip_rate_config_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- mutex_lock(&voip_info.lock);
-
- ucontrol->value.integer.value[0] = voip_info.rate;
-
- mutex_unlock(&voip_info.lock);
-
- return 0;
-}
-
static int msm_voip_rate_config_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
+ int ret = 0;
+ int rate = ucontrol->value.integer.value[0];
+
mutex_lock(&voip_info.lock);
- voip_info.rate = ucontrol->value.integer.value[0];
+ if (voip_info.rate != rate) {
+ voip_info.rate = rate;
+ pr_debug("%s: rate=%d\n", __func__, voip_info.rate);
- pr_debug("%s: rate=%d\n", __func__, voip_info.rate);
+ if (voip_info.state == VOIP_STARTED &&
+ (voip_info.mode == MODE_AMR ||
+ voip_info.mode == MODE_AMR_WB)) {
+ ret = voip_config_vocoder(
+ voip_info.capture_substream);
+ if (ret) {
+ pr_err("%s:Failed to configure vocoder, ret=%d\n",
+ __func__, ret);
+ goto done;
+ }
+
+ ret = voc_update_amr_vocoder_rate(
+ voc_get_session_id(VOIP_SESSION_NAME));
+ if (ret) {
+ pr_err("%s:Failed to update AMR rate, ret=%d\n",
+ __func__, ret);
+ }
+ }
+ }
+
+done:
mutex_unlock(&voip_info.lock);
- return 0;
+ return ret;
}
static int msm_voip_evrc_min_max_rate_config_get(struct snd_kcontrol *kcontrol,
diff --git a/sound/soc/msm/qdsp6v2/q6adm.c b/sound/soc/msm/qdsp6v2/q6adm.c
index 54b1263..3e30290 100644
--- a/sound/soc/msm/qdsp6v2/q6adm.c
+++ b/sound/soc/msm/qdsp6v2/q6adm.c
@@ -93,6 +93,11 @@
sz = sizeof(struct adm_cmd_set_pp_params_inband_v5) +
sizeof(struct srs_trumedia_params_GLOBAL);
adm_params = kzalloc(sz, GFP_KERNEL);
+ if (!adm_params) {
+ pr_err("%s, adm params memory alloc failed\n",
+ __func__);
+ return -ENOMEM;
+ }
adm_params->payload_size =
sizeof(struct srs_trumedia_params_GLOBAL) +
sizeof(struct adm_param_data_v5);
@@ -117,6 +122,11 @@
sz = sizeof(struct adm_cmd_set_pp_params_inband_v5) +
sizeof(struct srs_trumedia_params_WOWHD);
adm_params = kzalloc(sz, GFP_KERNEL);
+ if (!adm_params) {
+ pr_err("%s, adm params memory alloc failed\n",
+ __func__);
+ return -ENOMEM;
+ }
adm_params->payload_size =
sizeof(struct srs_trumedia_params_WOWHD) +
sizeof(struct adm_param_data_v5);
@@ -142,6 +152,11 @@
sz = sizeof(struct adm_cmd_set_pp_params_inband_v5) +
sizeof(struct srs_trumedia_params_CSHP);
adm_params = kzalloc(sz, GFP_KERNEL);
+ if (!adm_params) {
+ pr_err("%s, adm params memory alloc failed\n",
+ __func__);
+ return -ENOMEM;
+ }
adm_params->payload_size =
sizeof(struct srs_trumedia_params_CSHP) +
sizeof(struct adm_param_data_v5);
@@ -166,6 +181,11 @@
sz = sizeof(struct adm_cmd_set_pp_params_inband_v5) +
sizeof(struct srs_trumedia_params_HPF);
adm_params = kzalloc(sz, GFP_KERNEL);
+ if (!adm_params) {
+ pr_err("%s, adm params memory alloc failed\n",
+ __func__);
+ return -ENOMEM;
+ }
adm_params->payload_size =
sizeof(struct srs_trumedia_params_HPF) +
sizeof(struct adm_param_data_v5);
@@ -186,6 +206,11 @@
sz = sizeof(struct adm_cmd_set_pp_params_inband_v5) +
sizeof(struct srs_trumedia_params_PEQ);
adm_params = kzalloc(sz, GFP_KERNEL);
+ if (!adm_params) {
+ pr_err("%s, adm params memory alloc failed\n",
+ __func__);
+ return -ENOMEM;
+ }
adm_params->payload_size =
sizeof(struct srs_trumedia_params_PEQ) +
sizeof(struct adm_param_data_v5);
@@ -208,6 +233,11 @@
sz = sizeof(struct adm_cmd_set_pp_params_inband_v5) +
sizeof(struct srs_trumedia_params_HL);
adm_params = kzalloc(sz, GFP_KERNEL);
+ if (!adm_params) {
+ pr_err("%s, adm params memory alloc failed\n",
+ __func__);
+ return -ENOMEM;
+ }
adm_params->payload_size =
sizeof(struct srs_trumedia_params_HL) +
sizeof(struct adm_param_data_v5);
diff --git a/sound/soc/msm/qdsp6v2/q6voice.c b/sound/soc/msm/qdsp6v2/q6voice.c
index 0c7472f..06ee692 100644
--- a/sound/soc/msm/qdsp6v2/q6voice.c
+++ b/sound/soc/msm/qdsp6v2/q6voice.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2014, 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
@@ -943,6 +943,7 @@
if (is_voip_session(v->session_id) ||
is_qchat_session(v->session_id) ||
+ is_volte_session(v->session_id) ||
v->voc_state == VOC_ERROR) {
/* Destroy CVS. */
pr_debug("%s: CVS destroy session\n", __func__);
@@ -1493,6 +1494,77 @@
return ret;
}
+static int voice_config_cvs_vocoder_amr_rate(struct voice_data *v)
+{
+ int ret = 0;
+ void *apr_cvs;
+ u16 cvs_handle;
+ struct cvs_set_amr_enc_rate_cmd cvs_set_amr_rate;
+
+ if (v == NULL) {
+ pr_err("%s: v is NULL\n", __func__);
+
+ ret = -EINVAL;
+ goto done;
+ }
+ apr_cvs = common.apr_q6_cvs;
+
+ if (!apr_cvs) {
+ pr_err("%s: apr_cvs is NULL.\n", __func__);
+
+ ret = -EINVAL;
+ goto done;
+ }
+
+ cvs_handle = voice_get_cvs_handle(v);
+
+ pr_debug("%s: Setting AMR rate. Media Type: %d\n", __func__,
+ common.mvs_info.media_type);
+
+ cvs_set_amr_rate.hdr.hdr_field =
+ APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
+ APR_HDR_LEN(APR_HDR_SIZE),
+ APR_PKT_VER);
+ cvs_set_amr_rate.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
+ sizeof(cvs_set_amr_rate) - APR_HDR_SIZE);
+ cvs_set_amr_rate.hdr.src_port =
+ voice_get_idx_for_session(v->session_id);
+ cvs_set_amr_rate.hdr.dest_port = cvs_handle;
+ cvs_set_amr_rate.hdr.token = 0;
+
+ if (common.mvs_info.media_type == VSS_MEDIA_ID_AMR_NB_MODEM)
+ cvs_set_amr_rate.hdr.opcode =
+ VSS_ISTREAM_CMD_VOC_AMR_SET_ENC_RATE;
+ else if (common.mvs_info.media_type == VSS_MEDIA_ID_AMR_WB_MODEM)
+ cvs_set_amr_rate.hdr.opcode =
+ VSS_ISTREAM_CMD_VOC_AMRWB_SET_ENC_RATE;
+
+ cvs_set_amr_rate.amr_rate.mode = common.mvs_info.rate;
+
+ v->cvs_state = CMD_STATUS_FAIL;
+
+ ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_amr_rate);
+ if (ret < 0) {
+ pr_err("%s: Error %d sending SET_AMR_RATE\n",
+ __func__, ret);
+
+ goto done;
+ }
+ ret = wait_event_timeout(v->cvs_wait,
+ (v->cvs_state == CMD_STATUS_SUCCESS),
+ msecs_to_jiffies(TIMEOUT_MS));
+ if (!ret) {
+ pr_err("%s: wait_event timeout\n", __func__);
+
+ ret = -EINVAL;
+ goto done;
+ }
+
+ return 0;
+done:
+ return ret;
+}
+
static int voice_config_cvs_vocoder(struct voice_data *v)
{
int ret = 0;
@@ -1597,80 +1669,13 @@
break;
}
- case VSS_MEDIA_ID_AMR_NB_MODEM: {
- struct cvs_set_amr_enc_rate_cmd cvs_set_amr_rate;
-
- pr_debug("Setting AMR rate\n");
-
- cvs_set_amr_rate.hdr.hdr_field =
- APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
- APR_HDR_LEN(APR_HDR_SIZE),
- APR_PKT_VER);
- cvs_set_amr_rate.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
- sizeof(cvs_set_amr_rate) - APR_HDR_SIZE);
- cvs_set_amr_rate.hdr.src_port =
- voice_get_idx_for_session(v->session_id);
- cvs_set_amr_rate.hdr.dest_port = cvs_handle;
- cvs_set_amr_rate.hdr.token = 0;
- cvs_set_amr_rate.hdr.opcode =
- VSS_ISTREAM_CMD_VOC_AMR_SET_ENC_RATE;
- cvs_set_amr_rate.amr_rate.mode = common.mvs_info.rate;
-
- v->cvs_state = CMD_STATUS_FAIL;
-
- ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_amr_rate);
- if (ret < 0) {
- pr_err("%s: Error %d sending SET_AMR_RATE\n",
- __func__, ret);
- goto fail;
- }
- ret = wait_event_timeout(v->cvs_wait,
- (v->cvs_state == CMD_STATUS_SUCCESS),
- msecs_to_jiffies(TIMEOUT_MS));
- if (!ret) {
- pr_err("%s: wait_event timeout\n", __func__);
- goto fail;
- }
-
- ret = voice_set_dtx(v);
- if (ret < 0)
- goto fail;
-
- break;
- }
+ case VSS_MEDIA_ID_AMR_NB_MODEM:
case VSS_MEDIA_ID_AMR_WB_MODEM: {
- struct cvs_set_amrwb_enc_rate_cmd cvs_set_amrwb_rate;
-
- pr_debug("Setting AMR WB rate\n");
-
- cvs_set_amrwb_rate.hdr.hdr_field =
- APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
- APR_HDR_LEN(APR_HDR_SIZE),
- APR_PKT_VER);
- cvs_set_amrwb_rate.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
- sizeof(cvs_set_amrwb_rate) -
- APR_HDR_SIZE);
- cvs_set_amrwb_rate.hdr.src_port =
- voice_get_idx_for_session(v->session_id);
- cvs_set_amrwb_rate.hdr.dest_port = cvs_handle;
- cvs_set_amrwb_rate.hdr.token = 0;
- cvs_set_amrwb_rate.hdr.opcode =
- VSS_ISTREAM_CMD_VOC_AMRWB_SET_ENC_RATE;
- cvs_set_amrwb_rate.amrwb_rate.mode = common.mvs_info.rate;
-
- v->cvs_state = CMD_STATUS_FAIL;
-
- ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_amrwb_rate);
- if (ret < 0) {
- pr_err("%s: Error %d sending SET_AMRWB_RATE\n",
+ ret = voice_config_cvs_vocoder_amr_rate(v);
+ if (ret) {
+ pr_err("%s: Failed to update vocoder rate. %d\n",
__func__, ret);
- goto fail;
- }
- ret = wait_event_timeout(v->cvs_wait,
- (v->cvs_state == CMD_STATUS_SUCCESS),
- msecs_to_jiffies(TIMEOUT_MS));
- if (!ret) {
- pr_err("%s: wait_event timeout\n", __func__);
+
goto fail;
}
@@ -1697,6 +1702,31 @@
return -EINVAL;
}
+int voc_update_amr_vocoder_rate(uint32_t session_id)
+{
+ int ret = 0;
+ struct voice_data *v;
+
+ pr_debug("%s: session_id:%d", __func__, session_id);
+
+ v = voice_get_session(session_id);
+
+ if (v == NULL) {
+ pr_err("%s: v is NULL, session_id:%d\n", __func__,
+ session_id);
+
+ ret = -EINVAL;
+ goto done;
+ }
+
+ mutex_lock(&v->lock);
+ ret = voice_config_cvs_vocoder_amr_rate(v);
+ mutex_unlock(&v->lock);
+
+done:
+ return ret;
+}
+
static int voice_send_start_voice_cmd(struct voice_data *v)
{
struct apr_hdr mvm_start_voice_cmd;
diff --git a/sound/soc/msm/qdsp6v2/q6voice.h b/sound/soc/msm/qdsp6v2/q6voice.h
index 5c0cf21..9efc9fc 100644
--- a/sound/soc/msm/qdsp6v2/q6voice.h
+++ b/sound/soc/msm/qdsp6v2/q6voice.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2014, 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
@@ -1465,5 +1465,6 @@
int voc_start_record(uint32_t port_id, uint32_t set, uint32_t session_id);
int voice_get_idx_for_session(u32 session_id);
int voc_set_ext_ec_ref(uint16_t port_id, bool state);
+int voc_update_amr_vocoder_rate(uint32_t session_id);
#endif