Merge "msm: ipa: Bug fix in RM add_dependency"
diff --git a/Documentation/devicetree/bindings/arm/msm/msm_bus.txt b/Documentation/devicetree/bindings/arm/msm/msm_bus.txt
index 6b2f962..fbf1a1f 100644
--- a/Documentation/devicetree/bindings/arm/msm/msm_bus.txt
+++ b/Documentation/devicetree/bindings/arm/msm/msm_bus.txt
@@ -91,6 +91,31 @@
(Can be 0/1/2).
qcom,prio1: Priority high signal for a NoC bus master
(Can be 0/1/2)
+qcom,dual-conf: Indicates whether a BIMC/NoC master can be configured
+ in multiple modes at run-time. (Boolean)
+qcom,mode-thresh: Threshold mode for a BIMC/NoC master. Beyond a certain
+ threshold frequency, a threshold mode can be used.
+ (Can be Fixed/Limiter/Bypass/Regulator)
+qcom,bimc,bw: Bandwidth limit for a BIMC master using dual modes.
+ This bandwidth is used to calculate Grant count and
+ other parameters used in Limiter and Regular mode
+ for static BKE configuration. It is defined in KBps.
+qcom,bimc,gp: Grant Period for configuring a master in limiter
+ mode. This is an integer value in micro-seconds.
+qcom,bimc,thmp: Medium threshold percentage for BIMC masters.
+ This percentage is used to calculate medium threshold
+ value for BIMC Masters in Limiter mode for static
+ configuration. This can be any integer value between
+ 1 and 100.
+qcom,thresh: Beyond this threshold frequency, the mode usage is
+ switched from mode specified by property qcom,mode
+ to the one specified by qcom,mode-thresh. In case the
+ requested IB value falls below this threshold, the mode
+ is switched back to qcom,mode. Frequency is specified in
+ KBps.
+
+
+
Example:
@@ -135,6 +160,45 @@
};
};
+ msm-bimc@0xfc380000 {
+ compatible = "msm-bus-fabric";
+ reg = <0xfc380000 0x0006A000>;
+ cell-id = <0>;
+ label = "msm_bimc";
+ qcom,fabclk-dual = "mem_clk";
+ qcom,fabclk-active = "mem_a_clk";
+ qcom,ntieredslaves = <0>;
+ qcom,qos-freq = <19200>;
+ qcom,hw-sel = "BIMC";
+ qcom,rpm-en;
+
+ coresight-id = <55>;
+ coresight-name = "coresight-bimc";
+ coresight-nr-inports = <0>;
+ coresight-outports = <0>;
+ coresight-child-list = <&funnel_in1>;
+ coresight-child-ports = <3>;
+
+ mas-ampss-m0 {
+ cell-id = <1>;
+ label = "mas-ampss-m0";
+ qcom,masterp = <0>;
+ qcom,tier = <2>;
+ qcom,hw-sel = "BIMC";
+ qcom,mode = "Limiter";
+ qcom,qport = <0>;
+ qcom,ws = <10000>;
+ qcom,mas-hw-id = <0>;
+ qcom,prio-rd = <0>;
+ qcom,prio-wr = <0>;
+ qcom,mode-thresh = "Fixed";
+ qcom,thresh = <2000000>;
+ qcom,dual-conf;
+ qcom,bimc,bw = <300000>;
+ qcom,bimc,gp = <5>;
+ qcom,bimc,thmp = <50>;
+ };
+ };
diff --git a/Documentation/devicetree/bindings/leds/leds-qpnp.txt b/Documentation/devicetree/bindings/leds/leds-qpnp.txt
index ae1f648..5a668b2 100644
--- a/Documentation/devicetree/bindings/leds/leds-qpnp.txt
+++ b/Documentation/devicetree/bindings/leds/leds-qpnp.txt
@@ -46,6 +46,7 @@
- linux,default-trigger: trigger the led from external modules such as display
- qcom,default-state: default state of the led, should be "on" or "off"
- qcom,torch-enable: set flash led to torch mode
+- flash_boost-supply: SMBB regulator for LED flash mode
RGB Led is a tri-colored led, Red, Blue & Green.
@@ -198,6 +199,7 @@
qcom,leds@d300 {
compatible = "qcom,leds-qpnp";
status = "okay";
+ flash_boost-supply = <&pm8941_chg_boost>;
qcom,flash_0 {
qcom,max-current = <1000>;
qcom,default-state = "off";
diff --git a/Documentation/devicetree/bindings/pil/pil-q6v5-mss.txt b/Documentation/devicetree/bindings/pil/pil-q6v5-mss.txt
index ded8f77..d6980ac 100644
--- a/Documentation/devicetree/bindings/pil/pil-q6v5-mss.txt
+++ b/Documentation/devicetree/bindings/pil/pil-q6v5-mss.txt
@@ -20,6 +20,8 @@
- qcom,gpio-proxy-unvote: GPIO used by the modem to trigger proxy unvoting in
the apps.
- qcom,gpio-force-stop: GPIO used by the apps to force the modem to shutdown.
+- qcom,gpio-stop-ack: GPIO used by the modem to ack force stop or a graceful stop
+ to the apps.
Optional properties:
- vdd_mss-supply: Reference to the regulator that supplies the processor.
diff --git a/Makefile b/Makefile
index 75b36ae..be32c2f 100644
--- a/Makefile
+++ b/Makefile
@@ -563,7 +563,7 @@
all: vmlinux
ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE
-KBUILD_CFLAGS += -Os
+KBUILD_CFLAGS += -Os $(call cc-disable-warning,maybe-uninitialized,)
else
KBUILD_CFLAGS += -O2
endif
diff --git a/arch/arm/boot/dts/mpq8092.dtsi b/arch/arm/boot/dts/mpq8092.dtsi
index 946b54d..cc19cce 100644
--- a/arch/arm/boot/dts/mpq8092.dtsi
+++ b/arch/arm/boot/dts/mpq8092.dtsi
@@ -69,6 +69,11 @@
status = "disabled";
};
+ qcom,msm-imem@fe805000 {
+ compatible = "qcom,msm-imem";
+ reg = <0xfe805000 0x1000>; /* Address and size of IMEM */
+ };
+
spmi_bus: qcom,spmi@fc4c0000 {
cell-index = <0>;
compatible = "qcom,spmi-pmic-arb";
diff --git a/arch/arm/boot/dts/msm-pm8941.dtsi b/arch/arm/boot/dts/msm-pm8941.dtsi
index 85a5608..c78a144 100644
--- a/arch/arm/boot/dts/msm-pm8941.dtsi
+++ b/arch/arm/boot/dts/msm-pm8941.dtsi
@@ -1230,6 +1230,7 @@
compatible = "qcom,leds-qpnp";
reg = <0xd300 0x100>;
label = "flash";
+ flash_boost-supply = <&pm8941_chg_boost>;
};
qcom,leds@d400 {
diff --git a/arch/arm/boot/dts/msm8226-cdp.dtsi b/arch/arm/boot/dts/msm8226-cdp.dtsi
index c1ab954..5c5b8b0 100644
--- a/arch/arm/boot/dts/msm8226-cdp.dtsi
+++ b/arch/arm/boot/dts/msm8226-cdp.dtsi
@@ -300,7 +300,7 @@
qcom,cs-out-en;
qcom,op-fdbck = <1>;
qcom,default-state = "on";
- qcom,max-current = <25>;
+ qcom,max-current = <20>;
qcom,ctrl-delay-us = <0>;
qcom,boost-curr-lim = <3>;
qcom,cp-sel = <0>;
diff --git a/arch/arm/boot/dts/msm8226-mtp.dtsi b/arch/arm/boot/dts/msm8226-mtp.dtsi
index a9ae3b0..baa3539 100644
--- a/arch/arm/boot/dts/msm8226-mtp.dtsi
+++ b/arch/arm/boot/dts/msm8226-mtp.dtsi
@@ -292,7 +292,7 @@
qcom,cs-out-en;
qcom,op-fdbck = <1>;
qcom,default-state = "on";
- qcom,max-current = <25>;
+ qcom,max-current = <20>;
qcom,ctrl-delay-us = <0>;
qcom,boost-curr-lim = <3>;
qcom,cp-sel = <0>;
diff --git a/arch/arm/boot/dts/msm8226-qrd.dtsi b/arch/arm/boot/dts/msm8226-qrd.dtsi
index 1698ac1..2a294e7 100644
--- a/arch/arm/boot/dts/msm8226-qrd.dtsi
+++ b/arch/arm/boot/dts/msm8226-qrd.dtsi
@@ -296,7 +296,7 @@
qcom,cs-out-en;
qcom,op-fdbck = <1>;
qcom,default-state = "on";
- qcom,max-current = <25>;
+ qcom,max-current = <20>;
qcom,ctrl-delay-us = <0>;
qcom,boost-curr-lim = <3>;
qcom,cp-sel = <0>;
diff --git a/arch/arm/boot/dts/msm8226-regulator.dtsi b/arch/arm/boot/dts/msm8226-regulator.dtsi
index 5eb4684..3254d17 100644
--- a/arch/arm/boot/dts/msm8226-regulator.dtsi
+++ b/arch/arm/boot/dts/msm8226-regulator.dtsi
@@ -224,8 +224,27 @@
regulator-max-microvolt = <1800000>;
qcom,init-voltage = <1800000>;
status = "okay";
+ };
+
+ pm8226_l8_ao: regulator-l8-ao {
+ compatible = "qcom,rpm-regulator-smd";
+ regulator-name = "8226_l8_ao";
+ qcom,set = <1>;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ qcom,init-voltage = <1800000>;
qcom,consumer-supplies = "vdd_sr2_pll", "";
};
+
+ pm8226_l8_so: regulator-l8-so {
+ compatible = "qcom,rpm-regulator-smd";
+ regulator-name = "8226_l8_so";
+ qcom,set = <2>;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ qcom,init-voltage = <1800000>;
+ qcom,init-enable = <0>;
+ };
};
rpm-regulator-ldoa9 {
diff --git a/arch/arm/boot/dts/msm8226.dtsi b/arch/arm/boot/dts/msm8226.dtsi
index 26e834f..3c1f45b6 100644
--- a/arch/arm/boot/dts/msm8226.dtsi
+++ b/arch/arm/boot/dts/msm8226.dtsi
@@ -847,6 +847,7 @@
qcom,gpio-err-fatal = <&smp2pgpio_ssr_smp2p_1_in 0 0>;
qcom,gpio-err-ready = <&smp2pgpio_ssr_smp2p_1_in 1 0>;
qcom,gpio-proxy-unvote = <&smp2pgpio_ssr_smp2p_1_in 2 0>;
+ qcom,gpio-stop-ack = <&smp2pgpio_ssr_smp2p_1_in 3 0>;
/* GPIO output to mss */
qcom,gpio-force-stop = <&smp2pgpio_ssr_smp2p_1_out 0 0>;
diff --git a/arch/arm/boot/dts/msm8610-bus.dtsi b/arch/arm/boot/dts/msm8610-bus.dtsi
index 7ed914e..d9bb6ab 100644
--- a/arch/arm/boot/dts/msm8610-bus.dtsi
+++ b/arch/arm/boot/dts/msm8610-bus.dtsi
@@ -23,6 +23,13 @@
qcom,hw-sel = "NoC";
qcom,rpm-en;
+ coresight-id = <52>;
+ coresight-name = "coresight-mnoc";
+ coresight-nr-inports = <0>;
+ coresight-outports = <0>;
+ coresight-child-list = <&funnel_in0>;
+ coresight-child-ports = <5>;
+
mas-mdp-port0 {
cell-id = <22>;
label = "mas-mdp-port0";
@@ -221,6 +228,13 @@
qcom,hw-sel = "NoC";
qcom,rpm-en;
+ coresight-id = <50>;
+ coresight-name = "coresight-snoc";
+ coresight-nr-inports = <0>;
+ coresight-outports = <0>;
+ coresight-child-list = <&funnel_in0>;
+ coresight-child-ports = <3>;
+
mas-lpass-ahb {
cell-id = <52>;
label = "mas-lpass-ahb";
@@ -422,6 +436,13 @@
qcom,hw-sel = "NoC";
qcom,rpm-en;
+ coresight-id = <54>;
+ coresight-name = "coresight-pnoc";
+ coresight-nr-inports = <0>;
+ coresight-outports = <0>;
+ coresight-child-list = <&funnel_in0>;
+ coresight-child-ports = <6>;
+
mas-pnoc-cfg {
cell-id = <88>;
label = "mas-pnoc-cfg";
@@ -896,6 +917,13 @@
qcom,hw-sel = "BIMC";
qcom,rpm-en;
+ coresight-id = <55>;
+ coresight-name = "coresight-bimc";
+ coresight-nr-inports = <0>;
+ coresight-outports = <0>;
+ coresight-child-list = <&funnel_in1>;
+ coresight-child-ports = <3>;
+
mas-ampss-m0 {
cell-id = <1>;
label = "mas-ampss-m0";
diff --git a/arch/arm/boot/dts/msm8610-qrd.dts b/arch/arm/boot/dts/msm8610-qrd.dts
new file mode 100644
index 0000000..4bab7e4
--- /dev/null
+++ b/arch/arm/boot/dts/msm8610-qrd.dts
@@ -0,0 +1,228 @@
+/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+
+/include/ "msm8610.dtsi"
+
+/ {
+ model = "Qualcomm MSM 8610 QRD";
+ compatible = "qcom,msm8610-qrd", "qcom,msm8610", "qcom,qrd";
+ qcom,msm-id = <147 11 0>, <165 11 0>, <161 11 0>, <162 11 0>,
+ <163 11 0>, <164 11 0>, <166 11 0>;
+};
+
+&soc {
+ serial@f991e000 {
+ status = "ok";
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+ input-name = "gpio-keys";
+
+ camera_snapshot {
+ label = "camera_snapshot";
+ gpios = <&msmgpio 73 0x1>;
+ linux,input-type = <1>;
+ linux,code = <0x2fe>;
+ gpio-key,wakeup;
+ debounce-interval = <15>;
+ };
+
+ camera_focus {
+ label = "camera_focus";
+ gpios = <&msmgpio 74 0x1>;
+ linux,input-type = <1>;
+ linux,code = <0x210>;
+ gpio-key,wakeup;
+ debounce-interval = <15>;
+ };
+
+ vol_up {
+ label = "volume_up";
+ gpios = <&msmgpio 72 0x1>;
+ linux,input-type = <1>;
+ linux,code = <115>;
+ gpio-key,wakeup;
+ debounce-interval = <15>;
+ };
+ };
+
+ i2c@f9927000 {
+ msm8x10_wcd_codec@0d{
+ compatible = "qcom,msm8x10-wcd-i2c";
+ reg = <0x0d>;
+ cdc-vdda-cp-supply = <&pm8110_s4>;
+ qcom,cdc-vdda-cp-voltage = <2150000 2150000>;
+ qcom,cdc-vdda-cp-current = <650000>;
+
+ cdc-vdda-h-supply = <&pm8110_l6>;
+ qcom,cdc-vdda-h-voltage = <1800000 1800000>;
+ qcom,cdc-vdda-h-current = <250000>;
+
+ cdc-vdd-px-supply = <&pm8110_l6>;
+ qcom,cdc-vdd-px-voltage = <1800000 1800000>;
+ qcom,cdc-vdd-px-current = <10000>;
+
+ cdc-vdd-1p2v-supply = <&pm8110_l4>;
+ qcom,cdc-vdd-1p2v-voltage = <1200000 1200000>;
+ qcom,cdc-vdd-1p2v-current = <5000>;
+
+ cdc-vdd-mic-bias-supply = <&pm8110_l20>;
+ qcom,cdc-vdd-mic-bias-voltage = <3075000 3075000>;
+ qcom,cdc-vdd-mic-bias-current = <25000>;
+
+ qcom,cdc-micbias-cfilt-sel = <0x0>;
+ qcom,cdc-micbias-cfilt-mv = <1800000>;
+ qcom,cdc-mclk-clk-rate = <12288000>;
+ };
+
+ msm8x10_wcd_codec@77{
+ compatible = "qcom,msm8x10-wcd-i2c";
+ reg = <0x77>;
+ };
+
+ msm8x10_wcd_codec@66{
+ compatible = "qcom,msm8x10-wcd-i2c";
+ reg = <0x66>;
+ };
+
+ msm8x10_wcd_codec@55{
+ compatible = "qcom,msm8x10-wcd-i2c";
+ reg = <0x55>;
+ };
+ };
+};
+
+&spmi_bus {
+ qcom,pm8110@0 {
+ qcom,leds@a100 {
+ status = "okay";
+ qcom,led_mpp_2 {
+ label = "mpp";
+ linux,name = "wled-homerow";
+ linux-default-trigger = "hr-trigger";
+ qcom,default-state = "off";
+ qcom,max-current = <40>;
+ qcom,id = <6>;
+ qcom,source-sel = <1>;
+ qcom,mode-ctrl = <0x61>;
+ };
+ };
+
+ qcom,leds@a200 {
+ status = "okay";
+ qcom,led_mpp_3 {
+ label = "mpp";
+ linux,name = "wled-backlight";
+ linux,default-trigger = "bkl-trigger";
+ qcom,default-state = "on";
+ qcom,max-current = <40>;
+ qcom,id = <6>;
+ qcom,source-sel = <1>;
+ qcom,mode-ctrl = <0x10>;
+ };
+ };
+ };
+};
+
+&spmi_bus {
+ qcom,pm8110@1 {
+ qcom,vibrator@c000 {
+ status = "okay";
+ qcom,vib-timeout-ms = <15000>;
+ qcom,vib-vtg-level-mV = <3100>;
+ };
+ };
+};
+
+&sdhc_1 {
+ vdd-supply = <&pm8110_l17>;
+ qcom,vdd-always-on;
+ qcom,vdd-lpm-sup;
+ qcom,vdd-voltage-level = <2900000 2900000>;
+ qcom,vdd-current-level = <200 400000>;
+
+ vdd-io-supply = <&pm8110_l6>;
+ qcom,vdd-io-always-on;
+ qcom,vdd-io-voltage-level = <1800000 1800000>;
+ qcom,vdd-io-current-level = <200 60000>;
+
+ qcom,pad-pull-on = <0x0 0x3 0x3>; /* no-pull, pull-up, pull-up */
+ qcom,pad-pull-off = <0x0 0x3 0x3>; /* no-pull, pull-up, pull-up */
+ qcom,pad-drv-on = <0x4 0x4 0x4>; /* 10mA, 10mA, 10mA */
+ qcom,pad-drv-off = <0x0 0x0 0x0>; /* 2mA, 2mA, 2mA */
+
+ qcom,clk-rates = <400000 25000000 50000000 100000000 200000000>;
+ qcom,bus-speed-mode = "HS200_1p8v", "DDR_1p8v";
+ qcom,nonremovable;
+
+ status = "ok";
+};
+
+&sdhc_2 {
+ vdd-supply = <&pm8110_l18>;
+ qcom,vdd-voltage-level = <2950000 2950000>;
+ qcom,vdd-current-level = <15000 400000>;
+
+ vdd-io-supply = <&pm8110_l21>;
+ qcom,vdd-io-always-on;
+ qcom,vdd-io-lpm-sup;
+ qcom,vdd-io-voltage-level = <1800000 2950000>;
+ qcom,vdd-io-current-level = <200 50000>;
+
+ qcom,pad-pull-on = <0x0 0x3 0x3>; /* no-pull, pull-up, pull-up */
+ qcom,pad-pull-off = <0x0 0x3 0x3>; /* no-pull, pull-up, pull-up */
+ qcom,pad-drv-on = <0x4 0x4 0x4>; /* 10mA, 10mA, 10mA */
+ qcom,pad-drv-off = <0x0 0x0 0x0>; /* 2mA, 2mA, 2mA */
+
+ qcom,clk-rates = <400000 25000000 50000000 100000000 200000000>;
+
+ #address-cells = <0>;
+ interrupt-parent = <&sdhc_2>;
+ interrupts = <0 1 2>;
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0xffffffff>;
+ interrupt-map = <0 &intc 0 125 0
+ 1 &intc 0 221 0
+ 2 &msmgpio 42 0x3>;
+ interrupt-names = "hc_irq", "pwr_irq", "status_irq";
+ cd-gpios = <&msmgpio 42 0x1>;
+
+ status = "ok";
+};
+
+&pm8110_chg {
+ status = "ok";
+ qcom,charging-disabled;
+
+ qcom,chgr@1000 {
+ status = "ok";
+ };
+
+ qcom,buck@1100 {
+ status = "ok";
+ };
+
+ qcom,bat-if@1200 {
+ status = "ok";
+ };
+
+ qcom,usb-chgpth@1300 {
+ status = "ok";
+ };
+
+ qcom,chg-misc@1600 {
+ status = "ok";
+ };
+};
diff --git a/arch/arm/boot/dts/msm8610.dtsi b/arch/arm/boot/dts/msm8610.dtsi
index 5f71b0d..6b06be7 100644
--- a/arch/arm/boot/dts/msm8610.dtsi
+++ b/arch/arm/boot/dts/msm8610.dtsi
@@ -719,6 +719,7 @@
qcom,gpio-err-fatal = <&smp2pgpio_ssr_smp2p_1_in 0 0>;
qcom,gpio-err-ready = <&smp2pgpio_ssr_smp2p_1_in 1 0>;
qcom,gpio-proxy-unvote = <&smp2pgpio_ssr_smp2p_1_in 2 0>;
+ qcom,gpio-stop-ack = <&smp2pgpio_ssr_smp2p_1_in 3 0>;
/* GPIO output to mss */
qcom,gpio-force-stop = <&smp2pgpio_ssr_smp2p_1_out 0 0>;
diff --git a/arch/arm/boot/dts/msm8974-bus.dtsi b/arch/arm/boot/dts/msm8974-bus.dtsi
index bfe955e..609a1b3 100644
--- a/arch/arm/boot/dts/msm8974-bus.dtsi
+++ b/arch/arm/boot/dts/msm8974-bus.dtsi
@@ -1151,7 +1151,7 @@
qcom,fabclk-dual = "mem_clk";
qcom,fabclk-active = "mem_a_clk";
qcom,ntieredslaves = <0>;
- qcom,qos-freq = <4800>;
+ qcom,qos-freq = <19200>;
qcom,hw-sel = "BIMC";
qcom,rpm-en;
@@ -1168,12 +1168,18 @@
qcom,masterp = <0>;
qcom,tier = <2>;
qcom,hw-sel = "BIMC";
- qcom,mode = "Fixed";
+ qcom,mode = "Limiter";
qcom,qport = <0>;
qcom,ws = <10000>;
qcom,mas-hw-id = <0>;
qcom,prio-rd = <0>;
qcom,prio-wr = <0>;
+ qcom,mode-thresh = "Fixed";
+ qcom,thresh = <2000000>;
+ qcom,dual-conf;
+ qcom,bimc,bw = <300000>;
+ qcom,bimc,gp = <5>;
+ qcom,bimc,thmp = <50>;
};
mas-ampss-m1 {
@@ -1182,12 +1188,18 @@
qcom,masterp = <1>;
qcom,tier = <2>;
qcom,hw-sel = "BIMC";
- qcom,mode = "Fixed";
+ qcom,mode = "Limiter";
qcom,qport = <1>;
qcom,ws = <10000>;
qcom,mas-hw-id = <0>;
qcom,prio-rd = <0>;
qcom,prio-wr = <0>;
+ qcom,mode-thresh = "Fixed";
+ qcom,thresh = <2000000>;
+ qcom,dual-conf;
+ qcom,bimc,bw = <300000>;
+ qcom,bimc,gp = <5>;
+ qcom,bimc,thmp = <50>;
};
mas-mss-proc {
diff --git a/arch/arm/boot/dts/msm8974-liquid.dtsi b/arch/arm/boot/dts/msm8974-liquid.dtsi
index fa8c240..2dc52b6 100644
--- a/arch/arm/boot/dts/msm8974-liquid.dtsi
+++ b/arch/arm/boot/dts/msm8974-liquid.dtsi
@@ -208,7 +208,7 @@
/* Object 6, Instance = 0 */
00 00 00 00 00 00
/* Object 38, Instance = 0 */
- 19 01 00 0D 02 0D 00 00 00 00
+ 19 03 00 1E 05 0D 00 00 00 00
00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00
@@ -221,8 +221,8 @@
41 00 14 14 00 00 00 01 00 00
/* Object 9, Instance = 0 */
8F 00 00 20 34 00 87 4B 02 03
- 00 05 03 40 0A 14 14 0A 80 07
- 38 04 03 03 03 03 08 28 02 3C
+ 00 05 03 41 0A 14 14 0A 80 07
+ 38 04 00 00 03 03 08 28 02 3C
0F 0F 2E 33 01 00
/* Object 15, Instance = 0 */
00 00 00 00 00 00 00 00 00 00
diff --git a/arch/arm/boot/dts/msm8974-v2.dtsi b/arch/arm/boot/dts/msm8974-v2.dtsi
index 63a31dc..96e78ac 100644
--- a/arch/arm/boot/dts/msm8974-v2.dtsi
+++ b/arch/arm/boot/dts/msm8974-v2.dtsi
@@ -106,21 +106,21 @@
<3456000 2076000>,
<3662000 2198000>;
qcom,enc-ddr-ab-ib = <0 0>,
- <60000 302000>,
- <182000 302000>,
- <402000 302000>,
- <804000 604000>,
- <1288000 967000>,
- <2340000 1404000>,
- <24940000 1496000>;
+ <120000 302000>,
+ <364000 302000>,
+ <804000 302000>,
+ <1608000 604000>,
+ <2576000 967000>,
+ <4680000 1404000>,
+ <49880000 1496000>;
qcom,dec-ddr-ab-ib = <0 0>,
- <104000 303000>,
- <268000 303000>,
- <506000 303000>,
- <1012000 606000>,
- <1620000 970000>,
- <2024000 1212000>,
- <2132000 1279000>;
+ <208000 303000>,
+ <536000 303000>,
+ <1012000 303000>,
+ <2024000 606000>,
+ <3240000 970000>,
+ <4048000 1212000>,
+ <4264000 1279000>;
qcom,iommu-groups = <&venus_domain_ns &venus_domain_sec_bitstream
&venus_domain_sec_pixel &venus_domain_sec_non_pixel>;
qcom,iommu-group-buffer-types = <0xfff 0x91 0x42 0x120>;
diff --git a/arch/arm/boot/dts/msm8974.dtsi b/arch/arm/boot/dts/msm8974.dtsi
index a585586..9f3a5ce 100644
--- a/arch/arm/boot/dts/msm8974.dtsi
+++ b/arch/arm/boot/dts/msm8974.dtsi
@@ -1177,6 +1177,7 @@
qcom,gpio-err-fatal = <&smp2pgpio_ssr_smp2p_1_in 0 0>;
qcom,gpio-err-ready = <&smp2pgpio_ssr_smp2p_1_in 1 0>;
qcom,gpio-proxy-unvote = <&smp2pgpio_ssr_smp2p_1_in 2 0>;
+ qcom,gpio-stop-ack = <&smp2pgpio_ssr_smp2p_1_in 3 0>;
/* GPIO output to mss */
qcom,gpio-force-stop = <&smp2pgpio_ssr_smp2p_1_out 0 0>;
diff --git a/arch/arm/boot/dts/msm9625.dtsi b/arch/arm/boot/dts/msm9625.dtsi
index 947364c..f654545 100644
--- a/arch/arm/boot/dts/msm9625.dtsi
+++ b/arch/arm/boot/dts/msm9625.dtsi
@@ -165,6 +165,7 @@
qcom,hsusb-otg-lpm-on-dev-suspend;
qcom,hsusb-otg-clk-always-on-workaround;
qcom,hsusb-otg-delay-lpm-hndshk-on-disconnect;
+ qcom,hsusb-otg-delay-lpm;
qcom,msm-bus,name = "usb2";
qcom,msm-bus,num-cases = <2>;
@@ -771,6 +772,7 @@
qcom,gpio-err-fatal = <&smp2pgpio_ssr_smp2p_1_in 0 0>;
qcom,gpio-err-ready = <&smp2pgpio_ssr_smp2p_1_in 1 0>;
qcom,gpio-proxy-unvote = <&smp2pgpio_ssr_smp2p_1_in 2 0>;
+ qcom,gpio-stop-ack = <&smp2pgpio_ssr_smp2p_1_in 3 0>;
/* GPIO output to mss */
qcom,gpio-force-stop = <&smp2pgpio_ssr_smp2p_1_out 0 0>;
diff --git a/arch/arm/configs/mpq8092_defconfig b/arch/arm/configs/mpq8092_defconfig
index c06161d..179750e 100644
--- a/arch/arm/configs/mpq8092_defconfig
+++ b/arch/arm/configs/mpq8092_defconfig
@@ -50,6 +50,7 @@
CONFIG_MSM_SYSMON_COMM=y
CONFIG_MSM_DIRECT_SCLK_ACCESS=y
CONFIG_MSM_WATCHDOG_V2=y
+CONFIG_MSM_MEMORY_DUMP=y
CONFIG_MSM_DLOAD_MODE=y
CONFIG_MSM_RUN_QUEUE_STATS=y
CONFIG_MSM_SPM_V2=y
diff --git a/arch/arm/configs/msm7627a-perf_defconfig b/arch/arm/configs/msm7627a-perf_defconfig
index ba36df1..431ac58 100644
--- a/arch/arm/configs/msm7627a-perf_defconfig
+++ b/arch/arm/configs/msm7627a-perf_defconfig
@@ -278,7 +278,28 @@
CONFIG_MSM_CAMERA_SENSOR=y
CONFIG_MSM_ACTUATOR=y
CONFIG_OV7692=y
-# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
+# CONFIG_MEDIA_TUNER_SIMPLE is not set
+# CONFIG_MEDIA_TUNER_TDA8290 is not set
+# CONFIG_MEDIA_TUNER_TDA827X is not set
+# CONFIG_MEDIA_TUNER_TDA18271 is not set
+# CONFIG_MEDIA_TUNER_TDA9887 is not set
+# CONFIG_MEDIA_TUNER_TEA5761 is not set
+# CONFIG_MEDIA_TUNER_TEA5767 is not set
+# CONFIG_MEDIA_TUNER_MT20XX is not set
+# CONFIG_MEDIA_TUNER_MT2060 is not set
+# CONFIG_MEDIA_TUNER_MT2063 is not set
+# CONFIG_MEDIA_TUNER_MT2266 is not set
+# CONFIG_MEDIA_TUNER_MT2131 is not set
+# CONFIG_MEDIA_TUNER_QT1010 is not set
+# CONFIG_MEDIA_TUNER_XC2028 is not set
+# CONFIG_MEDIA_TUNER_XC5000 is not set
+# CONFIG_MEDIA_TUNER_XC4000 is not set
+# CONFIG_MEDIA_TUNER_MXL5005S is not set
+# CONFIG_MEDIA_TUNER_MXL5007T is not set
+# CONFIG_MEDIA_TUNER_MC44S803 is not set
+# CONFIG_MEDIA_TUNER_MAX2165 is not set
+# CONFIG_MEDIA_TUNER_TDA18218 is not set
+# CONFIG_MEDIA_TUNER_TDA18212 is not set
CONFIG_VIDEOBUF2_MSM_MEM=y
CONFIG_V4L_PLATFORM_DRIVERS=y
CONFIG_RADIO_TAVARUA=y
diff --git a/arch/arm/configs/msm7627a_defconfig b/arch/arm/configs/msm7627a_defconfig
index b903a0b..c635e4b 100644
--- a/arch/arm/configs/msm7627a_defconfig
+++ b/arch/arm/configs/msm7627a_defconfig
@@ -280,7 +280,28 @@
CONFIG_MSM_CAMERA_SENSOR=y
CONFIG_MSM_ACTUATOR=y
CONFIG_OV7692=y
-# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
+# CONFIG_MEDIA_TUNER_SIMPLE is not set
+# CONFIG_MEDIA_TUNER_TDA8290 is not set
+# CONFIG_MEDIA_TUNER_TDA827X is not set
+# CONFIG_MEDIA_TUNER_TDA18271 is not set
+# CONFIG_MEDIA_TUNER_TDA9887 is not set
+# CONFIG_MEDIA_TUNER_TEA5761 is not set
+# CONFIG_MEDIA_TUNER_TEA5767 is not set
+# CONFIG_MEDIA_TUNER_MT20XX is not set
+# CONFIG_MEDIA_TUNER_MT2060 is not set
+# CONFIG_MEDIA_TUNER_MT2063 is not set
+# CONFIG_MEDIA_TUNER_MT2266 is not set
+# CONFIG_MEDIA_TUNER_MT2131 is not set
+# CONFIG_MEDIA_TUNER_QT1010 is not set
+# CONFIG_MEDIA_TUNER_XC2028 is not set
+# CONFIG_MEDIA_TUNER_XC5000 is not set
+# CONFIG_MEDIA_TUNER_XC4000 is not set
+# CONFIG_MEDIA_TUNER_MXL5005S is not set
+# CONFIG_MEDIA_TUNER_MXL5007T is not set
+# CONFIG_MEDIA_TUNER_MC44S803 is not set
+# CONFIG_MEDIA_TUNER_MAX2165 is not set
+# CONFIG_MEDIA_TUNER_TDA18218 is not set
+# CONFIG_MEDIA_TUNER_TDA18212 is not set
CONFIG_VIDEOBUF2_MSM_MEM=y
CONFIG_V4L_PLATFORM_DRIVERS=y
CONFIG_RADIO_TAVARUA=y
diff --git a/arch/arm/configs/msm8226-perf_defconfig b/arch/arm/configs/msm8226-perf_defconfig
index 7bf54ce..98eb4d4 100644
--- a/arch/arm/configs/msm8226-perf_defconfig
+++ b/arch/arm/configs/msm8226-perf_defconfig
@@ -21,6 +21,7 @@
CONFIG_BLK_DEV_INITRD=y
CONFIG_RD_BZIP2=y
CONFIG_RD_LZMA=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_PANIC_TIMEOUT=5
CONFIG_KALLSYMS_ALL=y
CONFIG_EMBEDDED=y
@@ -200,6 +201,7 @@
CONFIG_CMA=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
+CONFIG_QSEECOM=y
CONFIG_MD=y
CONFIG_BLK_DEV_DM=y
CONFIG_DM_CRYPT=y
@@ -233,7 +235,6 @@
CONFIG_SPI_QUP=y
CONFIG_SPI_SPIDEV=m
CONFIG_SPMI=y
-CONFIG_MSM_BUS_SCALING=y
CONFIG_SPMI_MSM_PMIC_ARB=y
CONFIG_MSM_QPNP_INT=y
CONFIG_SLIMBUS_MSM_NGD=y
@@ -268,9 +269,8 @@
CONFIG_MSMB_CAMERA=y
CONFIG_OV9724=y
CONFIG_MSMB_JPEG=y
-CONFIG_SWITCH=y
-CONFIG_MSM_WFD=y
CONFIG_MSM_VIDC_V4L2=y
+CONFIG_MSM_WFD=y
CONFIG_VIDEOBUF2_MSM_MEM=y
CONFIG_V4L_PLATFORM_DRIVERS=y
CONFIG_RADIO_IRIS=y
@@ -294,7 +294,6 @@
CONFIG_UHID=y
CONFIG_HID_APPLE=y
CONFIG_HID_MAGICMOUSE=y
-CONFIG_HID_MICROSOFT=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_DEBUG_FILES=y
CONFIG_USB_GADGET_DEBUG_FS=y
@@ -315,6 +314,7 @@
CONFIG_MMC_MSM_SPS_SUPPORT=y
CONFIG_LEDS_QPNP=y
CONFIG_LEDS_TRIGGERS=y
+CONFIG_SWITCH=y
CONFIG_RTC_CLASS=y
# CONFIG_RTC_DRV_MSM is not set
CONFIG_RTC_DRV_QPNP=y
@@ -331,6 +331,7 @@
CONFIG_SPS_SUPPORT_NDP_BAM=y
CONFIG_QPNP_PWM=y
CONFIG_QPNP_POWER_ON=y
+CONFIG_QPNP_VIBRATOR=y
CONFIG_MSM_IOMMU=y
CONFIG_CORESIGHT=y
CONFIG_CORESIGHT_TMC=y
@@ -377,11 +378,7 @@
CONFIG_CRYPTO_MD4=y
CONFIG_CRYPTO_ARC4=y
CONFIG_CRYPTO_TWOFISH=y
-# CONFIG_CRYPTO_HW is not set
-CONFIG_CRC_CCITT=y
-CONFIG_QPNP_VIBRATOR=y
-CONFIG_QSEECOM=y
-CONFIG_CRYPTO_HW=y
CONFIG_CRYPTO_DEV_QCRYPTO=m
CONFIG_CRYPTO_DEV_QCE=y
-CONFIG_CRYPTO_DEV_QCEDEV=m
\ No newline at end of file
+CONFIG_CRYPTO_DEV_QCEDEV=m
+CONFIG_CRC_CCITT=y
diff --git a/arch/arm/configs/msm8226_defconfig b/arch/arm/configs/msm8226_defconfig
index 42becba..c18f8cb 100644
--- a/arch/arm/configs/msm8226_defconfig
+++ b/arch/arm/configs/msm8226_defconfig
@@ -21,6 +21,7 @@
CONFIG_BLK_DEV_INITRD=y
CONFIG_RD_BZIP2=y
CONFIG_RD_LZMA=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_PANIC_TIMEOUT=5
CONFIG_KALLSYMS_ALL=y
CONFIG_EMBEDDED=y
@@ -200,6 +201,7 @@
CONFIG_CMA=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
+CONFIG_QSEECOM=y
CONFIG_MD=y
CONFIG_BLK_DEV_DM=y
CONFIG_DM_CRYPT=y
@@ -234,7 +236,6 @@
CONFIG_SPI_QUP=y
CONFIG_SPI_SPIDEV=m
CONFIG_SPMI=y
-CONFIG_MSM_BUS_SCALING=y
CONFIG_SPMI_MSM_PMIC_ARB=y
CONFIG_MSM_QPNP_INT=y
CONFIG_SLIMBUS_MSM_NGD=y
@@ -242,8 +243,8 @@
CONFIG_GPIO_SYSFS=y
CONFIG_GPIO_QPNP_PIN=y
CONFIG_POWER_SUPPLY=y
-CONFIG_BATTERY_BCL=y
CONFIG_QPNP_CHARGER=y
+CONFIG_BATTERY_BCL=y
CONFIG_QPNP_BMS=y
CONFIG_SENSORS_QPNP_ADC_VOLTAGE=y
CONFIG_SENSORS_QPNP_ADC_CURRENT=y
@@ -271,9 +272,30 @@
CONFIG_MSMB_CAMERA=y
CONFIG_OV9724=y
CONFIG_MSMB_JPEG=y
-CONFIG_SWITCH=y
-CONFIG_MSM_WFD=y
CONFIG_MSM_VIDC_V4L2=y
+CONFIG_MSM_WFD=y
+# CONFIG_MEDIA_TUNER_SIMPLE is not set
+# CONFIG_MEDIA_TUNER_TDA8290 is not set
+# CONFIG_MEDIA_TUNER_TDA827X is not set
+# CONFIG_MEDIA_TUNER_TDA18271 is not set
+# CONFIG_MEDIA_TUNER_TDA9887 is not set
+# CONFIG_MEDIA_TUNER_TEA5761 is not set
+# CONFIG_MEDIA_TUNER_TEA5767 is not set
+# CONFIG_MEDIA_TUNER_MT20XX is not set
+# CONFIG_MEDIA_TUNER_MT2060 is not set
+# CONFIG_MEDIA_TUNER_MT2063 is not set
+# CONFIG_MEDIA_TUNER_MT2266 is not set
+# CONFIG_MEDIA_TUNER_MT2131 is not set
+# CONFIG_MEDIA_TUNER_QT1010 is not set
+# CONFIG_MEDIA_TUNER_XC2028 is not set
+# CONFIG_MEDIA_TUNER_XC5000 is not set
+# CONFIG_MEDIA_TUNER_XC4000 is not set
+# CONFIG_MEDIA_TUNER_MXL5005S is not set
+# CONFIG_MEDIA_TUNER_MXL5007T is not set
+# CONFIG_MEDIA_TUNER_MC44S803 is not set
+# CONFIG_MEDIA_TUNER_MAX2165 is not set
+# CONFIG_MEDIA_TUNER_TDA18218 is not set
+# CONFIG_MEDIA_TUNER_TDA18212 is not set
CONFIG_VIDEOBUF2_MSM_MEM=y
CONFIG_V4L_PLATFORM_DRIVERS=y
CONFIG_RADIO_IRIS=y
@@ -297,7 +319,6 @@
CONFIG_UHID=y
CONFIG_HID_APPLE=y
CONFIG_HID_MAGICMOUSE=y
-CONFIG_HID_MICROSOFT=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_DEBUG_FILES=y
CONFIG_USB_GADGET_DEBUG_FS=y
@@ -318,6 +339,7 @@
CONFIG_MMC_MSM_SPS_SUPPORT=y
CONFIG_LEDS_QPNP=y
CONFIG_LEDS_TRIGGERS=y
+CONFIG_SWITCH=y
CONFIG_RTC_CLASS=y
# CONFIG_RTC_DRV_MSM is not set
CONFIG_RTC_DRV_QPNP=y
@@ -334,6 +356,7 @@
CONFIG_SPS_SUPPORT_NDP_BAM=y
CONFIG_QPNP_PWM=y
CONFIG_QPNP_POWER_ON=y
+CONFIG_QPNP_VIBRATOR=y
CONFIG_MSM_IOMMU=y
CONFIG_CORESIGHT=y
CONFIG_CORESIGHT_TMC=y
@@ -380,11 +403,7 @@
CONFIG_CRYPTO_MD4=y
CONFIG_CRYPTO_ARC4=y
CONFIG_CRYPTO_TWOFISH=y
-# CONFIG_CRYPTO_HW is not set
-CONFIG_CRC_CCITT=y
-CONFIG_QPNP_VIBRATOR=y
-CONFIG_QSEECOM=y
-CONFIG_CRYPTO_HW=y
CONFIG_CRYPTO_DEV_QCRYPTO=m
CONFIG_CRYPTO_DEV_QCE=y
CONFIG_CRYPTO_DEV_QCEDEV=m
+CONFIG_CRC_CCITT=y
diff --git a/arch/arm/configs/msm8610-perf_defconfig b/arch/arm/configs/msm8610-perf_defconfig
index c0253da..3c56bd2 100644
--- a/arch/arm/configs/msm8610-perf_defconfig
+++ b/arch/arm/configs/msm8610-perf_defconfig
@@ -34,6 +34,7 @@
CONFIG_MODVERSIONS=y
CONFIG_PARTITION_ADVANCED=y
CONFIG_EFI_PARTITION=y
+CONFIG_IOSCHED_TEST=y
CONFIG_ARCH_MSM=y
CONFIG_ARCH_MSM8610=y
CONFIG_ARCH_MSM8226=y
@@ -61,8 +62,6 @@
CONFIG_MSM_WATCHDOG_V2=y
CONFIG_MSM_MEMORY_DUMP=y
CONFIG_MSM_DLOAD_MODE=y
-CONFIG_MSM_ENABLE_WDOG_DEBUG_CONTROL=y
-CONFIG_MSM_BOOT_STATS=y
CONFIG_MSM_ADSP_LOADER=m
CONFIG_MSM_OCMEM=y
CONFIG_MSM_OCMEM_LOCAL_POWER_CTRL=y
@@ -72,6 +71,8 @@
CONFIG_SENSORS_ADSP=y
CONFIG_MSM_RTB=y
CONFIG_MSM_RTB_SEPARATE_CPUS=y
+CONFIG_MSM_ENABLE_WDOG_DEBUG_CONTROL=y
+CONFIG_MSM_BOOT_STATS=y
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
CONFIG_SMP=y
@@ -203,6 +204,7 @@
CONFIG_CMA=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
+CONFIG_QSEECOM=y
CONFIG_MD=y
CONFIG_BLK_DEV_DM=y
CONFIG_DM_CRYPT=y
@@ -238,7 +240,6 @@
CONFIG_SPI_QUP=y
CONFIG_SPI_SPIDEV=m
CONFIG_SPMI=y
-CONFIG_MSM_BUS_SCALING=y
CONFIG_SPMI_MSM_PMIC_ARB=y
CONFIG_MSM_QPNP_INT=y
CONFIG_SLIMBUS_MSM_NGD=y
@@ -246,8 +247,8 @@
CONFIG_GPIO_SYSFS=y
CONFIG_GPIO_QPNP_PIN=y
CONFIG_POWER_SUPPLY=y
-CONFIG_BATTERY_BCL=y
CONFIG_QPNP_CHARGER=y
+CONFIG_BATTERY_BCL=y
CONFIG_QPNP_BMS=y
CONFIG_SENSORS_QPNP_ADC_VOLTAGE=y
CONFIG_SENSORS_QPNP_ADC_CURRENT=y
@@ -274,8 +275,8 @@
CONFIG_MSMB_CAMERA=y
CONFIG_OV9724=y
CONFIG_MSMB_JPEG=y
-CONFIG_SWITCH=y
CONFIG_MSM_VIDC_V4L2=y
+CONFIG_MSM_WFD=y
CONFIG_VIDEOBUF2_MSM_MEM=y
CONFIG_V4L_PLATFORM_DRIVERS=y
CONFIG_RADIO_IRIS=y
@@ -302,7 +303,6 @@
CONFIG_UHID=y
CONFIG_HID_APPLE=y
CONFIG_HID_MAGICMOUSE=y
-CONFIG_HID_MICROSOFT=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_DEBUG_FILES=y
CONFIG_USB_GADGET_DEBUG_FS=y
@@ -324,6 +324,7 @@
CONFIG_MMC_MSM_SPS_SUPPORT=y
CONFIG_LEDS_QPNP=y
CONFIG_LEDS_TRIGGERS=y
+CONFIG_SWITCH=y
CONFIG_RTC_CLASS=y
# CONFIG_RTC_DRV_MSM is not set
CONFIG_RTC_DRV_QPNP=y
@@ -340,6 +341,7 @@
CONFIG_SPS_SUPPORT_NDP_BAM=y
CONFIG_QPNP_PWM=y
CONFIG_QPNP_POWER_ON=y
+CONFIG_QPNP_VIBRATOR=y
CONFIG_MSM_IOMMU=y
CONFIG_EXT2_FS=y
CONFIG_EXT2_FS_XATTR=y
@@ -366,6 +368,3 @@
CONFIG_CRYPTO_TWOFISH=y
# CONFIG_CRYPTO_HW is not set
CONFIG_CRC_CCITT=y
-CONFIG_QPNP_VIBRATOR=y
-CONFIG_QSEECOM=y
-CONFIG_IOSCHED_TEST=y
diff --git a/arch/arm/configs/msm8610_defconfig b/arch/arm/configs/msm8610_defconfig
index ce5ee8d..eab374a 100644
--- a/arch/arm/configs/msm8610_defconfig
+++ b/arch/arm/configs/msm8610_defconfig
@@ -32,6 +32,7 @@
CONFIG_MODVERSIONS=y
CONFIG_PARTITION_ADVANCED=y
CONFIG_EFI_PARTITION=y
+CONFIG_IOSCHED_TEST=y
CONFIG_ARCH_MSM=y
CONFIG_ARCH_MSM8610=y
CONFIG_ARCH_MSM8226=y
@@ -201,6 +202,7 @@
CONFIG_CMA=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
+CONFIG_QSEECOM=y
CONFIG_MD=y
CONFIG_BLK_DEV_DM=y
CONFIG_DM_CRYPT=y
@@ -236,7 +238,6 @@
CONFIG_SPI_QUP=y
CONFIG_SPI_SPIDEV=m
CONFIG_SPMI=y
-CONFIG_MSM_BUS_SCALING=y
CONFIG_SPMI_MSM_PMIC_ARB=y
CONFIG_MSM_QPNP_INT=y
CONFIG_SLIMBUS_MSM_NGD=y
@@ -244,8 +245,8 @@
CONFIG_GPIO_SYSFS=y
CONFIG_GPIO_QPNP_PIN=y
CONFIG_POWER_SUPPLY=y
-CONFIG_BATTERY_BCL=y
CONFIG_QPNP_CHARGER=y
+CONFIG_BATTERY_BCL=y
CONFIG_QPNP_BMS=y
CONFIG_SENSORS_QPNP_ADC_VOLTAGE=y
CONFIG_SENSORS_QPNP_ADC_CURRENT=y
@@ -272,9 +273,30 @@
CONFIG_MSMB_CAMERA=y
CONFIG_OV9724=y
CONFIG_MSMB_JPEG=y
-CONFIG_SWITCH=y
-CONFIG_MSM_WFD=y
CONFIG_MSM_VIDC_V4L2=y
+CONFIG_MSM_WFD=y
+# CONFIG_MEDIA_TUNER_SIMPLE is not set
+# CONFIG_MEDIA_TUNER_TDA8290 is not set
+# CONFIG_MEDIA_TUNER_TDA827X is not set
+# CONFIG_MEDIA_TUNER_TDA18271 is not set
+# CONFIG_MEDIA_TUNER_TDA9887 is not set
+# CONFIG_MEDIA_TUNER_TEA5761 is not set
+# CONFIG_MEDIA_TUNER_TEA5767 is not set
+# CONFIG_MEDIA_TUNER_MT20XX is not set
+# CONFIG_MEDIA_TUNER_MT2060 is not set
+# CONFIG_MEDIA_TUNER_MT2063 is not set
+# CONFIG_MEDIA_TUNER_MT2266 is not set
+# CONFIG_MEDIA_TUNER_MT2131 is not set
+# CONFIG_MEDIA_TUNER_QT1010 is not set
+# CONFIG_MEDIA_TUNER_XC2028 is not set
+# CONFIG_MEDIA_TUNER_XC5000 is not set
+# CONFIG_MEDIA_TUNER_XC4000 is not set
+# CONFIG_MEDIA_TUNER_MXL5005S is not set
+# CONFIG_MEDIA_TUNER_MXL5007T is not set
+# CONFIG_MEDIA_TUNER_MC44S803 is not set
+# CONFIG_MEDIA_TUNER_MAX2165 is not set
+# CONFIG_MEDIA_TUNER_TDA18218 is not set
+# CONFIG_MEDIA_TUNER_TDA18212 is not set
CONFIG_VIDEOBUF2_MSM_MEM=y
CONFIG_V4L_PLATFORM_DRIVERS=y
CONFIG_RADIO_IRIS=y
@@ -300,7 +322,6 @@
CONFIG_UHID=y
CONFIG_HID_APPLE=y
CONFIG_HID_MAGICMOUSE=y
-CONFIG_HID_MICROSOFT=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_DEBUG_FILES=y
CONFIG_USB_GADGET_DEBUG_FS=y
@@ -322,6 +343,7 @@
CONFIG_MMC_MSM_SPS_SUPPORT=y
CONFIG_LEDS_QPNP=y
CONFIG_LEDS_TRIGGERS=y
+CONFIG_SWITCH=y
CONFIG_RTC_CLASS=y
# CONFIG_RTC_DRV_MSM is not set
CONFIG_RTC_DRV_QPNP=y
@@ -338,6 +360,7 @@
CONFIG_SPS_SUPPORT_NDP_BAM=y
CONFIG_QPNP_PWM=y
CONFIG_QPNP_POWER_ON=y
+CONFIG_QPNP_VIBRATOR=y
CONFIG_MSM_IOMMU=y
CONFIG_CORESIGHT=y
CONFIG_CORESIGHT_TMC=y
@@ -384,12 +407,7 @@
CONFIG_CRYPTO_MD4=y
CONFIG_CRYPTO_ARC4=y
CONFIG_CRYPTO_TWOFISH=y
-# CONFIG_CRYPTO_HW is not set
-CONFIG_CRC_CCITT=y
-CONFIG_QPNP_VIBRATOR=y
-CONFIG_QSEECOM=y
-CONFIG_CRYPTO_HW=y
CONFIG_CRYPTO_DEV_QCRYPTO=m
CONFIG_CRYPTO_DEV_QCE=y
CONFIG_CRYPTO_DEV_QCEDEV=m
-CONFIG_IOSCHED_TEST=y
+CONFIG_CRC_CCITT=y
diff --git a/arch/arm/configs/msm8660-perf_defconfig b/arch/arm/configs/msm8660-perf_defconfig
index 5885c6e..1b465af 100644
--- a/arch/arm/configs/msm8660-perf_defconfig
+++ b/arch/arm/configs/msm8660-perf_defconfig
@@ -314,7 +314,28 @@
CONFIG_MSM_ACTUATOR=y
CONFIG_MSM_GEMINI=y
CONFIG_OV7692=y
-# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
+# CONFIG_MEDIA_TUNER_SIMPLE is not set
+# CONFIG_MEDIA_TUNER_TDA8290 is not set
+# CONFIG_MEDIA_TUNER_TDA827X is not set
+# CONFIG_MEDIA_TUNER_TDA18271 is not set
+# CONFIG_MEDIA_TUNER_TDA9887 is not set
+# CONFIG_MEDIA_TUNER_TEA5761 is not set
+# CONFIG_MEDIA_TUNER_TEA5767 is not set
+# CONFIG_MEDIA_TUNER_MT20XX is not set
+# CONFIG_MEDIA_TUNER_MT2060 is not set
+# CONFIG_MEDIA_TUNER_MT2063 is not set
+# CONFIG_MEDIA_TUNER_MT2266 is not set
+# CONFIG_MEDIA_TUNER_MT2131 is not set
+# CONFIG_MEDIA_TUNER_QT1010 is not set
+# CONFIG_MEDIA_TUNER_XC2028 is not set
+# CONFIG_MEDIA_TUNER_XC5000 is not set
+# CONFIG_MEDIA_TUNER_XC4000 is not set
+# CONFIG_MEDIA_TUNER_MXL5005S is not set
+# CONFIG_MEDIA_TUNER_MXL5007T is not set
+# CONFIG_MEDIA_TUNER_MC44S803 is not set
+# CONFIG_MEDIA_TUNER_MAX2165 is not set
+# CONFIG_MEDIA_TUNER_TDA18218 is not set
+# CONFIG_MEDIA_TUNER_TDA18212 is not set
CONFIG_VIDEOBUF2_MSM_MEM=y
CONFIG_USB_VIDEO_CLASS=y
CONFIG_V4L_PLATFORM_DRIVERS=y
diff --git a/arch/arm/configs/msm8660_defconfig b/arch/arm/configs/msm8660_defconfig
index abc7460..40fde84 100644
--- a/arch/arm/configs/msm8660_defconfig
+++ b/arch/arm/configs/msm8660_defconfig
@@ -314,7 +314,28 @@
CONFIG_MSM_ACTUATOR=y
CONFIG_MSM_GEMINI=y
CONFIG_OV7692=y
-# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
+# CONFIG_MEDIA_TUNER_SIMPLE is not set
+# CONFIG_MEDIA_TUNER_TDA8290 is not set
+# CONFIG_MEDIA_TUNER_TDA827X is not set
+# CONFIG_MEDIA_TUNER_TDA18271 is not set
+# CONFIG_MEDIA_TUNER_TDA9887 is not set
+# CONFIG_MEDIA_TUNER_TEA5761 is not set
+# CONFIG_MEDIA_TUNER_TEA5767 is not set
+# CONFIG_MEDIA_TUNER_MT20XX is not set
+# CONFIG_MEDIA_TUNER_MT2060 is not set
+# CONFIG_MEDIA_TUNER_MT2063 is not set
+# CONFIG_MEDIA_TUNER_MT2266 is not set
+# CONFIG_MEDIA_TUNER_MT2131 is not set
+# CONFIG_MEDIA_TUNER_QT1010 is not set
+# CONFIG_MEDIA_TUNER_XC2028 is not set
+# CONFIG_MEDIA_TUNER_XC5000 is not set
+# CONFIG_MEDIA_TUNER_XC4000 is not set
+# CONFIG_MEDIA_TUNER_MXL5005S is not set
+# CONFIG_MEDIA_TUNER_MXL5007T is not set
+# CONFIG_MEDIA_TUNER_MC44S803 is not set
+# CONFIG_MEDIA_TUNER_MAX2165 is not set
+# CONFIG_MEDIA_TUNER_TDA18218 is not set
+# CONFIG_MEDIA_TUNER_TDA18212 is not set
CONFIG_VIDEOBUF2_MSM_MEM=y
CONFIG_USB_VIDEO_CLASS=y
CONFIG_V4L_PLATFORM_DRIVERS=y
diff --git a/arch/arm/configs/msm8960-perf_defconfig b/arch/arm/configs/msm8960-perf_defconfig
index fe62c19..80520e6 100644
--- a/arch/arm/configs/msm8960-perf_defconfig
+++ b/arch/arm/configs/msm8960-perf_defconfig
@@ -380,7 +380,28 @@
CONFIG_DVB_MPQ=m
CONFIG_DVB_MPQ_DEMUX=m
CONFIG_DVB_MPQ_VIDEO=m
-# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
+# CONFIG_MEDIA_TUNER_SIMPLE is not set
+# CONFIG_MEDIA_TUNER_TDA8290 is not set
+# CONFIG_MEDIA_TUNER_TDA827X is not set
+# CONFIG_MEDIA_TUNER_TDA18271 is not set
+# CONFIG_MEDIA_TUNER_TDA9887 is not set
+# CONFIG_MEDIA_TUNER_TEA5761 is not set
+# CONFIG_MEDIA_TUNER_TEA5767 is not set
+# CONFIG_MEDIA_TUNER_MT20XX is not set
+# CONFIG_MEDIA_TUNER_MT2060 is not set
+# CONFIG_MEDIA_TUNER_MT2063 is not set
+# CONFIG_MEDIA_TUNER_MT2266 is not set
+# CONFIG_MEDIA_TUNER_MT2131 is not set
+# CONFIG_MEDIA_TUNER_QT1010 is not set
+# CONFIG_MEDIA_TUNER_XC2028 is not set
+# CONFIG_MEDIA_TUNER_XC5000 is not set
+# CONFIG_MEDIA_TUNER_XC4000 is not set
+# CONFIG_MEDIA_TUNER_MXL5005S is not set
+# CONFIG_MEDIA_TUNER_MXL5007T is not set
+# CONFIG_MEDIA_TUNER_MC44S803 is not set
+# CONFIG_MEDIA_TUNER_MAX2165 is not set
+# CONFIG_MEDIA_TUNER_TDA18218 is not set
+# CONFIG_MEDIA_TUNER_TDA18212 is not set
CONFIG_VIDEOBUF2_MSM_MEM=y
CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
CONFIG_USB_VIDEO_CLASS=y
diff --git a/arch/arm/configs/msm8960_defconfig b/arch/arm/configs/msm8960_defconfig
index f699dee..77615e7 100644
--- a/arch/arm/configs/msm8960_defconfig
+++ b/arch/arm/configs/msm8960_defconfig
@@ -382,7 +382,28 @@
CONFIG_DVB_MPQ=m
CONFIG_DVB_MPQ_DEMUX=m
CONFIG_DVB_MPQ_VIDEO=m
-# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
+# CONFIG_MEDIA_TUNER_SIMPLE is not set
+# CONFIG_MEDIA_TUNER_TDA8290 is not set
+# CONFIG_MEDIA_TUNER_TDA827X is not set
+# CONFIG_MEDIA_TUNER_TDA18271 is not set
+# CONFIG_MEDIA_TUNER_TDA9887 is not set
+# CONFIG_MEDIA_TUNER_TEA5761 is not set
+# CONFIG_MEDIA_TUNER_TEA5767 is not set
+# CONFIG_MEDIA_TUNER_MT20XX is not set
+# CONFIG_MEDIA_TUNER_MT2060 is not set
+# CONFIG_MEDIA_TUNER_MT2063 is not set
+# CONFIG_MEDIA_TUNER_MT2266 is not set
+# CONFIG_MEDIA_TUNER_MT2131 is not set
+# CONFIG_MEDIA_TUNER_QT1010 is not set
+# CONFIG_MEDIA_TUNER_XC2028 is not set
+# CONFIG_MEDIA_TUNER_XC5000 is not set
+# CONFIG_MEDIA_TUNER_XC4000 is not set
+# CONFIG_MEDIA_TUNER_MXL5005S is not set
+# CONFIG_MEDIA_TUNER_MXL5007T is not set
+# CONFIG_MEDIA_TUNER_MC44S803 is not set
+# CONFIG_MEDIA_TUNER_MAX2165 is not set
+# CONFIG_MEDIA_TUNER_TDA18218 is not set
+# CONFIG_MEDIA_TUNER_TDA18212 is not set
CONFIG_VIDEOBUF2_MSM_MEM=y
CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
CONFIG_USB_VIDEO_CLASS=y
diff --git a/arch/arm/configs/msm8974-perf_defconfig b/arch/arm/configs/msm8974-perf_defconfig
index b933faa..64a67f5 100644
--- a/arch/arm/configs/msm8974-perf_defconfig
+++ b/arch/arm/configs/msm8974-perf_defconfig
@@ -329,12 +329,12 @@
CONFIG_OV2720=y
CONFIG_IMX135=y
CONFIG_MSM_CAMERA_SENSOR=y
+CONFIG_MSM_EEPROM=y
CONFIG_MSM_CPP=y
CONFIG_MSM_CCI=y
CONFIG_MSM_CSI30_HEADER=y
CONFIG_MSM_CSIPHY=y
CONFIG_MSM_CSID=y
-CONFIG_MSM_EEPROM=y
CONFIG_MSM_ISPIF=y
CONFIG_S5K3L1YX=y
CONFIG_MSMB_CAMERA=y
@@ -459,8 +459,8 @@
CONFIG_NLS_ISO8859_1=y
CONFIG_PRINTK_TIME=y
CONFIG_MAGIC_SYSRQ=y
-CONFIG_TIMER_STATS=y
CONFIG_SCHEDSTATS=y
+CONFIG_TIMER_STATS=y
# CONFIG_DEBUG_PREEMPT is not set
CONFIG_DEBUG_INFO=y
CONFIG_DEBUG_MEMORY_INIT=y
@@ -477,4 +477,3 @@
CONFIG_CRYPTO_DEV_QCRYPTO=m
CONFIG_CRYPTO_DEV_QCE=y
CONFIG_CRYPTO_DEV_QCEDEV=y
-CONFIG_SND_SOC_MSM_HDMI_CODEC_RX=y
diff --git a/arch/arm/configs/msm8974_defconfig b/arch/arm/configs/msm8974_defconfig
index cfdbb29a..b0c1284 100644
--- a/arch/arm/configs/msm8974_defconfig
+++ b/arch/arm/configs/msm8974_defconfig
@@ -335,12 +335,12 @@
CONFIG_OV2720=y
CONFIG_IMX135=y
CONFIG_MSM_CAMERA_SENSOR=y
+CONFIG_MSM_EEPROM=y
CONFIG_MSM_CPP=y
CONFIG_MSM_CCI=y
CONFIG_MSM_CSI30_HEADER=y
CONFIG_MSM_CSIPHY=y
CONFIG_MSM_CSID=y
-CONFIG_MSM_EEPROM=y
CONFIG_MSM_ISPIF=y
CONFIG_S5K3L1YX=y
CONFIG_MSMB_CAMERA=y
@@ -447,8 +447,8 @@
CONFIG_QPNP_REVID=y
CONFIG_QPNP_COINCELL=y
CONFIG_MSM_IOMMU=y
-CONFIG_IOMMU_PGTABLES_L2=y
CONFIG_MSM_IOMMU_PMON=y
+CONFIG_IOMMU_PGTABLES_L2=y
CONFIG_MOBICORE_SUPPORT=m
CONFIG_MOBICORE_API=m
CONFIG_CORESIGHT=y
@@ -509,4 +509,3 @@
CONFIG_CRYPTO_DEV_QCRYPTO=m
CONFIG_CRYPTO_DEV_QCE=y
CONFIG_CRYPTO_DEV_QCEDEV=y
-CONFIG_SND_SOC_MSM_HDMI_CODEC_RX=y
diff --git a/arch/arm/configs/msm9615_defconfig b/arch/arm/configs/msm9615_defconfig
index 0fb8538..3b84f8f 100644
--- a/arch/arm/configs/msm9615_defconfig
+++ b/arch/arm/configs/msm9615_defconfig
@@ -159,7 +159,6 @@
CONFIG_MTD_BLOCK=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
-# CONFIG_ANDROID_PMEM is not set
CONFIG_SCSI=y
CONFIG_SCSI_TGT=y
CONFIG_BLK_DEV_SD=y
diff --git a/arch/arm/configs/msm9625-perf_defconfig b/arch/arm/configs/msm9625-perf_defconfig
index c48eb79..3f15a68 100644
--- a/arch/arm/configs/msm9625-perf_defconfig
+++ b/arch/arm/configs/msm9625-perf_defconfig
@@ -54,9 +54,9 @@
CONFIG_MSM_WATCHDOG_V2=y
CONFIG_MSM_MEMORY_DUMP=y
CONFIG_MSM_DLOAD_MODE=y
-CONFIG_MSM_ENABLE_WDOG_DEBUG_CONTROL=y
CONFIG_MSM_ADSP_LOADER=m
CONFIG_MSM_RTB=y
+CONFIG_MSM_ENABLE_WDOG_DEBUG_CONTROL=y
CONFIG_MSM_UARTDM_Core_v14=y
CONFIG_MSM_BOOT_STATS=y
CONFIG_NO_HZ=y
@@ -161,15 +161,14 @@
CONFIG_CFG80211=m
CONFIG_NL80211_TESTMODE=y
CONFIG_MTD=y
-CONFIG_MTD_CHAR=y
CONFIG_MTD_CMDLINE_PARTS=y
CONFIG_MTD_OF_PARTS=y
+CONFIG_MTD_CHAR=y
CONFIG_MTD_BLOCK=y
# CONFIG_MTD_MSM_NAND is not set
CONFIG_MTD_MSM_QPIC_NAND=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
-# CONFIG_ANDROID_PMEM is not set
CONFIG_SCSI=y
CONFIG_SCSI_TGT=y
CONFIG_BLK_DEV_SD=y
@@ -227,6 +226,7 @@
CONFIG_THERMAL=y
CONFIG_THERMAL_TSENS8974=y
CONFIG_THERMAL_QPNP_ADC_TM=y
+CONFIG_THERMAL_MONITOR=y
CONFIG_WCD9320_CODEC=y
CONFIG_REGULATOR=y
CONFIG_REGULATOR_FIXED_VOLTAGE=y
diff --git a/arch/arm/configs/msm9625_defconfig b/arch/arm/configs/msm9625_defconfig
index 4f2a637..c771bc4 100644
--- a/arch/arm/configs/msm9625_defconfig
+++ b/arch/arm/configs/msm9625_defconfig
@@ -53,9 +53,9 @@
CONFIG_MSM_WATCHDOG_V2=y
CONFIG_MSM_MEMORY_DUMP=y
CONFIG_MSM_DLOAD_MODE=y
-CONFIG_MSM_ENABLE_WDOG_DEBUG_CONTROL=y
CONFIG_MSM_ADSP_LOADER=m
CONFIG_MSM_RTB=y
+CONFIG_MSM_ENABLE_WDOG_DEBUG_CONTROL=y
CONFIG_MSM_UARTDM_Core_v14=y
CONFIG_MSM_BOOT_STATS=y
CONFIG_NO_HZ=y
@@ -163,15 +163,14 @@
CONFIG_CFG80211=m
CONFIG_NL80211_TESTMODE=y
CONFIG_MTD=y
-CONFIG_MTD_CHAR=y
CONFIG_MTD_CMDLINE_PARTS=y
CONFIG_MTD_OF_PARTS=y
+CONFIG_MTD_CHAR=y
CONFIG_MTD_BLOCK=y
# CONFIG_MTD_MSM_NAND is not set
CONFIG_MTD_MSM_QPIC_NAND=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
-# CONFIG_ANDROID_PMEM is not set
CONFIG_SCSI=y
CONFIG_SCSI_TGT=y
CONFIG_BLK_DEV_SD=y
@@ -230,6 +229,7 @@
CONFIG_THERMAL=y
CONFIG_THERMAL_TSENS8974=y
CONFIG_THERMAL_QPNP_ADC_TM=y
+CONFIG_THERMAL_MONITOR=y
CONFIG_WCD9320_CODEC=y
CONFIG_REGULATOR=y
CONFIG_REGULATOR_FIXED_VOLTAGE=y
@@ -324,8 +324,5 @@
CONFIG_CRYPTO_DES=y
CONFIG_CRYPTO_TWOFISH=y
CONFIG_CRYPTO_DEFLATE=y
-#CONFIG_CRYPTO_DEV_QCRYPTO is not set
-#CONFIG_CRYPTO_DEV_QCE is not set
-#CONFIG_CRYPTO_DEV_QCEDEV is not set
CONFIG_CRC_CCITT=y
CONFIG_LIBCRC32C=y
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index 22891b8..86eb7d1 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -404,6 +404,7 @@
select GPIO_MSM_V3
select MAY_HAVE_SPARSE_IRQ
select SPARSE_IRQ
+ select CPU_FREQ_MSM
select MSM_MULTIMEDIA_USE_ION
select MSM_RPM_STATS_LOG
select MSM_QDSP6_APRV2
diff --git a/arch/arm/mach-msm/bam_dmux.c b/arch/arm/mach-msm/bam_dmux.c
index bed794b..b5a7552 100644
--- a/arch/arm/mach-msm/bam_dmux.c
+++ b/arch/arm/mach-msm/bam_dmux.c
@@ -1576,8 +1576,14 @@
static int ssrestart_check(void)
{
- DMUX_LOG_KERR("%s: modem timeout: BAM DMUX disabled\n", __func__);
+ int ret = 0;
+
+ DMUX_LOG_KERR("%s: modem timeout: BAM DMUX disabled for SSR\n",
+ __func__);
in_global_reset = 1;
+ ret = subsystem_restart("modem");
+ if (ret == -ENODEV)
+ panic("modem subsystem restart failed\n");
return 1;
}
diff --git a/arch/arm/mach-msm/clock-8960.c b/arch/arm/mach-msm/clock-8960.c
index 9a1611e..1e91d5b 100644
--- a/arch/arm/mach-msm/clock-8960.c
+++ b/arch/arm/mach-msm/clock-8960.c
@@ -5437,9 +5437,9 @@
CLK_LOOKUP("npl_clk", npl_tv_clk.c, ""),
CLK_LOOKUP("core_clk", gfx3d_clk.c, "kgsl-3d0.0"),
- CLK_LOOKUP("core_clk", gfx3d_clk.c, "footswitch-8x60.2"),
+ CLK_LOOKUP("core_clk", gfx3d_clk.c, "footswitch-8x60.11"),
CLK_LOOKUP("bus_clk",
- gfx3d_axi_clk.c, "footswitch-8x60.2"),
+ gfx3d_axi_clk.c, "footswitch-8x60.11"),
CLK_LOOKUP("iface_clk", vcap_p_clk.c, ""),
CLK_LOOKUP("iface_clk", vcap_p_clk.c, "msm_vcap.0"),
CLK_LOOKUP("iface_clk", vcap_p_clk.c, "footswitch-8x60.10"),
@@ -5493,7 +5493,7 @@
CLK_LOOKUP("master_iface_clk", dsi2_m_p_clk.c, "mipi_dsi.2"),
CLK_LOOKUP("slave_iface_clk", dsi2_s_p_clk.c, "mipi_dsi.2"),
CLK_LOOKUP("iface_clk", gfx3d_p_clk.c, "kgsl-3d0.0"),
- CLK_LOOKUP("iface_clk", gfx3d_p_clk.c, "footswitch-8x60.2"),
+ CLK_LOOKUP("iface_clk", gfx3d_p_clk.c, "footswitch-8x60.11"),
CLK_LOOKUP("master_iface_clk", hdmi_m_p_clk.c, "hdmi_msm.1"),
CLK_LOOKUP("slave_iface_clk", hdmi_s_p_clk.c, "hdmi_msm.1"),
CLK_LOOKUP("iface_clk", ijpeg_p_clk.c, "msm_gemini.0"),
diff --git a/arch/arm/mach-msm/cpuidle.c b/arch/arm/mach-msm/cpuidle.c
index e87c7b5..7c06268 100644
--- a/arch/arm/mach-msm/cpuidle.c
+++ b/arch/arm/mach-msm/cpuidle.c
@@ -14,7 +14,6 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/cpuidle.h>
-#include <linux/cpu_pm.h>
#include <mach/cpuidle.h>
@@ -75,8 +74,6 @@
int i;
enum msm_pm_sleep_mode pm_mode;
- cpu_pm_enter();
-
pm_mode = msm_pm_idle_enter(dev, drv, index);
for (i = 0; i < dev->state_count; i++) {
@@ -90,7 +87,6 @@
}
}
- cpu_pm_exit();
local_irq_enable();
return ret;
diff --git a/arch/arm/mach-msm/devices-8064.c b/arch/arm/mach-msm/devices-8064.c
index 14fe79d..4daccb1 100644
--- a/arch/arm/mach-msm/devices-8064.c
+++ b/arch/arm/mach-msm/devices-8064.c
@@ -2230,11 +2230,12 @@
static struct fs_driver_data gfx3d_fs_data = {
.clks = (struct fs_clk_data[]){
- { .name = "core_clk", .reset_rate = 27000000 },
+ { .name = "core_clk", .reset_rate = 1800000 },
{ .name = "iface_clk" },
{ .name = "bus_clk" },
{ 0 }
},
+ .reset_delay_us = 10,
.bus_port0 = MSM_BUS_MASTER_GRAPHICS_3D,
.bus_port1 = MSM_BUS_MASTER_GRAPHICS_3D_PORT1,
};
@@ -2323,7 +2324,7 @@
FS_8X60(FS_IJPEG, "vdd", "msm_gemini.0", &ijpeg_fs_data),
FS_8X60(FS_VFE, "vdd", "msm_vfe.0", &vfe_fs_data),
FS_8X60(FS_VPE, "vdd", "msm_vpe.0", &vpe_fs_data),
- FS_8X60(FS_GFX3D, "vdd", "kgsl-3d0.0", &gfx3d_fs_data),
+ FS_8X60(FS_GFX3D_8064, "vdd", "kgsl-3d0.0", &gfx3d_fs_data),
FS_8X60(FS_VED, "vdd", "msm_vidc.0", &ved_fs_data),
FS_8X60(FS_VCAP, "vdd", "msm_vcap.0", &vcap_fs_data),
};
diff --git a/arch/arm/mach-msm/footswitch-8x60.c b/arch/arm/mach-msm/footswitch-8x60.c
index 581c563..67bbd5e 100644
--- a/arch/arm/mach-msm/footswitch-8x60.c
+++ b/arch/arm/mach-msm/footswitch-8x60.c
@@ -25,7 +25,10 @@
#include <mach/msm_bus.h>
#include <mach/scm-io.h>
#include <mach/clk.h>
+#include <mach/rpm.h>
+
#include "footswitch.h"
+#include "rpm_resources.h"
#ifdef CONFIG_MSM_SECURE_IO
#undef readl_relaxed
@@ -239,7 +242,8 @@
return rc;
/* Allow core memory to collapse when its clock is gated. */
- clk_set_flags(fs->core_clk, CLKFLAG_NORETAIN_MEM);
+ if (fs->desc.id != FS_GFX3D_8064)
+ clk_set_flags(fs->core_clk, CLKFLAG_NORETAIN_MEM);
/* Halt all bus ports in the power domain. */
if (fs->bus_port0) {
@@ -442,6 +446,120 @@
return rc;
}
+static void force_bus_clocks(bool enforce)
+{
+ static struct msm_rpm_iv_pair iv;
+ int ret;
+
+ if (enforce) {
+ iv.id = MSM_RPM_STATUS_ID_RPM_CTL;
+ ret = msm_rpm_get_status(&iv, 1);
+ if (ret)
+ pr_err("Failed to read RPM_CTL resource status\n");
+
+ iv.id = MSM_RPM_ID_RPM_CTL;
+ iv.value |= BIT(6);
+ } else {
+ iv.id = MSM_RPM_ID_RPM_CTL;
+ iv.value &= ~BIT(6);
+ }
+
+ ret = msm_rpmrs_set(MSM_RPM_CTX_SET_0, &iv, 1);
+ if (ret)
+ pr_err("Force bus clocks request=%d failed\n", enforce);
+}
+
+static int gfx3d_8064_footswitch_enable(struct regulator_dev *rdev)
+{
+ struct footswitch *fs = rdev_get_drvdata(rdev);
+ struct fs_clk_data *clock;
+ uint32_t regval, rc = 0;
+
+ mutex_lock(&claim_lock);
+ fs->is_claimed = true;
+ mutex_unlock(&claim_lock);
+
+ /* Return early if already enabled. */
+ regval = readl_relaxed(fs->gfs_ctl_reg);
+ if ((regval & (ENABLE_BIT | CLAMP_BIT)) == ENABLE_BIT)
+ return 0;
+
+ /* Un-halt all bus ports in the power domain. */
+ if (fs->bus_port0) {
+ rc = msm_bus_axi_portunhalt(fs->bus_port0);
+ if (rc) {
+ pr_err("%s port 0 unhalt failed.\n", fs->desc.name);
+ goto err;
+ }
+ }
+ if (fs->bus_port1) {
+ rc = msm_bus_axi_portunhalt(fs->bus_port1);
+ if (rc) {
+ pr_err("%s port 1 unhalt failed.\n", fs->desc.name);
+ goto err_port2_halt;
+ }
+ }
+
+ /* Apply AFAB/EBI clock limits. */
+ force_bus_clocks(true);
+
+ /* Enable the power rail at the footswitch. */
+ regval |= ENABLE_BIT;
+ writel_relaxed(regval, fs->gfs_ctl_reg);
+ /* Wait for the rail to fully charge. */
+ mb();
+ udelay(1);
+
+ /* Make sure required clocks are on at the correct rates. */
+ rc = setup_clocks(fs);
+ if (rc)
+ goto err_setup_clocks;
+
+ /*
+ * (Re-)Assert resets for all clocks in the clock domain, since
+ * footswitch_enable() is first called before footswitch_disable()
+ * and resets should be asserted before power is restored.
+ */
+ for (clock = fs->clk_data; clock->clk; clock++)
+ ; /* Do nothing */
+ for (clock--; clock >= fs->clk_data; clock--)
+ clk_reset(clock->clk, CLK_RESET_ASSERT);
+ /* Wait for synchronous resets to propagate. */
+ udelay(fs->reset_delay_us);
+
+ /* Un-clamp the I/O ports. */
+ regval &= ~CLAMP_BIT;
+ writel_relaxed(regval, fs->gfs_ctl_reg);
+
+ /* Deassert resets for all clocks in the power domain. */
+ for (clock = fs->clk_data; clock->clk; clock++)
+ clk_reset(clock->clk, CLK_RESET_DEASSERT);
+
+ /* Prevent core memory from collapsing when its clock is gated. */
+ clk_set_flags(fs->core_clk, CLKFLAG_RETAIN_MEM);
+
+ /* Return clocks to their state before this function. */
+ restore_clocks(fs);
+
+ /* Remove AFAB/EBI clock limits after any transients have settled. */
+ udelay(30);
+ force_bus_clocks(false);
+
+ fs->is_enabled = true;
+ return 0;
+
+err_setup_clocks:
+ regval &= ~ENABLE_BIT;
+ writel_relaxed(regval, fs->gfs_ctl_reg);
+ force_bus_clocks(false);
+ msm_bus_axi_porthalt(fs->bus_port1);
+err_port2_halt:
+ msm_bus_axi_porthalt(fs->bus_port0);
+err:
+ return rc;
+}
+
+
static struct regulator_ops standard_fs_ops = {
.is_enabled = footswitch_is_enabled,
.enable = footswitch_enable,
@@ -454,6 +572,12 @@
.disable = gfx2d_footswitch_disable,
};
+static struct regulator_ops gfx3d_8064_fs_ops = {
+ .is_enabled = footswitch_is_enabled,
+ .enable = gfx3d_8064_footswitch_enable,
+ .disable = footswitch_disable,
+};
+
#define FOOTSWITCH(_id, _name, _ops, _gfs_ctl_reg) \
[(_id)] = { \
.desc = { \
@@ -468,6 +592,8 @@
static struct footswitch footswitches[] = {
FOOTSWITCH(FS_GFX2D0, "fs_gfx2d0", &gfx2d_fs_ops, GFX2D0_GFS_CTL_REG),
FOOTSWITCH(FS_GFX2D1, "fs_gfx2d1", &gfx2d_fs_ops, GFX2D1_GFS_CTL_REG),
+ FOOTSWITCH(FS_GFX3D_8064, "fs_gfx3d", &gfx3d_8064_fs_ops,
+ GFX3D_GFS_CTL_REG),
FOOTSWITCH(FS_GFX3D, "fs_gfx3d", &standard_fs_ops, GFX3D_GFS_CTL_REG),
FOOTSWITCH(FS_IJPEG, "fs_ijpeg", &standard_fs_ops, GEMINI_GFS_CTL_REG),
FOOTSWITCH(FS_MDP, "fs_mdp", &standard_fs_ops, MDP_GFS_CTL_REG),
diff --git a/arch/arm/mach-msm/footswitch.h b/arch/arm/mach-msm/footswitch.h
index 57e8eba..b961f42 100644
--- a/arch/arm/mach-msm/footswitch.h
+++ b/arch/arm/mach-msm/footswitch.h
@@ -28,7 +28,8 @@
#define FS_VFE 8
#define FS_VPE 9
#define FS_VCAP 10
-#define MAX_FS 11
+#define FS_GFX3D_8064 11
+#define MAX_FS 12
struct fs_clk_data {
const char *name;
diff --git a/arch/arm/mach-msm/include/mach/subsystem_restart.h b/arch/arm/mach-msm/include/mach/subsystem_restart.h
index 35b1f76..962429e 100644
--- a/arch/arm/mach-msm/include/mach/subsystem_restart.h
+++ b/arch/arm/mach-msm/include/mach/subsystem_restart.h
@@ -75,6 +75,8 @@
extern void subsys_unregister(struct subsys_device *dev);
extern void subsys_default_online(struct subsys_device *dev);
+extern void subsys_set_crash_status(struct subsys_device *dev, bool crashed);
+extern bool subsys_get_crash_status(struct subsys_device *dev);
#else
@@ -114,6 +116,12 @@
static inline void subsys_unregister(struct subsys_device *dev) { }
static inline void subsys_default_online(struct subsys_device *dev) { }
+static inline
+void subsys_set_crash_status(struct subsys_device *dev, bool crashed) { }
+static inline bool subsys_get_crash_status(struct subsys_device *dev)
+{
+ return false;
+}
#endif /* CONFIG_MSM_SUBSYSTEM_RESTART */
diff --git a/arch/arm/mach-msm/ipc_router.h b/arch/arm/mach-msm/ipc_router.h
index 502cac1..32832dd 100644
--- a/arch/arm/mach-msm/ipc_router.h
+++ b/arch/arm/mach-msm/ipc_router.h
@@ -107,6 +107,7 @@
struct msm_ipc_sock {
struct sock sk;
struct msm_ipc_port *port;
+ void *default_pil;
};
struct msm_ipc_router_xprt {
@@ -158,4 +159,15 @@
void msm_ipc_sync_default_sec_rule(void *rule);
+#if defined CONFIG_MSM_IPC_ROUTER_SMD_XPRT
+extern void *msm_ipc_load_default_node(void);
+
+extern void msm_ipc_unload_default_node(void *pil);
+#else
+static inline void *msm_ipc_load_default_node(void)
+{ return NULL; }
+
+static inline void msm_ipc_unload_default_node(void *pil) { }
+#endif
+
#endif
diff --git a/arch/arm/mach-msm/ipc_router_smd_xprt.c b/arch/arm/mach-msm/ipc_router_smd_xprt.c
index c7c2298..b2ec816 100644
--- a/arch/arm/mach-msm/ipc_router_smd_xprt.c
+++ b/arch/arm/mach-msm/ipc_router_smd_xprt.c
@@ -475,6 +475,31 @@
return 0;
}
+void *msm_ipc_load_default_node(void)
+{
+ void *pil = NULL;
+ const char *peripheral;
+
+ peripheral = smd_edge_to_subsystem(SMD_APPS_MODEM);
+ if (peripheral && !strncmp(peripheral, "modem", 6)) {
+ pil = subsystem_get(peripheral);
+ if (IS_ERR(pil)) {
+ pr_err("%s: Failed to load %s\n",
+ __func__, peripheral);
+ pil = NULL;
+ }
+ }
+ return pil;
+}
+EXPORT_SYMBOL(msm_ipc_load_default_node);
+
+void msm_ipc_unload_default_node(void *pil)
+{
+ if (pil)
+ subsystem_put(pil);
+}
+EXPORT_SYMBOL(msm_ipc_unload_default_node);
+
static struct platform_driver msm_ipc_router_smd_remote_driver[] = {
{
.probe = msm_ipc_router_smd_remote_probe,
diff --git a/arch/arm/mach-msm/ipc_socket.c b/arch/arm/mach-msm/ipc_socket.c
index 3409867..515dc92 100644
--- a/arch/arm/mach-msm/ipc_socket.c
+++ b/arch/arm/mach-msm/ipc_socket.c
@@ -312,6 +312,7 @@
struct sock *sk = sock->sk;
struct msm_ipc_port *port_ptr;
int ret;
+ void *pil;
if (!sk)
return -EINVAL;
@@ -341,6 +342,8 @@
if (!port_ptr)
return -ENODEV;
+ pil = msm_ipc_load_default_node();
+ msm_ipc_sk(sk)->default_pil = pil;
lock_sock(sk);
ret = msm_ipc_router_register_server(port_ptr, &addr->address);
@@ -462,6 +465,7 @@
unsigned int n;
size_t srv_info_sz = 0;
int ret;
+ void *pil;
if (!sk)
return -EINVAL;
@@ -489,6 +493,8 @@
break;
case IPC_ROUTER_IOCTL_LOOKUP_SERVER:
+ pil = msm_ipc_load_default_node();
+ msm_ipc_sk(sk)->default_pil = pil;
ret = copy_from_user(&server_arg, (void *)arg,
sizeof(server_arg));
if (ret) {
@@ -582,10 +588,13 @@
{
struct sock *sk = sock->sk;
struct msm_ipc_port *port_ptr = msm_ipc_sk_port(sk);
+ void *pil = msm_ipc_sk(sk)->default_pil;
int ret;
lock_sock(sk);
ret = msm_ipc_router_close_port(port_ptr);
+ if (pil)
+ msm_ipc_unload_default_node(pil);
release_sock(sk);
sock_put(sk);
sock->sk = NULL;
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_arb.c b/arch/arm/mach-msm/msm_bus/msm_bus_arb.c
index 60f05f6..f1c8726 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_arb.c
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_arb.c
@@ -342,6 +342,15 @@
return -ENXIO;
}
+ /**
+ * If master supports dual configuration, check if
+ * the configuration needs to be changed based on
+ * incoming requests
+ */
+ if (info->node_info->dual_conf)
+ fabdev->algo->config_master(fabdev, info,
+ req_clk, req_bw);
+
info->link_info.sel_bw = &info->link_info.bw[ctx];
info->link_info.sel_clk = &info->link_info.clk[ctx];
*info->link_info.sel_bw += add_bw;
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_bimc.c b/arch/arm/mach-msm/msm_bus/msm_bus_bimc.c
index d531aaa..bc15fe8 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_bimc.c
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_bimc.c
@@ -26,6 +26,10 @@
SLAVE_BLOCK_SCMO,
};
+enum bke_sw {
+ BKE_OFF = 0,
+ BKE_ON = 1,
+};
/* Misc module */
@@ -1367,7 +1371,7 @@
(M_BKE_GC_GC_BMSK >> \
M_BKE_GC_GC_SHFT)
-static int bimc_div(uint64_t *a, uint32_t b)
+static int bimc_div(int64_t *a, uint32_t b)
{
if ((*a > 0) && (*a < b))
return 1;
@@ -1508,7 +1512,7 @@
val0 = BKE_HEALTH_VAL(qmode->rl.qhealth[index].limit_commands,
qmode->rl.qhealth[index].areq_prio,
qmode->rl.qhealth[index].prio_level);
- val = (reg_val & (~(BKE_HEALTH_MASK) | (val0 & BKE_HEALTH_MASK)));
+ val = ((reg_val & (~(BKE_HEALTH_MASK))) | (val0 & BKE_HEALTH_MASK));
writel_relaxed(val, addr);
/* Ensure that priority for regulator/limiter modes are
* set before returning
@@ -1563,7 +1567,7 @@
mas_index), M_BKE_HEALTH_2_CONFIG_RMSK, 2, qmode);
set_qos_prio_rl(M_BKE_HEALTH_1_CONFIG_ADDR(binfo->base,
mas_index), M_BKE_HEALTH_1_CONFIG_RMSK, 1, qmode);
- set_qos_prio_rl(M_BKE_HEALTH_1_CONFIG_ADDR(binfo->base,
+ set_qos_prio_rl(M_BKE_HEALTH_0_CONFIG_ADDR(binfo->base,
mas_index), M_BKE_HEALTH_0_CONFIG_RMSK, 0 , qmode);
break;
case BIMC_QOS_MODE_BYPASS:
@@ -1573,10 +1577,11 @@
}
static void set_qos_bw_regs(void __iomem *baddr, uint32_t mas_index,
- long int th, long int tm, long int tl, uint32_t gp,
+ int32_t th, int32_t tm, int32_t tl, uint32_t gp,
uint32_t gc, bool bke_en)
{
- uint32_t reg_val, val;
+ int32_t reg_val, val;
+ int16_t val2;
/* Disable BKE before writing to registers as per spec */
reg_val = readl_relaxed(M_BKE_EN_ADDR(baddr, mas_index)) &
@@ -1605,15 +1610,15 @@
reg_val = readl_relaxed(M_BKE_THM_ADDR(baddr, mas_index)) &
M_BKE_THM_RMSK;
- val = tm << M_BKE_THM_THRESH_SHFT;
- writel_relaxed(((reg_val & ~(M_BKE_THM_THRESH_BMSK)) | (val &
+ val2 = tm << M_BKE_THM_THRESH_SHFT;
+ writel_relaxed(((reg_val & ~(M_BKE_THM_THRESH_BMSK)) | (val2 &
M_BKE_THM_THRESH_BMSK)), M_BKE_THM_ADDR(baddr, mas_index));
reg_val = readl_relaxed(M_BKE_THL_ADDR(baddr, mas_index)) &
M_BKE_THL_RMSK;
- val = tl << M_BKE_THL_THRESH_SHFT;
+ val2 = tl << M_BKE_THL_THRESH_SHFT;
writel_relaxed(((reg_val & ~(M_BKE_THL_THRESH_BMSK)) |
- (val & M_BKE_THL_THRESH_BMSK)), M_BKE_THL_ADDR(baddr,
+ (val2 & M_BKE_THL_THRESH_BMSK)), M_BKE_THL_ADDR(baddr,
mas_index));
/* Set BKE enable to the value it was */
@@ -1645,10 +1650,10 @@
/* Only calculate if there's a requested bandwidth and window */
if (qbw->bw && qbw->ws) {
- uint64_t th, tm, tl;
+ int64_t th, tm, tl;
uint32_t gp, gc, data_width;
- uint64_t gp_nominal, gp_required, gp_calc, data, temp;
- uint64_t win = qbw->ws * binfo->qos_freq;
+ int64_t gp_nominal, gp_required, gp_calc, data, temp;
+ int64_t win = qbw->ws * binfo->qos_freq;
temp = win;
/*
* Calculate nominal grant period defined by requested
@@ -1675,13 +1680,13 @@
bimc_div(&gp_required, qbw->bw);
/* User min of two grant periods */
- gp = min_t(uint64_t, gp_nominal, gp_required);
+ gp = min_t(int64_t, gp_nominal, gp_required);
/* Calculate bandwith in grants and ceil. */
temp = qbw->bw * gp;
data = data_width * binfo->qos_freq * 1000;
bimc_div(&temp, data);
- gc = min_t(uint64_t, MAX_GC, temp);
+ gc = min_t(int64_t, MAX_GC, temp);
/* Calculate thresholds */
th = qbw->bw - qbw->thh;
@@ -1811,6 +1816,57 @@
kfree(cd);
}
+static void bke_switch(void __iomem *baddr, uint32_t mas_index, bool req)
+{
+ uint32_t reg_val, val;
+
+ val = req << M_BKE_EN_EN_SHFT;
+ reg_val = readl_relaxed(M_BKE_EN_ADDR(baddr, mas_index)) &
+ M_BKE_EN_RMSK;
+ writel_relaxed(((reg_val & ~(M_BKE_EN_EN_BMSK)) | (val &
+ M_BKE_EN_EN_BMSK)), M_BKE_EN_ADDR(baddr, mas_index));
+ wmb();
+}
+
+static void msm_bus_bimc_config_master(
+ struct msm_bus_fabric_registration *fab_pdata,
+ struct msm_bus_inode_info *info,
+ uint64_t req_clk, uint64_t req_bw)
+{
+ int mode, i, ports;
+ struct msm_bus_bimc_info *binfo;
+
+ binfo = (struct msm_bus_bimc_info *)fab_pdata->hw_data;
+ ports = info->node_info->num_mports;
+
+ /**
+ * Here check the details of dual configuration.
+ * Take actions based on different modes.
+ * Check for threshold if limiter mode, etc.
+ */
+ if (req_clk > info->node_info->th)
+ mode = info->node_info->mode_thresh;
+ else
+ mode = info->node_info->mode;
+
+ switch (mode) {
+ case BIMC_QOS_MODE_BYPASS:
+ case BIMC_QOS_MODE_FIXED:
+ for (i = 0; i < ports; i++)
+ bke_switch(binfo->base, info->node_info->qport[i],
+ BKE_OFF);
+ break;
+ case BIMC_QOS_MODE_REGULATOR:
+ case BIMC_QOS_MODE_LIMITER:
+ for (i = 0; i < ports; i++)
+ bke_switch(binfo->base, info->node_info->qport[i],
+ BKE_ON);
+ break;
+ default:
+ break;
+ }
+}
+
static void msm_bus_bimc_update_bw(struct msm_bus_inode_info *hop,
struct msm_bus_inode_info *info,
struct msm_bus_fabric_registration *fab_pdata,
@@ -1910,10 +1966,106 @@
return 0;
}
+static void bimc_set_static_qos_bw(struct msm_bus_bimc_info *binfo,
+ int mport, struct msm_bus_bimc_qos_bw *qbw)
+{
+ int32_t bw_MBps, thh = 0, thm, thl, gc;
+ int16_t gp;
+ u64 temp;
+
+ if (binfo->qos_freq == 0) {
+ MSM_BUS_DBG("Zero QoS Frequency\n");
+ return;
+ }
+
+ if (!(qbw->bw && qbw->ws)) {
+ MSM_BUS_DBG("No QoS Bandwidth or Window size\n");
+ return;
+ }
+
+ /* Convert bandwidth to MBPS */
+ temp = qbw->bw;
+ bimc_div(&temp, 1000000);
+ bw_MBps = temp;
+
+ /* Grant period in clock cycles
+ * Grant period from bandwidth structure
+ * is in micro seconds, QoS freq is in KHz.
+ * Divide by 1000 to get clock cycles */
+ gp = (binfo->qos_freq * qbw->gp) / 1000;
+
+ /* Grant count = BW in MBps * Grant period
+ * in micro seconds */
+ gc = bw_MBps * qbw->gp;
+
+ /* Medium threshold = -((Medium Threshold percentage *
+ * Grant count) / 100) */
+ thm = -((qbw->thmp * gc) / 100);
+ qbw->thm = thm;
+
+ /* Low threshold = -(Grant count) */
+ thl = -gc;
+ qbw->thl = thl;
+
+ set_qos_bw_regs(binfo->base, mport, thh, thm, thl, gp,
+ gc, 1);
+}
+
+static void bimc_init_mas_reg(struct msm_bus_bimc_info *binfo,
+ struct msm_bus_inode_info *info,
+ struct msm_bus_bimc_qos_mode *qmode, int mode)
+{
+ int i;
+
+ switch (mode) {
+ case BIMC_QOS_MODE_FIXED:
+ qmode->fixed.prio_level = info->node_info->prio_lvl;
+ qmode->fixed.areq_prio_rd = info->node_info->prio_rd;
+ qmode->fixed.areq_prio_wr = info->node_info->prio_wr;
+ break;
+ case BIMC_QOS_MODE_LIMITER:
+ qmode->rl.qhealth[0].limit_commands = 1;
+ qmode->rl.qhealth[1].limit_commands = 0;
+ qmode->rl.qhealth[2].limit_commands = 0;
+ qmode->rl.qhealth[3].limit_commands = 0;
+ break;
+ default:
+ break;
+ }
+
+ if (!info->node_info->qport) {
+ MSM_BUS_DBG("No QoS Ports to init\n");
+ return;
+ }
+
+ for (i = 0; i < info->node_info->num_mports; i++) {
+ /* If not in bypass mode, update priority */
+ if (mode != BIMC_QOS_MODE_BYPASS) {
+ msm_bus_bimc_set_qos_prio(binfo, info->node_info->
+ qport[i], mode, qmode);
+
+ /* If not in fixed mode, update bandwidth */
+ if (mode != BIMC_QOS_MODE_FIXED) {
+ struct msm_bus_bimc_qos_bw qbw;
+ qbw.ws = info->node_info->ws;
+ qbw.bw = info->node_info->bimc_bw;
+ qbw.gp = info->node_info->bimc_gp;
+ qbw.thmp = info->node_info->bimc_thmp;
+ bimc_set_static_qos_bw(binfo,
+ info->node_info->qport[i], &qbw);
+ }
+ }
+
+ /* set mode */
+ msm_bus_bimc_set_qos_mode(binfo, info->node_info->qport[i],
+ mode);
+ }
+}
+
+
static int msm_bus_bimc_mas_init(struct msm_bus_bimc_info *binfo,
struct msm_bus_inode_info *info)
{
- int i;
struct msm_bus_bimc_qos_mode *qmode;
qmode = kzalloc(sizeof(struct msm_bus_bimc_qos_mode),
GFP_KERNEL);
@@ -1923,42 +2075,17 @@
return -ENOMEM;
}
- switch (info->node_info->mode) {
- case BIMC_QOS_MODE_FIXED:
- qmode->fixed.prio_level = info->node_info->prio_lvl;
- qmode->fixed.areq_prio_rd = info->node_info->prio_rd;
- qmode->fixed.areq_prio_wr = info->node_info->prio_wr;
- break;
- default:
- break;
- }
-
info->hw_data = (void *)qmode;
- if (!info->node_info->qport) {
- MSM_BUS_DBG("No QoS Ports to init\n");
- return 0;
- }
- for (i = 0; i < info->node_info->num_mports; i++) {
- /* If not in bypass mode, update priority */
- if (info->node_info->mode != BIMC_QOS_MODE_BYPASS) {
- msm_bus_bimc_set_qos_prio(binfo, info->node_info->
- qport[i], info->node_info->mode, qmode);
+ /**
+ * If the master supports dual configuration,
+ * configure registers for both modes
+ */
+ if (info->node_info->dual_conf)
+ bimc_init_mas_reg(binfo, info, qmode,
+ info->node_info->mode_thresh);
- /* If not in fixed mode, update bandwidth */
- if (info->node_info->mode != BIMC_QOS_MODE_FIXED) {
- struct msm_bus_bimc_qos_bw qbw;
- qbw.ws = info->node_info->ws;
- msm_bus_bimc_set_qos_bw(binfo,
- info->node_info->qport[i], &qbw);
- }
- }
-
- /* set mode */
- msm_bus_bimc_set_qos_mode(binfo, info->node_info->qport[i],
- info->node_info->mode);
- }
-
+ bimc_init_mas_reg(binfo, info, qmode, info->node_info->mode);
return 0;
}
@@ -1998,6 +2125,7 @@
hw_algo->commit = msm_bus_bimc_commit;
hw_algo->port_halt = msm_bus_bimc_port_halt;
hw_algo->port_unhalt = msm_bus_bimc_port_unhalt;
+ hw_algo->config_master = msm_bus_bimc_config_master;
/* BIMC slaves are shared. Slave registers are set through RPM */
if (!pdata->ahb)
pdata->rpm_enabled = 1;
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_bimc.h b/arch/arm/mach-msm/msm_bus/msm_bus_bimc.h
index 6df0bea..12c8325 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_bimc.h
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_bimc.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -93,9 +93,11 @@
struct msm_bus_bimc_qos_bw {
uint64_t bw; /* bw is in Bytes/sec */
uint32_t ws; /* Window size in nano seconds*/
- uint64_t thh; /* Threshold high, bytes per second */
- uint64_t thm; /* Threshold medium, bytes per second */
- uint64_t thl; /* Threshold low, bytes per second */
+ int64_t thh; /* Threshold high, bytes per second */
+ int64_t thm; /* Threshold medium, bytes per second */
+ int64_t thl; /* Threshold low, bytes per second */
+ u32 gp; /* Grant Period in micro seconds */
+ u32 thmp; /* Threshold medium in percentage */
};
struct msm_bus_bimc_clk_gate {
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_core.h b/arch/arm/mach-msm/msm_bus/msm_bus_core.h
index 98419a4..87719e3 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_core.h
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_core.h
@@ -81,6 +81,12 @@
unsigned int prio_wr;
unsigned int prio1;
unsigned int prio0;
+ u64 th;
+ unsigned int mode_thresh;
+ bool dual_conf;
+ u64 bimc_bw;
+ u32 bimc_gp;
+ u32 bimc_thmp;
const char *name;
};
@@ -147,6 +153,9 @@
*fab_pdata, void *hw_data, void **cdata);
int (*port_unhalt)(uint32_t haltid, uint8_t mport);
int (*port_halt)(uint32_t haltid, uint8_t mport);
+ void (*config_master)(struct msm_bus_fabric_registration *fab_pdata,
+ struct msm_bus_inode_info *info,
+ uint64_t req_clk, uint64_t req_bw);
};
struct msm_bus_fabric_device {
@@ -179,6 +188,9 @@
void (*update_bw)(struct msm_bus_fabric_device *fabdev, struct
msm_bus_inode_info * hop, struct msm_bus_inode_info *info,
int64_t add_bw, int *master_tiers, int ctx);
+ void (*config_master)(struct msm_bus_fabric_device *fabdev,
+ struct msm_bus_inode_info *info, uint64_t req_clk,
+ uint64_t req_bw);
};
struct msm_bus_board_algorithm {
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_fabric.c b/arch/arm/mach-msm/msm_bus/msm_bus_fabric.c
index 62da5ac..ddf747e 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_fabric.c
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_fabric.c
@@ -509,6 +509,46 @@
return status;
}
+static void msm_bus_fabric_config_master(
+ struct msm_bus_fabric_device *fabdev,
+ struct msm_bus_inode_info *info, uint64_t req_clk, uint64_t req_bw)
+{
+ struct msm_bus_fabric *fabric = to_msm_bus_fabric(fabdev);
+ long rounded_rate;
+
+ if (fabdev->hw_algo.config_master == NULL)
+ return;
+
+ /* Enable clocks before accessing QoS registers */
+ if (fabric->info.nodeclk[DUAL_CTX].clk)
+ if (fabric->info.nodeclk[DUAL_CTX].rate == 0) {
+ rounded_rate = clk_round_rate(fabric->
+ info.nodeclk[DUAL_CTX].clk, 1);
+ if (clk_set_rate(fabric->info.nodeclk[DUAL_CTX].clk,
+ rounded_rate))
+ MSM_BUS_ERR("Error: clk: en: Node: %d rate: %ld",
+ fabric->fabdev.id, rounded_rate);
+
+ clk_prepare_enable(fabric->info.nodeclk[DUAL_CTX].clk);
+ }
+
+ if (info->iface_clk.clk)
+ clk_prepare_enable(info->iface_clk.clk);
+
+ fabdev->hw_algo.config_master(fabric->pdata, info, req_clk, req_bw);
+
+ /* Disable clocks after accessing QoS registers */
+ if (fabric->info.nodeclk[DUAL_CTX].clk &&
+ fabric->info.nodeclk[DUAL_CTX].rate == 0)
+ clk_disable_unprepare(fabric->info.nodeclk[DUAL_CTX].clk);
+
+ if (info->iface_clk.clk) {
+ MSM_BUS_DBG("Commented: Will disable clock for info: %d\n",
+ info->node_info->priv_id);
+ clk_disable_unprepare(info->iface_clk.clk);
+ }
+}
+
/**
* msm_bus_fabric_hw_commit() - Commit the arbitration data to Hardware.
* @fabric: Fabric for which the data should be committed
@@ -664,6 +704,7 @@
.find_node = msm_bus_fabric_find_node,
.find_gw_node = msm_bus_fabric_find_gw_node,
.get_gw_list = msm_bus_fabric_get_gw_list,
+ .config_master = msm_bus_fabric_config_master,
};
static int msm_bus_fabric_hw_init(struct msm_bus_fabric_registration *pdata,
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_noc.c b/arch/arm/mach-msm/msm_bus/msm_bus_noc.c
index 3ae37e4..d33c340 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_noc.c
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_noc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -619,6 +619,7 @@
hw_algo->commit = msm_bus_noc_commit;
hw_algo->port_halt = msm_bus_noc_port_halt;
hw_algo->port_unhalt = msm_bus_noc_port_unhalt;
+ hw_algo->config_master = NULL;
return 0;
}
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_of.c b/arch/arm/mach-msm/msm_bus/msm_bus_of.c
index 4e25637..06894c6 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_of.c
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_of.c
@@ -22,7 +22,7 @@
#include <mach/msm_bus_board.h>
#include "msm_bus_core.h"
-#define KBTOMB(a) (a * 1000ULL)
+#define KBTOB(a) (a * 1000ULL)
static const char * const hw_sel_name[] = {"RPM", "NoC", "BIMC", NULL};
static const char * const mode_sel_name[] = {"Fixed", "Limiter", "Bypass",
"Regulator", NULL};
@@ -129,9 +129,9 @@
usecase[i].vectors[j].dst =
be32_to_cpu(vec_arr[index + 1]);
usecase[i].vectors[j].ab = (uint64_t)
- KBTOMB(be32_to_cpu(vec_arr[index + 2]));
+ KBTOB(be32_to_cpu(vec_arr[index + 2]));
usecase[i].vectors[j].ib = (uint64_t)
- KBTOMB(be32_to_cpu(vec_arr[index + 3]));
+ KBTOB(be32_to_cpu(vec_arr[index + 3]));
}
}
@@ -278,6 +278,7 @@
struct msm_bus_node_info *info;
struct device_node *child_node = NULL;
int i = 0, ret;
+ u32 temp;
for_each_child_of_node(of_node, child_node) {
i++;
@@ -352,6 +353,20 @@
of_property_read_u32(child_node, "qcom,buswidth",
&info[i].buswidth);
of_property_read_u32(child_node, "qcom,ws", &info[i].ws);
+ ret = of_property_read_u32(child_node, "qcom,thresh",
+ &temp);
+ if (!ret)
+ info[i].th = (uint64_t)KBTOB(temp);
+
+ ret = of_property_read_u32(child_node, "qcom,bimc,bw",
+ &temp);
+ if (!ret)
+ info[i].bimc_bw = (uint64_t)KBTOB(temp);
+
+ of_property_read_u32(child_node, "qcom,bimc,gp",
+ &info[i].bimc_gp);
+ of_property_read_u32(child_node, "qcom,bimc,thmp",
+ &info[i].bimc_thmp);
ret = of_property_read_string(child_node, "qcom,mode",
&sel_str);
if (ret)
@@ -366,6 +381,25 @@
info[i].mode = ret;
}
+ info[i].dual_conf =
+ of_property_read_bool(child_node, "qcom,dual-conf");
+
+ ret = of_property_read_string(child_node, "qcom,mode-thresh",
+ &sel_str);
+ if (ret)
+ info[i].mode_thresh = 0;
+ else {
+ ret = get_num(mode_sel_name, sel_str);
+ if (ret < 0) {
+ pr_err("Unknown mode :%s\n", sel_str);
+ goto err;
+ }
+
+ info[i].mode_thresh = ret;
+ MSM_BUS_DBG("AXI: THreshold mode set: %d\n",
+ info[i].mode_thresh);
+ }
+
ret = of_property_read_string(child_node, "qcom,perm-mode",
&sel_str);
if (ret)
diff --git a/arch/arm/mach-msm/pcie.c b/arch/arm/mach-msm/pcie.c
index c2ba6c1..c09b759 100644
--- a/arch/arm/mach-msm/pcie.c
+++ b/arch/arm/mach-msm/pcie.c
@@ -46,6 +46,7 @@
#define PCIE20_PARF_PHY_REFCLK 0x4C
#define PCIE20_PARF_CONFIG_BITS 0x50
+#define PCIE20_ELBI_VERSION 0x00
#define PCIE20_ELBI_SYS_CTRL 0x04
#define PCIE20_CAP 0x70
@@ -55,6 +56,8 @@
#define PCIE20_BUSNUMBERS 0x18
#define PCIE20_MEMORY_BASE_LIMIT 0x20
+#define PCIE20_PLR_AXI_MSTR_RESP_COMP_CTRL0 0x818
+#define PCIE20_PLR_AXI_MSTR_RESP_COMP_CTRL1 0x81c
#define PCIE20_PLR_IATU_VIEWPORT 0x900
#define PCIE20_PLR_IATU_CTRL1 0x904
#define PCIE20_PLR_IATU_CTRL2 0x908
@@ -478,6 +481,27 @@
msm_pcie_dev.axi_conf = NULL;
}
+static void msm_pcie_adjust_tlp_size(struct msm_pcie_dev_t *dev)
+{
+ /*
+ * Apply this fix only for device such as APQ8064 version 1.
+ * Set the Max TLP size to 2K, instead of using default of 4K
+ * to avoid a RAM problem in PCIE20 core of that version.
+ */
+ if (readl_relaxed(dev->elbi + PCIE20_ELBI_VERSION) == 0x01002107) {
+
+ /*
+ * CFG_REMOTE_RD_REQ_BRIDGE_SIZE:
+ * 5=4KB/4=2KB/3=1KB/2=512B/1=256B/0=128B
+ */
+ writel_relaxed(4, dev->pcie20 +
+ PCIE20_PLR_AXI_MSTR_RESP_COMP_CTRL0);
+
+ writel_relaxed(1, dev->pcie20 +
+ PCIE20_PLR_AXI_MSTR_RESP_COMP_CTRL1);
+ }
+};
+
static int __init msm_pcie_setup(int nr, struct pci_sys_data *sys)
{
int rc;
@@ -555,6 +579,12 @@
gpio_set_value_cansleep(dev->gpio[MSM_PCIE_GPIO_RST_N].num,
!dev->gpio[MSM_PCIE_GPIO_RST_N].on);
+ /*
+ * adjust tlp size before link comes up
+ * so there will be no transactions.
+ */
+ msm_pcie_adjust_tlp_size(dev);
+
/* enable link training */
msm_pcie_write_mask(dev->elbi + PCIE20_ELBI_SYS_CTRL, 0, BIT(0));
diff --git a/arch/arm/mach-msm/perf_trace_counters.h b/arch/arm/mach-msm/perf_trace_counters.h
index ce7e336..8f77bad 100644
--- a/arch/arm/mach-msm/perf_trace_counters.h
+++ b/arch/arm/mach-msm/perf_trace_counters.h
@@ -121,7 +121,6 @@
#endif
#undef TRACE_INCLUDE_PATH
-#define TRACE_INCLUDE_PATH .
+#define TRACE_INCLUDE_PATH ../../arch/arm/mach-msm
#define TRACE_INCLUDE_FILE perf_trace_counters
#include <trace/define_trace.h>
-
diff --git a/arch/arm/mach-msm/pil-q6v5-mss.c b/arch/arm/mach-msm/pil-q6v5-mss.c
index 5ef6638..8cf6011 100644
--- a/arch/arm/mach-msm/pil-q6v5-mss.c
+++ b/arch/arm/mach-msm/pil-q6v5-mss.c
@@ -79,6 +79,8 @@
#define EXTERNAL_BHS_STATUS BIT(4)
#define BHS_TIMEOUT_US 50
+#define STOP_ACK_TIMEOUT_MS 1000
+
struct mba_data {
void __iomem *rmb_base;
void __iomem *io_clamp_reg;
@@ -94,10 +96,12 @@
bool crash_shutdown;
bool ignore_errors;
int err_fatal_irq;
+ unsigned int stop_ack_irq;
int force_stop_gpio;
+ struct completion stop_ack;
};
-static int pbl_mba_boot_timeout_ms = 100;
+static int pbl_mba_boot_timeout_ms = 1000;
module_param(pbl_mba_boot_timeout_ms, int, S_IRUGO | S_IWUSR);
static int modem_auth_timeout_ms = 10000;
@@ -217,28 +221,13 @@
pil_q6v5_halt_axi_port(pil, drv->axi_halt_base + MSS_MODEM_HALT_BASE);
pil_q6v5_halt_axi_port(pil, drv->axi_halt_base + MSS_NC_HALT_BASE);
- /*
- * If the shutdown function is called before the reset function, clocks
- * and power will not be enabled yet. Enable them here so that register
- * writes performed during the shutdown succeed.
- */
- if (drv->is_booted == false) {
- pil_mss_power_up(drv);
- pil_mss_enable_clks(drv);
- }
- pil_q6v5_shutdown(pil);
-
- pil_mss_disable_clks(drv);
-
writel_relaxed(1, drv->restart_reg);
- /*
- * access to the cx_rail_bhs is restricted until after the gcc_mss
- * reset is asserted once the PBL starts executing.
- */
- pil_mss_power_down(drv);
-
- drv->is_booted = false;
+ if (drv->is_booted) {
+ pil_mss_disable_clks(drv);
+ pil_mss_power_down(drv);
+ drv->is_booted = false;
+ }
return 0;
}
@@ -499,16 +488,36 @@
return IRQ_HANDLED;
pr_err("Fatal error on the modem.\n");
+ subsys_set_crash_status(drv->subsys, true);
restart_modem(drv);
return IRQ_HANDLED;
}
+static irqreturn_t modem_stop_ack_intr_handler(int irq, void *dev_id)
+{
+ struct mba_data *drv = dev_id;
+ pr_info("Received stop ack interrupt from modem\n");
+ complete(&drv->stop_ack);
+ return IRQ_HANDLED;
+}
+
static int modem_shutdown(const struct subsys_desc *subsys)
{
struct mba_data *drv = subsys_to_drv(subsys);
+ unsigned long ret;
if (subsys->is_not_loadable)
return 0;
+
+ if (!subsys_get_crash_status(drv->subsys)) {
+ gpio_set_value(drv->force_stop_gpio, 1);
+ ret = wait_for_completion_timeout(&drv->stop_ack,
+ msecs_to_jiffies(STOP_ACK_TIMEOUT_MS));
+ if (!ret)
+ pr_warn("Timed out on stop ack from modem.\n");
+ gpio_set_value(drv->force_stop_gpio, 0);
+ }
+
pil_shutdown(&drv->desc);
pil_shutdown(&drv->q6->desc);
return 0;
@@ -526,6 +535,7 @@
* run concurrently with either the watchdog bite error handler or the
* SMSM callback, making it safe to unset the flag below.
*/
+ init_completion(&drv->stop_ack);
drv->ignore_errors = false;
ret = pil_boot(&drv->q6->desc);
if (ret)
@@ -540,7 +550,10 @@
{
struct mba_data *drv = subsys_to_drv(subsys);
drv->crash_shutdown = true;
- gpio_set_value(drv->force_stop_gpio, 1);
+ if (!subsys_get_crash_status(drv->subsys)) {
+ gpio_set_value(drv->force_stop_gpio, 1);
+ mdelay(STOP_ACK_TIMEOUT_MS);
+ }
}
static struct ramdump_segment smem_segments[] = {
@@ -597,6 +610,7 @@
if (drv->ignore_errors)
return IRQ_HANDLED;
pr_err("Watchdog bite received from modem software!\n");
+ subsys_set_crash_status(drv->subsys, true);
restart_modem(drv);
return IRQ_HANDLED;
}
@@ -609,6 +623,7 @@
if (desc->is_not_loadable)
return 0;
+ init_completion(&drv->stop_ack);
ret = pil_boot(&drv->q6->desc);
if (ret)
return ret;
@@ -703,6 +718,14 @@
goto err_irq;
}
+ ret = devm_request_irq(&pdev->dev, drv->stop_ack_irq,
+ modem_stop_ack_intr_handler,
+ IRQF_TRIGGER_RISING, "pil-mss", drv);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "Unable to register SMP2P stop ack handler!\n");
+ goto err_irq;
+ }
+
drv->adsp_state_notifier = subsys_notif_register_notifier("adsp",
&adsp_state_notifier_block);
if (IS_ERR(drv->adsp_state_notifier)) {
@@ -837,7 +860,7 @@
static int __devinit pil_mss_driver_probe(struct platform_device *pdev)
{
struct mba_data *drv;
- int ret, err_fatal_gpio, is_not_loadable;
+ int ret, err_fatal_gpio, is_not_loadable, stop_ack_gpio;
drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_KERNEL);
if (!drv)
@@ -864,6 +887,16 @@
if (drv->err_fatal_irq < 0)
return drv->err_fatal_irq;
+ stop_ack_gpio = of_get_named_gpio(pdev->dev.of_node,
+ "qcom,gpio-stop-ack", 0);
+ if (stop_ack_gpio < 0)
+ return stop_ack_gpio;
+
+ ret = gpio_to_irq(stop_ack_gpio);
+ if (ret < 0)
+ return ret;
+ drv->stop_ack_irq = ret;
+
/* Get the GPIO pin for writing the outbound bits: add more as needed */
drv->force_stop_gpio = of_get_named_gpio(pdev->dev.of_node,
"qcom,gpio-force-stop", 0);
diff --git a/arch/arm/mach-msm/pm-8x60.c b/arch/arm/mach-msm/pm-8x60.c
index 7792276..545723c 100644
--- a/arch/arm/mach-msm/pm-8x60.c
+++ b/arch/arm/mach-msm/pm-8x60.c
@@ -59,6 +59,7 @@
#include "timer.h"
#include "pm-boot.h"
#include <mach/event_timer.h>
+#include <linux/cpu_pm.h>
#define SCM_L2_RETENTION (0x2)
#define SCM_CMD_TERMINATE_PC (0x2)
@@ -484,6 +485,9 @@
pr_info("CPU%u: %s: notify_rpm %d\n",
cpu, __func__, (int) notify_rpm);
+ if (from_idle == true)
+ cpu_pm_enter();
+
ret = msm_spm_set_low_power_mode(
MSM_SPM_MODE_POWER_COLLAPSE, notify_rpm);
WARN_ON(ret);
@@ -516,6 +520,10 @@
ret = msm_spm_set_low_power_mode(MSM_SPM_MODE_CLOCK_GATING, false);
WARN_ON(ret);
+
+ if (from_idle == true)
+ cpu_pm_exit();
+
return collapsed;
}
diff --git a/arch/arm/mach-msm/subsystem_restart.c b/arch/arm/mach-msm/subsystem_restart.c
index 8e507ff..a5e04cd 100644
--- a/arch/arm/mach-msm/subsystem_restart.c
+++ b/arch/arm/mach-msm/subsystem_restart.c
@@ -137,6 +137,7 @@
* @dentry: debugfs directory for this device
* @do_ramdump_on_put: ramdump on subsystem_put() if true
* @err_ready: completion variable to record error ready from subsystem
+ * @crashed: indicates if subsystem has crashed
*/
struct subsys_device {
struct subsys_desc *desc;
@@ -160,6 +161,7 @@
struct miscdevice misc_dev;
char miscdevice_name[32];
struct completion err_ready;
+ bool crashed;
};
static struct subsys_device *to_subsys(struct device *d)
@@ -813,6 +815,15 @@
}
EXPORT_SYMBOL(subsystem_crashed);
+void subsys_set_crash_status(struct subsys_device *dev, bool crashed)
+{
+ dev->crashed = true;
+}
+
+bool subsys_get_crash_status(struct subsys_device *dev)
+{
+ return dev->crashed;
+}
#ifdef CONFIG_DEBUG_FS
static ssize_t subsys_debugfs_read(struct file *filp, char __user *ubuf,
size_t cnt, loff_t *ppos)
diff --git a/drivers/char/diag/diag_dci.c b/drivers/char/diag/diag_dci.c
index 9b404c6..fa0e9d7 100644
--- a/drivers/char/diag/diag_dci.c
+++ b/drivers/char/diag/diag_dci.c
@@ -375,16 +375,23 @@
int diag_send_dci_pkt(struct diag_master_table entry, unsigned char *buf,
int len, int index)
{
- int i;
- int status = 0;
+ int i, status = 0;
+ unsigned int read_len = 0;
- /* remove UID from user space pkt before sending to peripheral */
- buf = buf + 4;
- if (len > APPS_BUF_SIZE - 10) {
- pr_err("diag: dci: buffer overwrite possible since payload bigger than buf size\n");
+ /* The first 4 bytes is the uid tag and the next four bytes is
+ the minmum packet length of a request packet */
+ if (len < DCI_PKT_REQ_MIN_LEN) {
+ pr_err("diag: dci: Invalid pkt len %d in %s\n", len, __func__);
return -EIO;
}
- len = len - 4;
+ if (len > APPS_BUF_SIZE - 10) {
+ pr_err("diag: dci: Invalid payload length in %s\n", __func__);
+ return -EIO;
+ }
+ /* remove UID from user space pkt before sending to peripheral*/
+ buf = buf + sizeof(int);
+ read_len += sizeof(int);
+ len = len - sizeof(int);
mutex_lock(&driver->dci_mutex);
/* prepare DCI packet */
driver->apps_dci_buf[0] = CONTROL_CHAR; /* start */
@@ -395,7 +402,13 @@
driver->req_tracking_tbl[index].tag;
for (i = 0; i < len; i++)
driver->apps_dci_buf[i+9] = *(buf+i);
+ read_len += len;
driver->apps_dci_buf[9+len] = CONTROL_CHAR; /* end */
+ if ((read_len + 9) >= USER_SPACE_DATA) {
+ pr_err("diag: dci: Invalid length while forming dci pkt in %s",
+ __func__);
+ return -EIO;
+ }
for (i = 0; i < NUM_SMD_DCI_CHANNELS; i++) {
struct diag_smd_info *smd_info = driver->separate_cmdrsp[i] ?
@@ -449,10 +462,10 @@
{
unsigned char *temp = buf;
uint16_t subsys_cmd_code, log_code, item_num;
- int subsys_id, cmd_code, ret = -1, index = -1, found = 0, read_len = 0;
+ int subsys_id, cmd_code, ret = -1, index = -1, found = 0;
struct diag_master_table entry;
int count, set_mask, num_codes, bit_index, event_id, offset = 0, i;
- unsigned int byte_index;
+ unsigned int byte_index, read_len = 0;
uint8_t equip_id, *log_mask_ptr, *head_log_mask_ptr, byte_mask;
uint8_t *event_mask_ptr;
@@ -462,15 +475,24 @@
return DIAG_DCI_SEND_DATA_FAIL;
}
+ if (!temp) {
+ pr_err("diag: Invalid buffer in %s\n", __func__);
+ }
+
/* This is Pkt request/response transaction */
if (*(int *)temp > 0) {
+ if (len < DCI_PKT_REQ_MIN_LEN || len > USER_SPACE_DATA) {
+ pr_err("diag: dci: Invalid length %d len in %s", len,
+ __func__);
+ return -EIO;
+ }
/* enter this UID into kernel table and return index */
index = diag_register_dci_transaction(*(int *)temp);
if (index < 0) {
pr_alert("diag: registering new DCI transaction failed\n");
return DIAG_DCI_NO_REG;
}
- temp += 4;
+ temp += sizeof(int);
/*
* Check for registered peripheral and fwd pkt to
* appropriate proc
@@ -480,7 +502,12 @@
subsys_id = (int)(*(char *)temp);
temp++;
subsys_cmd_code = *(uint16_t *)temp;
- temp += 2;
+ temp += sizeof(uint16_t);
+ read_len += sizeof(int) + 2 + sizeof(uint16_t);
+ if (read_len >= USER_SPACE_DATA) {
+ pr_err("diag: dci: Invalid length in %s\n", __func__);
+ return -EIO;
+ }
pr_debug("diag: %d %d %d", cmd_code, subsys_id,
subsys_cmd_code);
for (i = 0; i < diag_max_reg; i++) {
@@ -514,6 +541,12 @@
}
}
} else if (*(int *)temp == DCI_LOG_TYPE) {
+ /* Minimum length of a log mask config is 12 + 2 bytes for
+ atleast one log code to be set or reset */
+ if (len < DCI_LOG_CON_MIN_LEN || len > USER_SPACE_DATA) {
+ pr_err("diag: dci: Invalid length in %s\n", __func__);
+ return -EIO;
+ }
/* find client id and table */
i = diag_dci_find_client_index(current->tgid);
if (i == DCI_CLIENT_INDEX_INVALID) {
@@ -521,21 +554,33 @@
return ret;
}
/* Extract each log code and put in client table */
- temp += 4;
- read_len += 4;
+ temp += sizeof(int);
+ read_len += sizeof(int);
set_mask = *(int *)temp;
- temp += 4;
- read_len += 4;
+ temp += sizeof(int);
+ read_len += sizeof(int);
num_codes = *(int *)temp;
- temp += 4;
- read_len += 4;
+ temp += sizeof(int);
+ read_len += sizeof(int);
+
+ if (num_codes == 0 || (num_codes >= (USER_SPACE_DATA - 8)/2)) {
+ pr_err("diag: dci: Invalid number of log codes %d\n",
+ num_codes);
+ return -EIO;
+ }
head_log_mask_ptr = driver->dci_client_tbl[i].dci_log_mask;
+ if (!head_log_mask_ptr) {
+ pr_err("diag: dci: Invalid Log mask pointer in %s\n",
+ __func__);
+ return -ENOMEM;
+ }
pr_debug("diag: head of dci log mask %p\n", head_log_mask_ptr);
count = 0; /* iterator for extracting log codes */
while (count < num_codes) {
if (read_len >= USER_SPACE_DATA) {
- pr_err("diag: dci: Log type, possible buffer overflow\n");
+ pr_err("diag: dci: Invalid length for log type in %s",
+ __func__);
return -EIO;
}
log_code = *(uint16_t *)temp;
@@ -589,6 +634,12 @@
/* send updated mask to peripherals */
ret = diag_send_dci_log_mask(driver->smd_cntl[MODEM_DATA].ch);
} else if (*(int *)temp == DCI_EVENT_TYPE) {
+ /* Minimum length of a event mask config is 12 + 4 bytes for
+ atleast one event id to be set or reset. */
+ if (len < DCI_EVENT_CON_MIN_LEN || len > USER_SPACE_DATA) {
+ pr_err("diag: dci: Invalid length in %s\n", __func__);
+ return -EIO;
+ }
/* find client id and table */
i = diag_dci_find_client_index(current->tgid);
if (i == DCI_CLIENT_INDEX_INVALID) {
@@ -596,21 +647,36 @@
return ret;
}
/* Extract each log code and put in client table */
- temp += 4;
- read_len += 4;
+ temp += sizeof(int);
+ read_len += sizeof(int);
set_mask = *(int *)temp;
- temp += 4;
- read_len += 4;
+ temp += sizeof(int);
+ read_len += sizeof(int);
num_codes = *(int *)temp;
- temp += 4;
- read_len += 4;
+ temp += sizeof(int);
+ read_len += sizeof(int);
+
+ /* Check for positive number of event ids. Also, the number of
+ event ids should fit in the buffer along with set_mask and
+ num_codes which are 4 bytes each */
+ if (num_codes == 0 || (num_codes >= (USER_SPACE_DATA - 8)/2)) {
+ pr_err("diag: dci: Invalid number of event ids %d\n",
+ num_codes);
+ return -EIO;
+ }
event_mask_ptr = driver->dci_client_tbl[i].dci_event_mask;
+ if (!event_mask_ptr) {
+ pr_err("diag: dci: Invalid event mask pointer in %s\n",
+ __func__);
+ return -ENOMEM;
+ }
pr_debug("diag: head of dci event mask %p\n", event_mask_ptr);
count = 0; /* iterator for extracting log codes */
while (count < num_codes) {
if (read_len >= USER_SPACE_DATA) {
- pr_err("diag: dci: Event type, possible buffer overflow\n");
+ pr_err("diag: dci: Invalid length for event type in %s",
+ __func__);
return -EIO;
}
event_id = *(int *)temp;
diff --git a/drivers/char/diag/diag_dci.h b/drivers/char/diag/diag_dci.h
index 4dc1bfc..d530de9 100644
--- a/drivers/char/diag/diag_dci.h
+++ b/drivers/char/diag/diag_dci.h
@@ -24,6 +24,9 @@
#define DISABLE_LOG_MASK 0
#define MAX_EVENT_SIZE 512
#define DCI_CLIENT_INDEX_INVALID -1
+#define DCI_PKT_REQ_MIN_LEN 8
+#define DCI_LOG_CON_MIN_LEN 14
+#define DCI_EVENT_CON_MIN_LEN 16
/* 16 log code categories, each has:
diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c
index 79f7174..fda64e5 100644
--- a/drivers/cpufreq/cpufreq_ondemand.c
+++ b/drivers/cpufreq/cpufreq_ondemand.c
@@ -112,7 +112,7 @@
static unsigned int dbs_enable; /* number of CPUs using this policy */
/*
- * dbs_mutex protects dbs_enable in governor start/stop.
+ * dbs_mutex protects dbs_enable and dbs_info during start/stop.
*/
static DEFINE_MUTEX(dbs_mutex);
@@ -585,6 +585,10 @@
POWERSAVE_BIAS_MINLEVEL));
dbs_tuners_ins.powersave_bias = input;
+
+ mutex_lock(&dbs_mutex);
+ get_online_cpus();
+
if (!bypass) {
if (reenable_timer) {
/* reinstate dbs timer */
@@ -652,6 +656,9 @@
}
}
+ put_online_cpus();
+ mutex_unlock(&dbs_mutex);
+
return count;
}
diff --git a/drivers/crypto/msm/qce50.c b/drivers/crypto/msm/qce50.c
index ca56317..75d0d39 100644
--- a/drivers/crypto/msm/qce50.c
+++ b/drivers/crypto/msm/qce50.c
@@ -460,9 +460,6 @@
else
key_size = creq->encklen;
- _byte_stream_to_net_words(enckey32, creq->enckey, key_size);
- enck_size_in_word = key_size/sizeof(uint32_t);
-
pce = cmdlistinfo->go_proc;
if ((creq->flags & QCRYPTO_CTX_USE_HW_KEY) == QCRYPTO_CTX_USE_HW_KEY) {
use_hw_key = true;
@@ -478,6 +475,10 @@
else
pce->addr = (uint32_t)(CRYPTO_GOPROC_REG +
pce_dev->phy_iobase);
+ if ((use_pipe_key == false) && (use_hw_key == false)) {
+ _byte_stream_to_net_words(enckey32, creq->enckey, key_size);
+ enck_size_in_word = key_size/sizeof(uint32_t);
+ }
if ((creq->op == QCE_REQ_AEAD) && (creq->mode == QCE_MODE_CCM)) {
uint32_t authklen32 = creq->encklen/sizeof(uint32_t);
@@ -913,9 +914,6 @@
else
key_size = creq->encklen;
- _byte_stream_to_net_words(enckey32, creq->enckey, key_size);
-
- enck_size_in_word = key_size/sizeof(uint32_t);
if ((creq->flags & QCRYPTO_CTX_USE_HW_KEY) == QCRYPTO_CTX_USE_HW_KEY) {
use_hw_key = true;
} else {
@@ -923,7 +921,10 @@
QCRYPTO_CTX_USE_PIPE_KEY)
use_pipe_key = true;
}
-
+ if ((use_pipe_key == false) && (use_hw_key == false)) {
+ _byte_stream_to_net_words(enckey32, creq->enckey, key_size);
+ enck_size_in_word = key_size/sizeof(uint32_t);
+ }
if ((creq->op == QCE_REQ_AEAD) && (creq->mode == QCE_MODE_CCM)) {
uint32_t authklen32 = creq->encklen/sizeof(uint32_t);
uint32_t noncelen32 = MAX_NONCE/sizeof(uint32_t);
diff --git a/drivers/crypto/msm/qcrypto.c b/drivers/crypto/msm/qcrypto.c
index 3601365..39b9a46 100644
--- a/drivers/crypto/msm/qcrypto.c
+++ b/drivers/crypto/msm/qcrypto.c
@@ -774,11 +774,21 @@
struct qcrypto_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
struct crypto_priv *cp = ctx->cp;
+ if ((ctx->flags & QCRYPTO_CTX_USE_HW_KEY) == QCRYPTO_CTX_USE_HW_KEY)
+ return 0;
+
if (_qcrypto_check_aes_keylen(cipher, cp, len)) {
return -EINVAL;
} else {
ctx->enc_key_len = len;
- memcpy(ctx->enc_key, key, len);
+ if (!(ctx->flags & QCRYPTO_CTX_USE_PIPE_KEY)) {
+ if (key != NULL) {
+ memcpy(ctx->enc_key, key, len);
+ } else {
+ pr_err("%s Inavlid key pointer\n", __func__);
+ return -EINVAL;
+ }
+ }
}
return 0;
};
@@ -790,12 +800,20 @@
struct qcrypto_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
struct crypto_priv *cp = ctx->cp;
-
+ if ((ctx->flags & QCRYPTO_CTX_USE_HW_KEY) == QCRYPTO_CTX_USE_HW_KEY)
+ return 0;
if (_qcrypto_check_aes_keylen(cipher, cp, len/2)) {
return -EINVAL;
} else {
ctx->enc_key_len = len;
- memcpy(ctx->enc_key, key, len);
+ if (!(ctx->flags & QCRYPTO_CTX_USE_PIPE_KEY)) {
+ if (key != NULL) {
+ memcpy(ctx->enc_key, key, len);
+ } else {
+ pr_err("%s Inavlid key pointer\n", __func__);
+ return -EINVAL;
+ }
+ }
}
return 0;
};
@@ -808,6 +826,12 @@
u32 tmp[DES_EXPKEY_WORDS];
int ret = des_ekey(tmp, key);
+ if ((ctx->flags & QCRYPTO_CTX_USE_HW_KEY) == QCRYPTO_CTX_USE_HW_KEY) {
+ pr_err("%s HW KEY usage not supported for DES algorithm\n",
+ __func__);
+ return 0;
+ };
+
if (len != DES_KEY_SIZE) {
crypto_ablkcipher_set_flags(cipher, CRYPTO_TFM_RES_BAD_KEY_LEN);
return -EINVAL;
@@ -819,7 +843,14 @@
}
ctx->enc_key_len = len;
- memcpy(ctx->enc_key, key, len);
+ if (!(ctx->flags & QCRYPTO_CTX_USE_PIPE_KEY)) {
+ if (key != NULL) {
+ memcpy(ctx->enc_key, key, len);
+ } else {
+ pr_err("%s Inavlid key pointer\n", __func__);
+ return -EINVAL;
+ }
+ }
return 0;
};
@@ -829,12 +860,24 @@
struct crypto_tfm *tfm = crypto_ablkcipher_tfm(cipher);
struct qcrypto_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
+ if ((ctx->flags & QCRYPTO_CTX_USE_HW_KEY) == QCRYPTO_CTX_USE_HW_KEY) {
+ pr_err("%s HW KEY usage not supported for 3DES algorithm\n",
+ __func__);
+ return 0;
+ };
if (len != DES3_EDE_KEY_SIZE) {
crypto_ablkcipher_set_flags(cipher, CRYPTO_TFM_RES_BAD_KEY_LEN);
return -EINVAL;
};
ctx->enc_key_len = len;
- memcpy(ctx->enc_key, key, len);
+ if (!(ctx->flags & QCRYPTO_CTX_USE_PIPE_KEY)) {
+ if (key != NULL) {
+ memcpy(ctx->enc_key, key, len);
+ } else {
+ pr_err("%s Inavlid key pointer\n", __func__);
+ return -EINVAL;
+ }
+ }
return 0;
};
diff --git a/drivers/gpu/msm/kgsl_sync.c b/drivers/gpu/msm/kgsl_sync.c
index aad8ef1..2f67405 100644
--- a/drivers/gpu/msm/kgsl_sync.c
+++ b/drivers/gpu/msm/kgsl_sync.c
@@ -12,9 +12,12 @@
*/
#include <linux/file.h>
+#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
+#include <asm/current.h>
+
#include "kgsl_sync.h"
struct sync_pt *kgsl_sync_pt_create(struct sync_timeline *timeline,
@@ -179,24 +182,67 @@
return ret;
}
+static unsigned int kgsl_sync_get_timestamp(
+ struct kgsl_sync_timeline *ktimeline, enum kgsl_timestamp_type type)
+{
+ struct kgsl_context *context = idr_find(&ktimeline->device->context_idr,
+ ktimeline->context_id);
+ if (context == NULL)
+ return 0;
+
+ return kgsl_readtimestamp(ktimeline->device, context, type);
+}
+
+static void kgsl_sync_timeline_value_str(struct sync_timeline *sync_timeline,
+ char *str, int size)
+{
+ struct kgsl_sync_timeline *ktimeline =
+ (struct kgsl_sync_timeline *) sync_timeline;
+ unsigned int timestamp_retired = kgsl_sync_get_timestamp(ktimeline,
+ KGSL_TIMESTAMP_RETIRED);
+ snprintf(str, size, "%u retired:%u", ktimeline->last_timestamp,
+ timestamp_retired);
+}
+
+static void kgsl_sync_pt_value_str(struct sync_pt *sync_pt,
+ char *str, int size)
+{
+ struct kgsl_sync_pt *kpt = (struct kgsl_sync_pt *) sync_pt;
+ snprintf(str, size, "%u", kpt->timestamp);
+}
+
static const struct sync_timeline_ops kgsl_sync_timeline_ops = {
.driver_name = "kgsl-timeline",
.dup = kgsl_sync_pt_dup,
.has_signaled = kgsl_sync_pt_has_signaled,
.compare = kgsl_sync_pt_compare,
+ .timeline_value_str = kgsl_sync_timeline_value_str,
+ .pt_value_str = kgsl_sync_pt_value_str,
};
int kgsl_sync_timeline_create(struct kgsl_context *context)
{
struct kgsl_sync_timeline *ktimeline;
+ /* Generate a name which includes the thread name, thread id, process
+ * name, process id, and context id. This makes it possible to
+ * identify the context of a timeline in the sync dump. */
+ char ktimeline_name[sizeof(context->timeline->name)] = {};
+ snprintf(ktimeline_name, sizeof(ktimeline_name),
+ "%s_%.15s(%d)-%.15s(%d)-%d",
+ context->dev_priv->device->name,
+ current->group_leader->comm, current->group_leader->pid,
+ current->comm, current->pid, context->id);
+
context->timeline = sync_timeline_create(&kgsl_sync_timeline_ops,
- (int) sizeof(struct kgsl_sync_timeline), "kgsl-timeline");
+ (int) sizeof(struct kgsl_sync_timeline), ktimeline_name);
if (context->timeline == NULL)
return -EINVAL;
ktimeline = (struct kgsl_sync_timeline *) context->timeline;
ktimeline->last_timestamp = 0;
+ ktimeline->device = context->dev_priv->device;
+ ktimeline->context_id = context->id;
return 0;
}
diff --git a/drivers/gpu/msm/kgsl_sync.h b/drivers/gpu/msm/kgsl_sync.h
index 06b3ad0..63adf06 100644
--- a/drivers/gpu/msm/kgsl_sync.h
+++ b/drivers/gpu/msm/kgsl_sync.h
@@ -19,6 +19,8 @@
struct kgsl_sync_timeline {
struct sync_timeline timeline;
unsigned int last_timestamp;
+ struct kgsl_device *device;
+ u32 context_id;
};
struct kgsl_sync_pt {
diff --git a/drivers/gud/mobicore_driver/build_tag.h b/drivers/gud/mobicore_driver/build_tag.h
index 4abd003..2a7772e 100644
--- a/drivers/gud/mobicore_driver/build_tag.h
+++ b/drivers/gud/mobicore_driver/build_tag.h
@@ -26,4 +26,4 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#define MOBICORE_COMPONENT_BUILD_TAG \
- "*** GC_MSM8960_Release_V016 ###"
+ "*** GC_MSM8960_Release_V019 ###"
diff --git a/drivers/gud/mobicore_driver/main.c b/drivers/gud/mobicore_driver/main.c
index a2b3ad7..b5cb1a6 100644
--- a/drivers/gud/mobicore_driver/main.c
+++ b/drivers/gud/mobicore_driver/main.c
@@ -29,6 +29,7 @@
#include <linux/mman.h>
#include <linux/completion.h>
#include <linux/fdtable.h>
+#include <linux/cdev.h>
#include <net/net_namespace.h>
#include <net/sock.h>
#include <net/tcp_states.h>
@@ -56,6 +57,15 @@
struct device *mcd = &mcd_debug_subname;
+/* We need 2 devices for admin and user interface*/
+#define MC_DEV_MAX 2
+
+/* Need to discover a chrdev region for the driver */
+static dev_t mc_dev_admin, mc_dev_user;
+struct cdev mc_admin_cdev, mc_user_cdev;
+/* Device class for the driver assigned major */
+static struct class *mc_device_class;
+
#ifndef FMODE_PATH
#define FMODE_PATH 0x0
#endif
@@ -1205,13 +1215,6 @@
.read = mc_fd_read,
};
-static struct miscdevice mc_admin_device = {
- .name = MC_ADMIN_DEVNODE,
- .mode = (S_IRWXU),
- .minor = 253,
- .fops = &mc_admin_fops,
-};
-
/* function table structure of this device driver. */
static const struct file_operations mc_user_fops = {
.owner = THIS_MODULE,
@@ -1221,30 +1224,80 @@
.mmap = mc_fd_mmap,
};
-static struct miscdevice mc_user_device = {
- .name = MC_USER_DEVNODE,
- .mode = (S_IRWXU | S_IRWXG | S_IRWXO),
- .minor = 254,
- .fops = &mc_user_fops,
-};
+static int create_devices(void)
+{
+ int ret = 0;
+
+ cdev_init(&mc_admin_cdev, &mc_admin_fops);
+ cdev_init(&mc_user_cdev, &mc_user_fops);
+
+ mc_device_class = class_create(THIS_MODULE, "mobicore");
+ if (IS_ERR(mc_device_class)) {
+ MCDRV_DBG_ERROR(mcd, "failed to create device class");
+ ret = PTR_ERR(mc_device_class);
+ goto out;
+ }
+
+ ret = alloc_chrdev_region(&mc_dev_admin, 0, MC_DEV_MAX, "mobicore");
+ if (ret < 0) {
+ MCDRV_DBG_ERROR(mcd, "failed to allocate char dev region\n");
+ goto error;
+ }
+ mc_dev_user = MKDEV(MAJOR(mc_dev_admin), 1);
+
+ MCDRV_DBG_VERBOSE(mcd, "%s: dev %d", "mobicore", MAJOR(mc_dev_region));
+
+ /* First the ADMIN node */
+ ret = cdev_add(&mc_admin_cdev, mc_dev_admin, 1);
+ if (ret != 0) {
+ MCDRV_DBG_ERROR(mcd, "admin device register failed\n");
+ goto error;
+ }
+ mc_admin_cdev.owner = THIS_MODULE;
+ device_create(mc_device_class, NULL, mc_dev_admin, NULL,
+ MC_ADMIN_DEVNODE);
+
+ /* Then the user node */
+
+ ret = cdev_add(&mc_user_cdev, mc_dev_user, 1);
+ if (ret != 0) {
+ MCDRV_DBG_ERROR(mcd, "user device register failed\n");
+ goto error_unregister;
+ }
+ mc_user_cdev.owner = THIS_MODULE;
+ device_create(mc_device_class, NULL, mc_dev_user, NULL,
+ MC_USER_DEVNODE);
+
+ goto out;
+error_unregister:
+ device_destroy(mc_device_class, mc_dev_admin);
+ device_destroy(mc_device_class, mc_dev_user);
+
+ cdev_del(&mc_admin_cdev);
+ cdev_del(&mc_user_cdev);
+ unregister_chrdev_region(mc_dev_admin, MC_DEV_MAX);
+error:
+ class_destroy(mc_device_class);
+out:
+ return ret;
+}
/*
* This function is called the kernel during startup or by a insmod command.
- * This device is installed and registered as miscdevice, then interrupt and
+ * This device is installed and registered as cdev, then interrupt and
* queue handling is set up
*/
static int __init mobicore_init(void)
{
int ret = 0;
-
dev_set_name(mcd, "mcd");
- MCDRV_DBG(mcd, "enter (Build " __TIMESTAMP__ ")\n");
- MCDRV_DBG(mcd, "mcDrvModuleApi version is %i.%i\n",
- MCDRVMODULEAPI_VERSION_MAJOR,
- MCDRVMODULEAPI_VERSION_MINOR);
+ dev_info(mcd, "MobiCore Driver, Build: " __TIMESTAMP__ "\n");
+ dev_info(mcd, "MobiCore mcDrvModuleApi version is %i.%i\n",
+ MCDRVMODULEAPI_VERSION_MAJOR,
+ MCDRVMODULEAPI_VERSION_MINOR);
#ifdef MOBICORE_COMPONENT_BUILD_TAG
- MCDRV_DBG(mcd, "%s\n", MOBICORE_COMPONENT_BUILD_TAG);
+ dev_info(mcd, "MobiCore %s\n", MOBICORE_COMPONENT_BUILD_TAG);
#endif
/* Hardware does not support ARM TrustZone -> Cannot continue! */
if (!has_security_extensions()) {
@@ -1264,6 +1317,10 @@
goto error;
init_completion(&ctx.isr_comp);
+
+ /* initialize event counter for signaling of an IRQ to zero */
+ atomic_set(&ctx.isr_counter, 0);
+
/* set up S-SIQ interrupt handler */
ret = request_irq(MC_INTR_SSIQ, mc_ssiq_isr, IRQF_TRIGGER_RISING,
MC_ADMIN_DEVNODE, &ctx);
@@ -1280,20 +1337,9 @@
}
#endif
- ret = misc_register(&mc_admin_device);
- if (ret != 0) {
- MCDRV_DBG_ERROR(mcd, "admin device register failed\n");
- goto free_isr;
- }
-
- ret = misc_register(&mc_user_device);
- if (ret != 0) {
- MCDRV_DBG_ERROR(mcd, "user device register failed\n");
- goto free_admin;
- }
-
- /* initialize event counter for signaling of an IRQ to zero */
- atomic_set(&ctx.isr_counter, 0);
+ ret = create_devices();
+ if (ret != 0)
+ goto free_pm;
ret = mc_init_l2_tables();
@@ -1315,10 +1361,12 @@
MCDRV_DBG(mcd, "initialized\n");
return 0;
-free_admin:
- misc_deregister(&mc_admin_device);
+free_pm:
+#ifdef MC_PM_RUNTIME
+ mc_pm_free();
free_isr:
free_irq(MC_INTR_SSIQ, &ctx);
+#endif
err_req_irq:
mc_fastcall_destroy();
error:
@@ -1341,10 +1389,12 @@
mc_pm_free();
#endif
- free_irq(MC_INTR_SSIQ, &ctx);
+ device_destroy(mc_device_class, mc_dev_admin);
+ device_destroy(mc_device_class, mc_dev_user);
+ class_destroy(mc_device_class);
+ unregister_chrdev_region(mc_dev_admin, MC_DEV_MAX);
- misc_deregister(&mc_admin_device);
- misc_deregister(&mc_user_device);
+ free_irq(MC_INTR_SSIQ, &ctx);
mc_fastcall_destroy();
@@ -1358,4 +1408,3 @@
MODULE_AUTHOR("Trustonic Limited");
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("MobiCore driver");
-
diff --git a/drivers/leds/leds-qpnp.c b/drivers/leds/leds-qpnp.c
index 9101a3d..2ea7128 100644
--- a/drivers/leds/leds-qpnp.c
+++ b/drivers/leds/leds-qpnp.c
@@ -23,6 +23,7 @@
#include <linux/spmi.h>
#include <linux/qpnp/pwm.h>
#include <linux/workqueue.h>
+#include <linux/regulator/consumer.h>
#define WLED_MOD_EN_REG(base, n) (base + 0x60 + n*0x10)
#define WLED_IDAC_DLY_REG(base, n) (WLED_MOD_EN_REG(base, n) + 0x01)
@@ -362,6 +363,9 @@
* @second_addr - address of secondary flash to be written
* @safety_timer - enable safety timer or watchdog timer
* @torch_enable - enable flash LED torch mode
+ * @regulator_get - regulator attached or not
+ * @flash_on - flash status, on or off
+ * @flash_boost_reg - boost regulator for flash
*/
struct flash_config_data {
u8 current_prgm;
@@ -376,6 +380,9 @@
u16 second_addr;
bool safety_timer;
bool torch_enable;
+ bool regulator_get;
+ bool flash_on;
+ struct regulator *flash_boost_reg;
};
/**
@@ -935,8 +942,9 @@
static void qpnp_led_set(struct led_classdev *led_cdev,
enum led_brightness value)
{
- int rc;
+ int rc, i;
struct qpnp_led_data *led;
+ struct qpnp_led_data *led_array;
led = container_of(led_cdev, struct qpnp_led_data, cdev);
if (value < LED_OFF || value > led->cdev.max_brightness) {
@@ -944,6 +952,33 @@
return;
}
+ if (led->id == QPNP_ID_FLASH1_LED0 || led->id == QPNP_ID_FLASH1_LED1) {
+ if (!led->flash_cfg->flash_on && value > 0) {
+ led_array = dev_get_drvdata(&led->spmi_dev->dev);
+ if (!led_array) {
+ dev_err(&led->spmi_dev->dev,
+ "Unable to unable to get array\n");
+ return;
+ }
+
+ for (i = 0; i < led->num_leds; i++) {
+ if (led_array[i].flash_cfg->regulator_get) {
+ rc = regulator_enable(led_array[i].\
+ flash_cfg->\
+ flash_boost_reg);
+ if (rc) {
+ dev_err(&led->spmi_dev->dev,
+ "Regulator enable" \
+ "failed(%d)\n",
+ rc);
+ return;
+ }
+ }
+ }
+ led->flash_cfg->flash_on = true;
+ }
+ }
+
spin_lock(&led->lock);
led->cdev.brightness = value;
@@ -986,6 +1021,32 @@
break;
}
spin_unlock(&led->lock);
+
+ if (led->id == QPNP_ID_FLASH1_LED0 || led->id == QPNP_ID_FLASH1_LED1) {
+ if (led->flash_cfg->flash_on && !value) {
+ led_array = dev_get_drvdata(&led->spmi_dev->dev);
+ if (!led_array) {
+ dev_err(&led->spmi_dev->dev,
+ "Unable to get LED array\n");
+ return;
+ }
+
+ for (i = 0; i < led->num_leds; i++) {
+ if (led_array[i].flash_cfg->regulator_get) {
+ rc = regulator_disable(led_array[i]\
+ .flash_cfg->flash_boost_reg);
+ if (rc) {
+ dev_err(&led->spmi_dev->dev,
+ "Unable to disable" \
+ " regulator(%d)\n",
+ rc);
+ return;
+ }
+ }
+ }
+ led->flash_cfg->flash_on = false;
+ }
+ }
}
static int __devinit qpnp_led_set_max_brightness(struct qpnp_led_data *led)
@@ -1239,6 +1300,8 @@
{
int rc;
+ led->flash_cfg->flash_on = false;
+
rc = qpnp_led_masked_write(led,
FLASH_LED_STROBE_CTRL(led->base),
FLASH_STROBE_MASK, FLASH_DISABLE_ALL);
@@ -1655,7 +1718,7 @@
}
static int __devinit qpnp_get_config_flash(struct qpnp_led_data *led,
- struct device_node *node)
+ struct device_node *node, bool *reg_set)
{
int rc;
u32 val;
@@ -1672,11 +1735,39 @@
led->flash_cfg->current_addr = FLASH_LED_0_CURR(led->base);
led->flash_cfg->second_addr = FLASH_LED_1_CURR(led->base);
led->flash_cfg->trigger_flash = FLASH_LED_0_OUTPUT;
+ if (!*reg_set) {
+ led->flash_cfg->flash_boost_reg =
+ regulator_get(&led->spmi_dev->dev,
+ "flash_boost");
+ if (IS_ERR(led->flash_cfg->flash_boost_reg)) {
+ rc = PTR_ERR(led->flash_cfg->flash_boost_reg);
+ dev_err(&led->spmi_dev->dev,
+ "Regulator get failed(%d)\n", rc);
+ return rc;
+ }
+ led->flash_cfg->regulator_get = true;
+ *reg_set = true;
+ } else
+ led->flash_cfg->regulator_get = false;
} else if (led->id == QPNP_ID_FLASH1_LED1) {
led->flash_cfg->enable_module = FLASH_ENABLE_ALL;
led->flash_cfg->current_addr = FLASH_LED_1_CURR(led->base);
led->flash_cfg->second_addr = FLASH_LED_0_CURR(led->base);
led->flash_cfg->trigger_flash = FLASH_LED_1_OUTPUT;
+ if (!*reg_set) {
+ led->flash_cfg->flash_boost_reg =
+ regulator_get(&led->spmi_dev->dev,
+ "flash_boost");
+ if (IS_ERR(led->flash_cfg->flash_boost_reg)) {
+ rc = PTR_ERR(led->flash_cfg->flash_boost_reg);
+ dev_err(&led->spmi_dev->dev,
+ "Regulator get failed(%d)\n", rc);
+ return rc;
+ }
+ led->flash_cfg->regulator_get = true;
+ *reg_set = true;
+ } else
+ led->flash_cfg->regulator_get = false;
} else {
dev_err(&led->spmi_dev->dev, "Unknown flash LED name given\n");
return -EINVAL;
@@ -2038,6 +2129,7 @@
struct device_node *node, *temp;
int rc, i, num_leds = 0, parsed_leds = 0;
const char *led_label;
+ bool regulator_probe = false;
node = spmi->dev.of_node;
if (node == NULL)
@@ -2120,7 +2212,9 @@
}
} else if (strncmp(led_label, "flash", sizeof("flash"))
== 0) {
- rc = qpnp_get_config_flash(led, temp);
+ if (!of_find_property(node, "flash_boost-supply", NULL))
+ regulator_probe = true;
+ rc = qpnp_get_config_flash(led, temp, ®ulator_probe);
if (rc < 0) {
dev_err(&led->spmi_dev->dev,
"Unable to read flash config data\n");
@@ -2182,13 +2276,12 @@
/* configure default state */
if (led->default_on) {
led->cdev.brightness = led->cdev.max_brightness;
+ qpnp_led_set(&led->cdev, led->cdev.brightness);
if (led->turn_off_delay_ms > 0)
qpnp_led_turn_off(led);
} else
led->cdev.brightness = LED_OFF;
- qpnp_led_set(&led->cdev, led->cdev.brightness);
-
parsed_leds++;
}
dev_set_drvdata(&spmi->dev, led_array);
@@ -2212,6 +2305,9 @@
break;
case QPNP_ID_FLASH1_LED0:
case QPNP_ID_FLASH1_LED1:
+ if (led_array[i].flash_cfg->regulator_get)
+ regulator_put(led_array[i].flash_cfg-> \
+ flash_boost_reg);
sysfs_remove_group(&led_array[i].cdev.dev->kobj,
&led_attr_group);
break;
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c b/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c
index 74a920c..2a2656f 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c
@@ -420,7 +420,7 @@
static int msm_isp_buf_done(struct msm_isp_buf_mgr *buf_mgr,
uint32_t bufq_handle, uint32_t buf_index,
- struct timeval *tv, uint32_t frame_id)
+ struct timeval *tv, uint32_t frame_id, uint32_t output_format)
{
int rc = -1;
unsigned long flags;
@@ -467,6 +467,7 @@
} else {
buf_info->vb2_buf->v4l2_buf.timestamp = *tv;
buf_info->vb2_buf->v4l2_buf.sequence = frame_id;
+ buf_info->vb2_buf->v4l2_buf.reserved = output_format;
buf_mgr->vb2_ops->buf_done(buf_info->vb2_buf,
bufq->session_id, bufq->stream_id);
}
@@ -577,7 +578,7 @@
else
rc = msm_isp_buf_done(buf_mgr,
info->handle, info->buf_idx,
- buf_info->tv, buf_info->frame_id);
+ buf_info->tv, buf_info->frame_id, 0);
}
} else {
bufq = msm_isp_get_bufq(buf_mgr, info->handle);
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.h b/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.h
index fda1a57..6d6ff9d 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.h
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.h
@@ -108,7 +108,7 @@
int (*buf_done) (struct msm_isp_buf_mgr *buf_mgr,
uint32_t bufq_handle, uint32_t buf_index,
- struct timeval *tv, uint32_t frame_id);
+ struct timeval *tv, uint32_t frame_id, uint32_t output_format);
int (*buf_divert) (struct msm_isp_buf_mgr *buf_mgr,
uint32_t bufq_handle, uint32_t buf_index,
struct timeval *tv, uint32_t frame_id);
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp.h b/drivers/media/platform/msm/camera_v2/isp/msm_isp.h
index 6de6e74..cf03c7f 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp.h
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp.h
@@ -207,12 +207,21 @@
AVALIABLE,
INACTIVE,
ACTIVE,
- PAUSE,
+ PAUSED,
START_PENDING,
STOP_PENDING,
+ PAUSE_PENDING,
+ RESUME_PENDING,
STARTING,
STOPPING,
- PAUSE_PENDING,
+ PAUSING,
+ RESUMING,
+};
+
+enum msm_vfe_axi_cfg_update_state {
+ NO_AXI_CFG_UPDATE,
+ APPLYING_UPDATE_RESUME,
+ UPDATE_REQUESTED,
};
#define VFE_NO_DROP 0xFFFFFFFF
@@ -251,6 +260,7 @@
uint32_t init_frame_drop;
uint32_t burst_frame_count;/*number of sof before burst stop*/
uint8_t framedrop_update;
+ spinlock_t lock;
/*Bandwidth calculation info*/
uint32_t max_width;
@@ -263,6 +273,7 @@
uint32_t runtime_burst_frame_count;/*number of sof before burst stop*/
uint32_t runtime_num_burst_capture;
uint8_t runtime_framedrop_update;
+ uint32_t runtime_output_format;
};
struct msm_vfe_axi_composite_info {
@@ -298,6 +309,7 @@
composite_info[MAX_NUM_COMPOSITE_MASK];
uint8_t num_used_composite_mask;
uint32_t stream_update;
+ atomic_t axi_cfg_update;
enum msm_isp_camif_update_state pipeline_update;
struct msm_vfe_src_info src_info[VFE_SRC_MAX];
uint16_t stream_handle_cnt;
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp32.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp32.c
index 3a94af3..73b4f4d 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp32.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp32.c
@@ -638,6 +638,7 @@
} else {
switch (stream_info->output_format) {
case V4L2_PIX_FMT_NV12:
+ case V4L2_PIX_FMT_NV14:
case V4L2_PIX_FMT_NV16:
xbar_cfg |= 0x3 << 3; /*PAIR_STREAM_SWAP_CTRL*/
break;
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c
index 7bf8511..1f9afd8 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c
@@ -531,6 +531,8 @@
msm_isp_axi_stream_update(vfe_dev);
if (atomic_read(&vfe_dev->stats_data.stats_update))
msm_isp_stats_stream_update(vfe_dev);
+ if (atomic_read(&vfe_dev->axi_data.axi_cfg_update))
+ msm_isp_axi_cfg_update(vfe_dev);
msm_isp_update_framedrop_reg(vfe_dev);
msm_isp_update_error_frame_count(vfe_dev);
@@ -895,6 +897,7 @@
} else {
switch (stream_info->output_format) {
case V4L2_PIX_FMT_NV12:
+ case V4L2_PIX_FMT_NV14:
case V4L2_PIX_FMT_NV16:
xbar_cfg |= 0x3 << 4; /*PAIR_STREAM_SWAP_CTRL*/
break;
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
index e3d036f6..f804595 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
@@ -43,6 +43,7 @@
memset(&axi_data->stream_info[i], 0,
sizeof(struct msm_vfe_axi_stream));
+ spin_lock_init(&axi_data->stream_info[i].lock);
axi_data->stream_info[i].session_id = stream_cfg_cmd->session_id;
axi_data->stream_info[i].stream_id = stream_cfg_cmd->stream_id;
axi_data->stream_info[i].buf_divert = stream_cfg_cmd->buf_divert;
@@ -101,6 +102,8 @@
break;
case V4L2_PIX_FMT_NV12:
case V4L2_PIX_FMT_NV21:
+ case V4L2_PIX_FMT_NV14:
+ case V4L2_PIX_FMT_NV41:
case V4L2_PIX_FMT_NV16:
case V4L2_PIX_FMT_NV61:
stream_info->num_planes = 2;
@@ -142,6 +145,7 @@
}
stream_info->output_format = stream_cfg_cmd->output_format;
+ stream_info->runtime_output_format = stream_info->output_format;
stream_info->stream_src = stream_cfg_cmd->stream_src;
stream_info->frame_based = stream_cfg_cmd->frame_base;
return 0;
@@ -197,6 +201,15 @@
size = plane_cfg[plane_idx].output_height *
plane_cfg[plane_idx].output_width / 2;
break;
+ case V4L2_PIX_FMT_NV14:
+ case V4L2_PIX_FMT_NV41:
+ if (plane_cfg[plane_idx].output_plane_format == Y_PLANE)
+ size = plane_cfg[plane_idx].output_height *
+ plane_cfg[plane_idx].output_width;
+ else
+ size = plane_cfg[plane_idx].output_height *
+ plane_cfg[plane_idx].output_width / 8;
+ break;
case V4L2_PIX_FMT_NV16:
case V4L2_PIX_FMT_NV61:
size = plane_cfg[plane_idx].output_height *
@@ -278,19 +291,32 @@
struct msm_vfe_axi_stream_cfg_cmd *stream_cfg_cmd)
{
int rc = 0, i;
+ unsigned long flags;
struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
struct msm_vfe_axi_stream *stream_info;
enum msm_vfe_axi_state valid_state =
(stream_cfg_cmd->cmd == START_STREAM) ? INACTIVE : ACTIVE;
-
for (i = 0; i < stream_cfg_cmd->num_streams; i++) {
stream_info = &axi_data->stream_info[
HANDLE_TO_IDX(stream_cfg_cmd->stream_handle[i])];
+ spin_lock_irqsave(&stream_info->lock, flags);
if (stream_info->state != valid_state) {
- pr_err("%s: Invalid stream state\n", __func__);
- rc = -EINVAL;
- break;
+ if ((stream_info->state == PAUSING ||
+ stream_info->state == PAUSED ||
+ stream_info->state == RESUME_PENDING ||
+ stream_info->state == RESUMING) &&
+ stream_cfg_cmd->cmd == STOP_STREAM) {
+ stream_info->state = ACTIVE;
+ } else {
+ pr_err("%s: Invalid stream state: %d\n",
+ __func__, stream_info->state);
+ spin_unlock_irqrestore(
+ &stream_info->lock, flags);
+ rc = -EINVAL;
+ break;
+ }
}
+ spin_unlock_irqrestore(&stream_info->lock, flags);
if (stream_cfg_cmd->cmd == START_STREAM) {
stream_info->bufq_handle =
@@ -548,7 +574,8 @@
if (stream_info->state == INACTIVE)
return;
for (i = 0; i < stream_info->num_planes; i++) {
- if (stream_info->state == START_PENDING)
+ if (stream_info->state == START_PENDING ||
+ stream_info->state == RESUME_PENDING)
vfe_dev->hw_info->vfe_ops.axi_ops.
enable_wm(vfe_dev, stream_info->wm[i], 1);
else
@@ -558,7 +585,7 @@
if (stream_info->state == START_PENDING)
axi_data->num_active_stream++;
- else
+ else if (stream_info->state == STOP_PENDING)
axi_data->num_active_stream--;
}
@@ -594,6 +621,60 @@
complete(&vfe_dev->stream_config_complete);
}
+static void msm_isp_reload_ping_pong_offset(struct vfe_device *vfe_dev,
+ struct msm_vfe_axi_stream *stream_info)
+{
+ int i, j;
+ uint32_t flag;
+ struct msm_isp_buffer *buf;
+ for (i = 0; i < 2; i++) {
+ buf = stream_info->buf[i];
+ flag = i ? VFE_PONG_FLAG : VFE_PING_FLAG;
+ for (j = 0; j < stream_info->num_planes; j++) {
+ vfe_dev->hw_info->vfe_ops.axi_ops.update_ping_pong_addr(
+ vfe_dev, stream_info->wm[j], flag,
+ buf->mapped_info[j].paddr +
+ stream_info->plane_cfg[j].plane_addr_offset);
+ }
+ }
+}
+
+void msm_isp_axi_cfg_update(struct vfe_device *vfe_dev)
+{
+ int i, j;
+ uint32_t update_state;
+ unsigned long flags;
+ struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
+ struct msm_vfe_axi_stream *stream_info;
+ for (i = 0; i < MAX_NUM_STREAM; i++) {
+ stream_info = &axi_data->stream_info[i];
+ if (stream_info->stream_type == BURST_STREAM ||
+ stream_info->state == AVALIABLE)
+ continue;
+ spin_lock_irqsave(&stream_info->lock, flags);
+ if (stream_info->state == PAUSING) {
+ /*AXI Stopped, apply update*/
+ stream_info->state = PAUSED;
+ msm_isp_reload_ping_pong_offset(vfe_dev, stream_info);
+ for (j = 0; j < stream_info->num_planes; j++)
+ vfe_dev->hw_info->vfe_ops.axi_ops.
+ cfg_wm_reg(vfe_dev, stream_info, j);
+ /*Resume AXI*/
+ stream_info->state = RESUME_PENDING;
+ msm_isp_axi_stream_enable_cfg(
+ vfe_dev, &axi_data->stream_info[i]);
+ stream_info->state = RESUMING;
+ } else if (stream_info->state == RESUMING) {
+ stream_info->runtime_output_format =
+ stream_info->output_format;
+ stream_info->state = ACTIVE;
+ }
+ spin_unlock_irqrestore(&stream_info->lock, flags);
+ }
+
+ update_state = atomic_dec_return(&axi_data->axi_cfg_update);
+}
+
static void msm_isp_cfg_pong_address(struct vfe_device *vfe_dev,
struct msm_vfe_axi_stream *stream_info)
{
@@ -690,6 +771,8 @@
buf_event.u.buf_done.handle =
stream_info->bufq_handle;
buf_event.u.buf_done.buf_idx = buf->buf_idx;
+ buf_event.u.buf_done.output_format =
+ stream_info->runtime_output_format;
msm_isp_send_event(vfe_dev,
ISP_EVENT_BUF_DIVERT + stream_idx,
&buf_event);
@@ -697,7 +780,8 @@
} else {
vfe_dev->buf_mgr->ops->buf_done(vfe_dev->buf_mgr,
buf->bufq_handle, buf->buf_idx,
- &ts->buf_time, frame_id);
+ &ts->buf_time, frame_id,
+ stream_info->runtime_output_format);
}
}
}
@@ -954,10 +1038,11 @@
vfe_dev->hw_info->vfe_ops.core_ops.reg_update(vfe_dev);
msm_isp_update_camif_output_count(vfe_dev, stream_cfg_cmd);
- if (camif_update == ENABLE_CAMIF)
+ if (camif_update == ENABLE_CAMIF) {
+ vfe_dev->axi_data.src_info[VFE_PIX_0].frame_id = 0;
vfe_dev->hw_info->vfe_ops.core_ops.
update_camif_state(vfe_dev, camif_update);
-
+ }
if (wait_for_complete)
rc = msm_isp_axi_wait_for_cfg_done(vfe_dev, camif_update);
@@ -1045,40 +1130,87 @@
int msm_isp_update_axi_stream(struct vfe_device *vfe_dev, void *arg)
{
- int rc = 0;
+ int rc = 0, i, j;
struct msm_vfe_axi_stream *stream_info;
struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
struct msm_vfe_axi_stream_update_cmd *update_cmd = arg;
- stream_info = &axi_data->stream_info[
- HANDLE_TO_IDX(update_cmd->stream_handle)];
- if (stream_info->state != ACTIVE && stream_info->state != INACTIVE) {
- pr_err("%s: Invalid stream state\n", __func__);
- return -EINVAL;
+ struct msm_vfe_axi_stream_cfg_update_info *update_info;
+
+ if (update_cmd->update_type == UPDATE_STREAM_AXI_CONFIG &&
+ atomic_read(&axi_data->axi_cfg_update)) {
+ pr_err("%s: AXI stream config updating\n", __func__);
+ return -EBUSY;
}
- switch (update_cmd->update_type) {
- case ENABLE_STREAM_BUF_DIVERT:
- stream_info->buf_divert = 1;
- break;
- case DISABLE_STREAM_BUF_DIVERT:
- stream_info->buf_divert = 0;
- vfe_dev->buf_mgr->ops->flush_buf(vfe_dev->buf_mgr,
- stream_info->bufq_handle,
- MSM_ISP_BUFFER_FLUSH_DIVERTED);
- break;
- case UPDATE_STREAM_FRAMEDROP_PATTERN: {
- uint32_t framedrop_period =
- msm_isp_get_framedrop_period(update_cmd->skip_pattern);
- stream_info->runtime_init_frame_drop = 0;
- stream_info->framedrop_pattern = 0x1;
- stream_info->framedrop_period = framedrop_period - 1;
- vfe_dev->hw_info->vfe_ops.axi_ops.
- cfg_framedrop(vfe_dev, stream_info);
- break;
+ for (i = 0; i < update_cmd->num_streams; i++) {
+ update_info = &update_cmd->update_info[i];
+ stream_info = &axi_data->stream_info[
+ HANDLE_TO_IDX(update_info->stream_handle)];
+ if (stream_info->state != ACTIVE &&
+ stream_info->state != INACTIVE) {
+ pr_err("%s: Invalid stream state\n", __func__);
+ return -EINVAL;
+ }
+ if (stream_info->state == ACTIVE &&
+ stream_info->stream_type == BURST_STREAM) {
+ pr_err("%s: Cannot update active burst stream\n",
+ __func__);
+ return -EINVAL;
+ }
}
- default:
- pr_err("%s: Invalid update type\n", __func__);
- return -EINVAL;
+
+ for (i = 0; i < update_cmd->num_streams; i++) {
+ update_info = &update_cmd->update_info[i];
+ stream_info = &axi_data->stream_info[
+ HANDLE_TO_IDX(update_info->stream_handle)];
+
+ switch (update_cmd->update_type) {
+ case ENABLE_STREAM_BUF_DIVERT:
+ stream_info->buf_divert = 1;
+ break;
+ case DISABLE_STREAM_BUF_DIVERT:
+ stream_info->buf_divert = 0;
+ vfe_dev->buf_mgr->ops->flush_buf(vfe_dev->buf_mgr,
+ stream_info->bufq_handle,
+ MSM_ISP_BUFFER_FLUSH_DIVERTED);
+ break;
+ case UPDATE_STREAM_FRAMEDROP_PATTERN: {
+ uint32_t framedrop_period =
+ msm_isp_get_framedrop_period(
+ update_info->skip_pattern);
+ stream_info->runtime_init_frame_drop = 0;
+ stream_info->framedrop_pattern = 0x1;
+ stream_info->framedrop_period = framedrop_period - 1;
+ vfe_dev->hw_info->vfe_ops.axi_ops.
+ cfg_framedrop(vfe_dev, stream_info);
+ break;
+ }
+ case UPDATE_STREAM_AXI_CONFIG: {
+ for (j = 0; j < stream_info->num_planes; j++) {
+ stream_info->plane_cfg[j] =
+ update_info->plane_cfg[j];
+ }
+ stream_info->output_format = update_info->output_format;
+ if (stream_info->state == ACTIVE) {
+ stream_info->state = PAUSE_PENDING;
+ msm_isp_axi_stream_enable_cfg(
+ vfe_dev, stream_info);
+ stream_info->state = PAUSING;
+ atomic_set(&axi_data->axi_cfg_update,
+ UPDATE_REQUESTED);
+ } else {
+ for (j = 0; j < stream_info->num_planes; j++)
+ vfe_dev->hw_info->vfe_ops.axi_ops.
+ cfg_wm_reg(vfe_dev, stream_info, j);
+ stream_info->runtime_output_format =
+ stream_info->output_format;
+ }
+ break;
+ }
+ default:
+ pr_err("%s: Invalid update type\n", __func__);
+ return -EINVAL;
+ }
}
return rc;
}
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.h b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.h
index 3d775f9..7d282bd 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.h
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.h
@@ -41,6 +41,7 @@
int msm_isp_cfg_axi_stream(struct vfe_device *vfe_dev, void *arg);
int msm_isp_release_axi_stream(struct vfe_device *vfe_dev, void *arg);
int msm_isp_update_axi_stream(struct vfe_device *vfe_dev, void *arg);
+void msm_isp_axi_cfg_update(struct vfe_device *vfe_dev);
void msm_isp_axi_stream_update(struct vfe_device *vfe_dev);
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
index ee205c0..ac44c61 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
@@ -647,6 +647,8 @@
break;
case V4L2_PIX_FMT_NV12:
case V4L2_PIX_FMT_NV21:
+ case V4L2_PIX_FMT_NV14:
+ case V4L2_PIX_FMT_NV41:
case V4L2_PIX_FMT_NV16:
case V4L2_PIX_FMT_NV61:
val = CAL_WORD(pixel_per_line, 1, 8);
@@ -691,6 +693,8 @@
return 12;
case V4L2_PIX_FMT_NV12:
case V4L2_PIX_FMT_NV21:
+ case V4L2_PIX_FMT_NV14:
+ case V4L2_PIX_FMT_NV41:
return 8;
case V4L2_PIX_FMT_NV16:
case V4L2_PIX_FMT_NV61:
diff --git a/drivers/media/platform/msm/camera_v2/msm.c b/drivers/media/platform/msm/camera_v2/msm.c
index 5581723..9fe9065 100644
--- a/drivers/media/platform/msm/camera_v2/msm.c
+++ b/drivers/media/platform/msm/camera_v2/msm.c
@@ -492,6 +492,22 @@
return 0;
}
+static int __msm_close_destry_session_notify_apps(void *d1, void *d2)
+{
+ struct v4l2_event event;
+ struct msm_v4l2_event_data *event_data =
+ (struct msm_v4l2_event_data *)&event.u.data[0];
+ struct msm_session *session = d1;
+
+ event.type = MSM_CAMERA_V4L2_EVENT_TYPE;
+ event.id = MSM_CAMERA_MSM_NOTIFY;
+ event_data->command = MSM_CAMERA_PRIV_SHUTDOWN;
+
+ v4l2_event_queue(session->event_q.vdev, &event);
+
+ return 0;
+}
+
static long msm_private_ioctl(struct file *file, void *fh,
bool valid_prio, int cmd, void *arg)
{
@@ -551,6 +567,13 @@
}
break;
+ case MSM_CAM_V4L2_IOCTL_NOTIFY_ERROR:
+ /* send v4l2_event to HAL next*/
+ msm_queue_traverse_action(msm_session_q,
+ struct msm_session, list,
+ __msm_close_destry_session_notify_apps, NULL);
+ break;
+
default:
rc = -ENOTTY;
break;
@@ -678,22 +701,6 @@
return rc;
}
-static int __msm_close_destry_session_notify_apps(void *d1, void *d2)
-{
- struct v4l2_event event;
- struct msm_v4l2_event_data *event_data =
- (struct msm_v4l2_event_data *)&event.u.data[0];
- struct msm_session *session = d1;
-
- event.type = MSM_CAMERA_V4L2_EVENT_TYPE;
- event.id = MSM_CAMERA_MSM_NOTIFY;
- event_data->command = MSM_CAMERA_PRIV_SHUTDOWN;
-
- v4l2_event_queue(session->event_q.vdev, &event);
-
- return 0;
-}
-
static int msm_close(struct file *filep)
{
int rc = 0;
diff --git a/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.c b/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.c
index 895f452..154ee87 100644
--- a/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.c
+++ b/drivers/media/platform/msm/camera_v2/msm_buf_mgr/msm_generic_buf_mgr.c
@@ -62,6 +62,7 @@
(bufs->vb2_buf->v4l2_buf.index == buf_info->index)) {
bufs->vb2_buf->v4l2_buf.sequence = buf_info->frame_id;
bufs->vb2_buf->v4l2_buf.timestamp = buf_info->timestamp;
+ bufs->vb2_buf->v4l2_buf.reserved = 0;
ret = buf_mngr_dev->vb2_ops.buf_done
(bufs->vb2_buf,
buf_info->session_id,
diff --git a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c
index 4dd3f3d..4f02197 100644
--- a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c
+++ b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c
@@ -741,10 +741,14 @@
if (NULL != fw)
ptr_bin = (uint32_t *)fw->data;
- for (i = 0; i < fw->size/4; i++) {
- if (ptr_bin) {
- msm_cpp_write(*ptr_bin, cpp_dev->base);
- ptr_bin++;
+ if (ptr_bin == NULL) {
+ pr_err("ptr_bin is NULL\n");
+ } else {
+ for (i = 0; i < fw->size/4; i++) {
+ if (ptr_bin) {
+ msm_cpp_write(*ptr_bin, cpp_dev->base);
+ ptr_bin++;
+ }
}
}
if (fw)
@@ -1172,6 +1176,11 @@
int rc = 0;
char *fw_name_bin;
+ if (ioctl_ptr == NULL) {
+ pr_err("ioctl_ptr is null\n");
+ return -EINVAL;
+ }
+
mutex_lock(&cpp_dev->mutex);
CPP_DBG("E cmd: %d\n", cmd);
switch (cmd) {
@@ -1187,7 +1196,7 @@
case VIDIOC_MSM_CPP_LOAD_FIRMWARE: {
if (cpp_dev->is_firmware_loaded == 0) {
- fw_name_bin = kzalloc(ioctl_ptr->len, GFP_KERNEL);
+ fw_name_bin = kzalloc(ioctl_ptr->len+1, GFP_KERNEL);
if (!fw_name_bin) {
pr_err("%s:%d: malloc error\n", __func__,
__LINE__);
@@ -1195,6 +1204,14 @@
return -EINVAL;
}
+ if (ioctl_ptr->ioctl_ptr == NULL) {
+ pr_err("ioctl_ptr->ioctl_ptr=NULL\n");
+ return -EINVAL;
+ }
+ if (ioctl_ptr->len == 0) {
+ pr_err("ioctl_ptr->len is 0\n");
+ return -EINVAL;
+ }
rc = (copy_from_user(fw_name_bin,
(void __user *)ioctl_ptr->ioctl_ptr,
ioctl_ptr->len) ? -EFAULT : 0);
@@ -1204,6 +1221,11 @@
mutex_unlock(&cpp_dev->mutex);
return -EINVAL;
}
+ *(fw_name_bin+ioctl_ptr->len) = '\0';
+ if (cpp_dev == NULL) {
+ pr_err("cpp_dev is null\n");
+ return -EINVAL;
+ }
disable_irq(cpp_dev->irq->start);
cpp_load_fw(cpp_dev, fw_name_bin);
diff --git a/drivers/media/platform/msm/vidc/hfi_packetization.c b/drivers/media/platform/msm/vidc/hfi_packetization.c
index 42d4f95..6e8c809 100644
--- a/drivers/media/platform/msm/vidc/hfi_packetization.c
+++ b/drivers/media/platform/msm/vidc/hfi_packetization.c
@@ -61,6 +61,18 @@
[ilog2(HAL_COLOR_FORMAT_BGR888)] = HFI_COLOR_FORMAT_BGR888,
};
+static int nal_type[] = {
+ [ilog2(HAL_NAL_FORMAT_STARTCODES)] = HFI_NAL_FORMAT_STARTCODES,
+ [ilog2(HAL_NAL_FORMAT_ONE_NAL_PER_BUFFER)] =
+ HFI_NAL_FORMAT_ONE_NAL_PER_BUFFER,
+ [ilog2(HAL_NAL_FORMAT_ONE_BYTE_LENGTH)] =
+ HFI_NAL_FORMAT_ONE_BYTE_LENGTH,
+ [ilog2(HAL_NAL_FORMAT_TWO_BYTE_LENGTH)] =
+ HFI_NAL_FORMAT_TWO_BYTE_LENGTH,
+ [ilog2(HAL_NAL_FORMAT_FOUR_BYTE_LENGTH)] =
+ HFI_NAL_FORMAT_FOUR_BYTE_LENGTH,
+};
+
static inline int hal_to_hfi_type(int property, int hal_type)
{
if (hal_type && (roundup_pow_of_two(hal_type) != hal_type)) {
@@ -85,6 +97,9 @@
case HAL_PARAM_UNCOMPRESSED_FORMAT_SELECT:
return (hal_type >= ARRAY_SIZE(color_format)) ?
-ENOTSUPP : color_format[hal_type];
+ case HAL_PARAM_NAL_STREAM_FORMAT_SELECT:
+ return (hal_type >= ARRAY_SIZE(nal_type)) ?
+ -ENOTSUPP : nal_type[hal_type];
default:
return -ENOTSUPP;
}
@@ -717,40 +732,20 @@
}
case HAL_PARAM_NAL_STREAM_FORMAT_SELECT:
{
- struct hal_nal_stream_format_supported *prop =
- (struct hal_nal_stream_format_supported *)pdata;
+ struct hfi_nal_stream_format_select *hfi;
+ struct hal_nal_stream_format_select *prop =
+ (struct hal_nal_stream_format_select *)pdata;
pkt->rg_property_data[0] =
HFI_PROPERTY_PARAM_NAL_STREAM_FORMAT_SELECT;
+ hfi = (struct hfi_nal_stream_format_select *)
+ &pkt->rg_property_data[1];
dprintk(VIDC_DBG, "data is :%d",
- prop->nal_stream_format_supported);
-
- switch (prop->nal_stream_format_supported) {
- case HAL_NAL_FORMAT_STARTCODES:
- pkt->rg_property_data[1] =
- HFI_NAL_FORMAT_STARTCODES;
- break;
- case HAL_NAL_FORMAT_ONE_NAL_PER_BUFFER:
- pkt->rg_property_data[1] =
- HFI_NAL_FORMAT_ONE_NAL_PER_BUFFER;
- break;
- case HAL_NAL_FORMAT_ONE_BYTE_LENGTH:
- pkt->rg_property_data[1] =
- HFI_NAL_FORMAT_ONE_BYTE_LENGTH;
- break;
- case HAL_NAL_FORMAT_TWO_BYTE_LENGTH:
- pkt->rg_property_data[1] =
- HFI_NAL_FORMAT_TWO_BYTE_LENGTH;
- break;
- case HAL_NAL_FORMAT_FOUR_BYTE_LENGTH:
- pkt->rg_property_data[1] =
- HFI_NAL_FORMAT_FOUR_BYTE_LENGTH;
- break;
- default:
- dprintk(VIDC_ERR, "Invalid nal format: 0x%x",
- prop->nal_stream_format_supported);
- break;
- }
- pkt->size += sizeof(u32) * 2;
+ prop->nal_stream_format_select);
+ hfi->nal_stream_format_select = hal_to_hfi_type(
+ HAL_PARAM_NAL_STREAM_FORMAT_SELECT,
+ prop->nal_stream_format_select);
+ pkt->size += sizeof(u32) +
+ sizeof(struct hfi_nal_stream_format_select);
break;
}
case HAL_PARAM_VDEC_OUTPUT_ORDER:
diff --git a/drivers/media/platform/msm/vidc/hfi_response_handler.c b/drivers/media/platform/msm/vidc/hfi_response_handler.c
index 19f5dcd..859345f 100644
--- a/drivers/media/platform/msm/vidc/hfi_response_handler.c
+++ b/drivers/media/platform/msm/vidc/hfi_response_handler.c
@@ -676,7 +676,7 @@
{
struct msm_vidc_cb_cmd_done cmd_done;
struct vidc_hal_session_init_done session_init_done;
-
+ struct hal_session *sess_close = NULL;
dprintk(VIDC_DBG, "RECEIVED:SESSION_INIT_DONE");
if (sizeof(struct hfi_msg_sys_session_init_done_packet)
> pkt->size) {
@@ -696,6 +696,16 @@
if (!cmd_done.status) {
cmd_done.status = hfi_process_sess_init_done_prop_read(
pkt, &session_init_done);
+ } else {
+ sess_close = (struct hal_session *)pkt->session_id;
+ if (sess_close) {
+ dprintk(VIDC_INFO,
+ "Sess init failed: Deleting session: 0x%x 0x%p",
+ sess_close->session_id, sess_close);
+ list_del(&sess_close->list);
+ kfree(sess_close);
+ sess_close = NULL;
+ }
}
cmd_done.size = sizeof(struct vidc_hal_session_init_done);
callback(SESSION_INIT_DONE, &cmd_done);
@@ -1015,6 +1025,7 @@
sess_close->session_id);
list_del(&sess_close->list);
kfree(sess_close);
+ sess_close = NULL;
callback(SESSION_END_DONE, &cmd_done);
}
@@ -1050,6 +1061,7 @@
sess_close->session_id);
list_del(&sess_close->list);
kfree(sess_close);
+ sess_close = NULL;
callback(SESSION_ABORT_DONE, &cmd_done);
}
diff --git a/drivers/media/platform/msm/vidc/msm_venc.c b/drivers/media/platform/msm/vidc/msm_venc.c
index b8b3453..7a1fd81 100644
--- a/drivers/media/platform/msm/vidc/msm_venc.c
+++ b/drivers/media/platform/msm/vidc/msm_venc.c
@@ -124,18 +124,6 @@
static struct msm_vidc_ctrl msm_venc_ctrls[] = {
{
- .id = V4L2_CID_MPEG_VIDC_VIDEO_FRAME_RATE,
- .name = "Frame Rate",
- .type = V4L2_CTRL_TYPE_INTEGER,
- .minimum = MIN_FRAME_RATE,
- .maximum = MAX_FRAME_RATE,
- .default_value = MIN_FRAME_RATE,
- .step = 1,
- .menu_skip_mask = 0,
- .qmenu = NULL,
- .cluster = MSM_VENC_CTRL_CLUSTER_TIMING,
- },
- {
.id = V4L2_CID_MPEG_VIDC_VIDEO_IDR_PERIOD,
.name = "IDR Period",
.type = V4L2_CTRL_TYPE_INTEGER,
@@ -1160,7 +1148,6 @@
static int try_set_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl)
{
int rc = 0;
- struct hal_frame_rate frame_rate;
struct hal_request_iframe request_iframe;
struct hal_bitrate bitrate;
struct hal_profile_level profile_level;
@@ -1202,13 +1189,6 @@
})
switch (ctrl->id) {
- case V4L2_CID_MPEG_VIDC_VIDEO_FRAME_RATE:
- property_id =
- HAL_CONFIG_FRAME_RATE;
- frame_rate.frame_rate = ctrl->val;
- frame_rate.buffer_type = HAL_BUFFER_OUTPUT;
- pdata = &frame_rate;
- break;
case V4L2_CID_MPEG_VIDC_VIDEO_IDR_PERIOD:
property_id =
HAL_CONFIG_VENC_IDR_PERIOD;
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.c b/drivers/media/platform/msm/vidc/msm_vidc_common.c
index 5356b03..002363e 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_common.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_common.c
@@ -61,30 +61,8 @@
if (inst->session_type == type &&
inst->state >= MSM_VIDC_OPEN_DONE &&
inst->state < MSM_VIDC_STOP_DONE) {
- int stride, scanlines, rc;
- struct hfi_device *hdev;
-
- hdev = inst->core->device;
- if (!hdev) {
- dprintk(VIDC_ERR,
- "No hdev (probably in bad state)\n");
- mutex_unlock(&inst->lock);
- return -EINVAL;
- }
-
- rc = call_hfi_op(hdev, get_stride_scanline,
- COLOR_FMT_NV12,
- inst->prop.width, inst->prop.height,
- &stride, &scanlines);
- if (rc) {
- dprintk(VIDC_WARN,
- "Failed to determine stride/scan when getting load. Perf. might be affected\n");
- stride = inst->prop.width;
- scanlines = inst->prop.height;
- }
-
- num_mbs_per_sec += NUM_MBS_PER_SEC(stride, scanlines,
- inst->prop.fps);
+ num_mbs_per_sec += NUM_MBS_PER_SEC(inst->prop.height,
+ inst->prop.width, inst->prop.fps);
}
mutex_unlock(&inst->lock);
}
@@ -308,10 +286,21 @@
static void change_inst_state(struct msm_vidc_inst *inst,
enum instance_state state)
{
+ if (!inst) {
+ dprintk(VIDC_ERR, "Invalid parameter %s", __func__);
+ return;
+ }
mutex_lock(&inst->lock);
+ if (inst->state == MSM_VIDC_CORE_INVALID) {
+ dprintk(VIDC_DBG,
+ "Inst: %p is in bad state can't change state",
+ inst);
+ goto exit;
+ }
dprintk(VIDC_DBG, "Moved inst: %p from state: %d to state: %d\n",
inst, inst->state, state);
inst->state = state;
+exit:
mutex_unlock(&inst->lock);
}
@@ -362,27 +351,6 @@
return rc;
}
-static void handle_session_init_done(enum command_response cmd, void *data)
-{
- struct msm_vidc_cb_cmd_done *response = data;
- struct msm_vidc_inst *inst;
- if (response && !response->status) {
- struct vidc_hal_session_init_done *session_init_done =
- (struct vidc_hal_session_init_done *) response->data;
- inst = (struct msm_vidc_inst *)response->session_id;
-
- inst->capability.width = session_init_done->width;
- inst->capability.height = session_init_done->height;
- inst->capability.frame_rate =
- session_init_done->frame_rate;
- inst->capability.capability_set = true;
- signal_session_msg_receipt(cmd, inst);
- } else {
- dprintk(VIDC_ERR,
- "Failed to get valid response for session init\n");
- }
-}
-
static void queue_v4l2_event(struct msm_vidc_inst *inst, int event_type)
{
struct v4l2_event event = {.id = 0, .type = event_type};
@@ -390,6 +358,52 @@
wake_up(&inst->kernel_event_queue);
}
+static void msm_comm_generate_session_error(struct msm_vidc_inst *inst)
+{
+ if (!inst) {
+ dprintk(VIDC_ERR, "%s: invalid input parameters", __func__);
+ return;
+ }
+ mutex_lock(&inst->lock);
+ inst->session = NULL;
+ inst->state = MSM_VIDC_CORE_INVALID;
+ queue_v4l2_event(inst, V4L2_EVENT_MSM_VIDC_SYS_ERROR);
+ mutex_unlock(&inst->lock);
+}
+
+static void handle_session_init_done(enum command_response cmd, void *data)
+{
+ struct msm_vidc_cb_cmd_done *response = data;
+ struct msm_vidc_inst *inst = NULL;
+ if (response) {
+ struct vidc_hal_session_init_done *session_init_done =
+ (struct vidc_hal_session_init_done *)
+ response->data;
+ inst = (struct msm_vidc_inst *)response->session_id;
+ if (!inst) {
+ dprintk(VIDC_ERR, "%s: invalid input parameters",
+ __func__);
+ return;
+ }
+ if (!response->status && session_init_done) {
+ inst->capability.width = session_init_done->width;
+ inst->capability.height = session_init_done->height;
+ inst->capability.frame_rate =
+ session_init_done->frame_rate;
+ inst->capability.capability_set = true;
+ } else {
+ dprintk(VIDC_ERR,
+ "Session init response from FW : 0x%x",
+ response->status);
+ msm_comm_generate_session_error(inst);
+ }
+ signal_session_msg_receipt(cmd, inst);
+ } else {
+ dprintk(VIDC_ERR,
+ "Failed to get valid response for session init\n");
+ }
+}
+
static void handle_event_change(enum command_response cmd, void *data)
{
struct msm_vidc_cb_cmd_done *response = data;
@@ -553,6 +567,9 @@
struct msm_vidc_cb_cmd_done *response = data;
struct msm_vidc_inst *inst = NULL ;
struct msm_vidc_core *core = NULL;
+ struct hfi_device *hdev = NULL;
+ int rc = 0;
+
subsystem_crashed("venus");
if (response) {
core = get_vidc_core(response->device_id);
@@ -565,8 +582,18 @@
list) {
mutex_lock(&inst->lock);
inst->state = MSM_VIDC_CORE_INVALID;
+ if (inst->core)
+ hdev = inst->core->device;
+ if (hdev && inst->session) {
+ rc = call_hfi_op(hdev, session_clean,
+ (void *) inst->session);
+ if (rc)
+ dprintk(VIDC_ERR,
+ "Sess clean failed :%p",
+ inst);
+ }
+ inst->session = NULL;
mutex_unlock(&inst->lock);
-
queue_v4l2_event(inst,
V4L2_EVENT_MSM_VIDC_SYS_ERROR);
}
@@ -585,6 +612,8 @@
struct msm_vidc_cb_cmd_done *response = data;
struct msm_vidc_inst *inst;
struct msm_vidc_core *core = NULL;
+ struct hfi_device *hdev = NULL;
+ int rc = 0;
dprintk(VIDC_ERR, "Venus Subsystem crashed\n");
core = get_vidc_core(response->device_id);
if (!core) {
@@ -600,6 +629,17 @@
queue_v4l2_event(inst, V4L2_EVENT_MSM_VIDC_SYS_ERROR);
mutex_lock(&inst->lock);
inst->state = MSM_VIDC_CORE_INVALID;
+ if (inst->core)
+ hdev = inst->core->device;
+ if (hdev && inst->session) {
+ rc = call_hfi_op(hdev, session_clean,
+ (void *) inst->session);
+ if (rc)
+ dprintk(VIDC_ERR,
+ "Sess clean failed :%p",
+ inst);
+
+ }
inst->session = NULL;
mutex_unlock(&inst->lock);
}
@@ -716,6 +756,7 @@
switch (fill_buf_done->picture_type) {
case HAL_PICTURE_IDR:
vb->v4l2_buf.flags |= V4L2_QCOM_BUF_FLAG_IDRFRAME;
+ vb->v4l2_buf.flags |= V4L2_BUF_FLAG_KEYFRAME;
break;
case HAL_PICTURE_I:
vb->v4l2_buf.flags |= V4L2_BUF_FLAG_KEYFRAME;
@@ -1213,9 +1254,11 @@
}
init_completion(
&inst->completions[SESSION_MSG_INDEX(SESSION_INIT_DONE)]);
+ mutex_lock(&inst->lock);
inst->session = call_hfi_op(hdev, session_init, hdev->hfi_device_data,
(u32) inst, get_hal_domain(inst->session_type),
get_hal_codec_type(fourcc));
+ mutex_unlock(&inst->lock);
if (!inst->session) {
dprintk(VIDC_ERR,
"Failed to call session init for: %d, %d, %d, %d\n",
@@ -1241,6 +1284,12 @@
dprintk(VIDC_ERR, "%s invalid parameters", __func__);
return -EINVAL;
}
+ if (inst->state == MSM_VIDC_CORE_INVALID ||
+ inst->core->state == VIDC_CORE_INVALID) {
+ dprintk(VIDC_ERR,
+ "Core is in bad state can't do load res");
+ return -EINVAL;
+ }
num_mbs_per_sec = msm_comm_get_load(inst->core, MSM_VIDC_DECODER);
num_mbs_per_sec += msm_comm_get_load(inst->core, MSM_VIDC_ENCODER);
@@ -1315,6 +1364,12 @@
dprintk(VIDC_ERR, "%s invalid parameters", __func__);
return -EINVAL;
}
+ if (inst->state == MSM_VIDC_CORE_INVALID ||
+ inst->core->state == VIDC_CORE_INVALID) {
+ dprintk(VIDC_ERR,
+ "Core is in bad state can't do start");
+ return -EINVAL;
+ }
hdev = inst->core->device;
@@ -2231,6 +2286,7 @@
"Core %p and inst %p are in bad state\n",
core, inst);
msm_comm_flush_in_invalid_state(inst);
+ return 0;
}
mutex_lock(&inst->sync_lock);
@@ -2453,10 +2509,9 @@
dprintk(VIDC_ERR, "%s: invalid input parameters", __func__);
return -EINVAL;
}
- if (inst->state < MSM_VIDC_OPEN_DONE) {
+ if (!inst->session || inst->state < MSM_VIDC_OPEN_DONE) {
dprintk(VIDC_WARN,
"No corresponding FW session. No need to send Abort");
- inst->state = MSM_VIDC_CORE_INVALID;
return rc;
}
hdev = inst->core->device;
diff --git a/drivers/media/platform/msm/vidc/q6_hfi.c b/drivers/media/platform/msm/vidc/q6_hfi.c
index 577b2b5..0678fc2 100644
--- a/drivers/media/platform/msm/vidc/q6_hfi.c
+++ b/drivers/media/platform/msm/vidc/q6_hfi.c
@@ -618,6 +618,21 @@
HFI_CMD_SYS_SESSION_ABORT);
}
+static int q6_hfi_session_clean(void *session)
+{
+ struct hal_session *sess_close;
+ if (!session) {
+ dprintk(VIDC_ERR, "Invalid Params %s", __func__);
+ return -EINVAL;
+ }
+ sess_close = session;
+ dprintk(VIDC_DBG, "deleted the session: 0x%x",
+ sess_close->session_id);
+ list_del(&sess_close->list);
+ kfree(sess_close);
+ return 0;
+}
+
static int q6_hfi_session_set_buffers(void *sess,
struct vidc_buffer_addr_info *buffer_info)
{
@@ -1364,6 +1379,7 @@
hdev->session_init = q6_hfi_session_init;
hdev->session_end = q6_hfi_session_end;
hdev->session_abort = q6_hfi_session_abort;
+ hdev->session_clean = q6_hfi_session_clean;
hdev->session_set_buffers = q6_hfi_session_set_buffers;
hdev->session_release_buffers = q6_hfi_session_release_buffers;
hdev->session_load_res = q6_hfi_session_load_res;
diff --git a/drivers/media/platform/msm/vidc/venus_hfi.c b/drivers/media/platform/msm/vidc/venus_hfi.c
index bc5adc11..ca4ac53 100644
--- a/drivers/media/platform/msm/vidc/venus_hfi.c
+++ b/drivers/media/platform/msm/vidc/venus_hfi.c
@@ -1457,12 +1457,12 @@
goto err_session_init_fail;
}
- if (venus_hfi_iface_cmdq_write(dev, &pkt))
- goto err_session_init_fail;
if (venus_hfi_sys_set_debug(dev, msm_fw_debug))
dprintk(VIDC_ERR, "Setting fw_debug msg ON failed");
if (venus_hfi_sys_set_idle_message(dev, msm_fw_low_power_mode))
dprintk(VIDC_ERR, "Setting idle response ON failed");
+ if (venus_hfi_iface_cmdq_write(dev, &pkt))
+ goto err_session_init_fail;
return (void *) new_session;
err_session_init_fail:
@@ -1509,6 +1509,21 @@
HFI_CMD_SYS_SESSION_ABORT);
}
+static int venus_hfi_session_clean(void *session)
+{
+ struct hal_session *sess_close;
+ if (!session) {
+ dprintk(VIDC_ERR, "Invalid Params %s", __func__);
+ return -EINVAL;
+ }
+ sess_close = session;
+ dprintk(VIDC_DBG, "deleted the session: 0x%p",
+ sess_close);
+ list_del(&sess_close->list);
+ kfree(sess_close);
+ return 0;
+}
+
static int venus_hfi_session_set_buffers(void *sess,
struct vidc_buffer_addr_info *buffer_info)
{
@@ -2613,7 +2628,7 @@
static int venus_hfi_iommu_attach(struct venus_hfi_device *device)
{
- int rc;
+ int rc = 0;
struct iommu_domain *domain;
int i;
struct iommu_set *iommu_group_set;
@@ -2983,6 +2998,7 @@
hdev->session_init = venus_hfi_session_init;
hdev->session_end = venus_hfi_session_end;
hdev->session_abort = venus_hfi_session_abort;
+ hdev->session_clean = venus_hfi_session_clean;
hdev->session_set_buffers = venus_hfi_session_set_buffers;
hdev->session_release_buffers = venus_hfi_session_release_buffers;
hdev->session_load_res = venus_hfi_session_load_res;
diff --git a/drivers/media/platform/msm/vidc/vidc_hfi_api.h b/drivers/media/platform/msm/vidc/vidc_hfi_api.h
index 01395e5..389c13f 100644
--- a/drivers/media/platform/msm/vidc/vidc_hfi_api.h
+++ b/drivers/media/platform/msm/vidc/vidc_hfi_api.h
@@ -754,6 +754,10 @@
u32 nal_stream_format_supported;
};
+struct hal_nal_stream_format_select {
+ u32 nal_stream_format_select;
+};
+
struct hal_multi_view_format {
u32 views;
u32 rg_view_order[1];
@@ -1077,6 +1081,7 @@
int height, int *stride, int *scanlines);
int (*capability_check)(u32 fourcc, u32 width,
u32 *max_width, u32 *max_height);
+ int (*session_clean)(void *sess);
};
typedef void (*hfi_cmd_response_callback) (enum command_response cmd,
diff --git a/drivers/media/platform/msm/vidc/vidc_hfi_helper.h b/drivers/media/platform/msm/vidc/vidc_hfi_helper.h
index 6234dba..2b6d6bb 100644
--- a/drivers/media/platform/msm/vidc/vidc_hfi_helper.h
+++ b/drivers/media/platform/msm/vidc/vidc_hfi_helper.h
@@ -476,6 +476,9 @@
u32 nal_stream_format_supported;
};
+struct hfi_nal_stream_format_select {
+ u32 nal_stream_format_select;
+};
#define HFI_PICTURE_TYPE_I 0x01
#define HFI_PICTURE_TYPE_P 0x02
#define HFI_PICTURE_TYPE_B 0x04
diff --git a/drivers/media/platform/msm/wfd/Kconfig b/drivers/media/platform/msm/wfd/Kconfig
index 6050d73..4fd668e 100644
--- a/drivers/media/platform/msm/wfd/Kconfig
+++ b/drivers/media/platform/msm/wfd/Kconfig
@@ -4,3 +4,9 @@
---help---
Enables the Wifi Display driver.
+menuconfig MSM_WFD_DEBUG
+ bool "Qualcomm MSM Wifi Display Driver Debug Mode"
+ depends on MSM_WFD
+ ---help---
+ Enables the Wifi Display driver in debug mode
+
diff --git a/drivers/media/platform/msm/wfd/Makefile b/drivers/media/platform/msm/wfd/Makefile
index 813bc64..c05f517 100644
--- a/drivers/media/platform/msm/wfd/Makefile
+++ b/drivers/media/platform/msm/wfd/Makefile
@@ -2,6 +2,8 @@
obj-y += wfd-ioctl.o
obj-y += wfd-util.o
obj-y += vsg-subdev.o
+
+ #pick up the MDP subdevice
ifeq ($(CONFIG_FB_MSM_WRITEBACK_MSM_PANEL),y)
obj-y += mdp-4-subdev.o
else ifeq ($(CONFIG_FB_MSM_MDSS_WRITEBACK),y)
@@ -9,6 +11,14 @@
else
obj-y += mdp-dummy-subdev.o
endif
- obj-$(CONFIG_MSM_VIDC_1080P) += enc-mfc-subdev.o
- obj-$(CONFIG_MSM_VIDC_V4L2) += enc-venus-subdev.o
+
+ #pick up the Encoder subdevice
+ ifeq ($(CONFIG_MSM_VIDC_1080P),y)
+ obj-y += enc-mfc-subdev.o
+ else ifeq ($(CONFIG_MSM_VIDC_V4L2),y)
+ obj-y += enc-venus-subdev.o
+ else
+ obj-y += enc-dummy-subdev.o
+ endif
+
endif
diff --git a/drivers/media/platform/msm/wfd/enc-dummy-subdev.c b/drivers/media/platform/msm/wfd/enc-dummy-subdev.c
new file mode 100644
index 0000000..3acb6f8
--- /dev/null
+++ b/drivers/media/platform/msm/wfd/enc-dummy-subdev.c
@@ -0,0 +1,575 @@
+/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License version 2 and
+* only version 2 as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+*/
+
+#include <linux/list.h>
+#include <linux/mutex.h>
+#include <media/msm_media_info.h>
+#include <media/v4l2-subdev.h>
+#include "enc-subdev.h"
+#include "wfd-util.h"
+
+#ifndef CONFIG_MSM_WFD_DEBUG
+#error "Dummy subdevice must only be used when CONFIG_MSM_WFD_DEBUG=y"
+#endif
+
+#define DEFAULT_WIDTH 1920
+#define DEFAULT_HEIGHT 1080
+#define ALLOC_SIZE ALIGN((DEFAULT_WIDTH * DEFAULT_HEIGHT * 3) / 2, SZ_1M)
+#define FILL_SIZE ((DEFAULT_WIDTH * DEFAULT_HEIGHT * 3) / 2)
+
+static struct ion_client *venc_ion_client;
+struct venc_inst {
+ struct mutex lock;
+ struct venc_msg_ops vmops;
+ struct mem_region output_bufs, input_bufs;
+ struct workqueue_struct *wq;
+};
+
+struct encode_task {
+ struct venc_inst *inst;
+ struct work_struct work;
+};
+
+int venc_load_fw(struct v4l2_subdev *sd)
+{
+ return 0;
+}
+
+int venc_init(struct v4l2_subdev *sd, u32 val)
+{
+ if (!venc_ion_client)
+ venc_ion_client = msm_ion_client_create(-1, "wfd_enc_subdev");
+
+ return venc_ion_client ? 0 : -ENOMEM;
+}
+
+static long venc_open(struct v4l2_subdev *sd, void *arg)
+{
+ struct venc_inst *inst = NULL;
+ struct venc_msg_ops *vmops = arg;
+ int rc = 0;
+
+ if (!vmops) {
+ WFD_MSG_ERR("Callbacks required for %s\n", __func__);
+ rc = -EINVAL;
+ goto venc_open_fail;
+ } else if (!sd) {
+ WFD_MSG_ERR("Subdevice required for %s\n", __func__);
+ rc = -EINVAL;
+ goto venc_open_fail;
+ }
+
+ inst = kzalloc(sizeof(*inst), GFP_KERNEL);
+ if (!inst) {
+ WFD_MSG_ERR("Failed to allocate memory\n");
+ rc = -EINVAL;
+ goto venc_open_fail;
+ }
+
+ INIT_LIST_HEAD(&inst->output_bufs.list);
+ INIT_LIST_HEAD(&inst->input_bufs.list);
+ mutex_init(&inst->lock);
+ inst->wq = create_workqueue("venc-dummy-subdev");
+ inst->vmops = *vmops;
+ sd->dev_priv = inst;
+ vmops->cookie = inst;
+ return 0;
+venc_open_fail:
+ return rc;
+}
+
+static long venc_close(struct v4l2_subdev *sd, void *arg)
+{
+ struct venc_inst *inst = NULL;
+ int rc = 0;
+
+ if (!sd) {
+ WFD_MSG_ERR("Subdevice required for %s\n", __func__);
+ rc = -EINVAL;
+ goto venc_close_fail;
+ }
+
+ inst = (struct venc_inst *)sd->dev_priv;
+ destroy_workqueue(inst->wq);
+ kfree(inst);
+ sd->dev_priv = inst = NULL;
+venc_close_fail:
+ return rc;
+
+}
+
+static long venc_get_buffer_req(struct v4l2_subdev *sd, void *arg)
+{
+ int rc = 0;
+ struct bufreq *bufreq = arg;
+ if (!sd) {
+ WFD_MSG_ERR("Subdevice required for %s\n", __func__);
+ rc = -EINVAL;
+ goto venc_buf_req_fail;
+ } else if (!arg) {
+ WFD_MSG_ERR("Invalid buffer requirements\n");
+ rc = -EINVAL;
+ goto venc_buf_req_fail;
+ }
+
+
+ bufreq->count = 3;
+ bufreq->size = ALLOC_SIZE;
+venc_buf_req_fail:
+ return rc;
+}
+
+static long venc_set_buffer_req(struct v4l2_subdev *sd, void *arg)
+{
+ int rc = 0;
+ struct bufreq *bufreq = arg;
+
+ if (!sd) {
+ WFD_MSG_ERR("Subdevice required for %s\n", __func__);
+ rc = -EINVAL;
+ goto venc_buf_req_fail;
+ } else if (!arg) {
+ WFD_MSG_ERR("Invalid buffer requirements\n");
+ rc = -EINVAL;
+ goto venc_buf_req_fail;
+ }
+
+ bufreq->size = ALLOC_SIZE;
+venc_buf_req_fail:
+ return rc;
+
+}
+
+static long venc_start(struct v4l2_subdev *sd)
+{
+ return 0;
+}
+
+static long venc_stop(struct v4l2_subdev *sd)
+{
+ struct venc_inst *inst = NULL;
+
+ if (!sd) {
+ WFD_MSG_ERR("Subdevice required for %s\n", __func__);
+ return -EINVAL;
+ }
+
+ inst = (struct venc_inst *)sd->dev_priv;
+ flush_workqueue(inst->wq);
+ return 0;
+}
+
+static long venc_set_input_buffer(struct v4l2_subdev *sd, void *arg)
+{
+ return 0;
+}
+
+static long venc_set_output_buffer(struct v4l2_subdev *sd, void *arg)
+{
+ return 0;
+}
+
+static long venc_set_format(struct v4l2_subdev *sd, void *arg)
+{
+ struct venc_inst *inst = NULL;
+ struct v4l2_format *fmt = arg;
+
+ if (!sd) {
+ WFD_MSG_ERR("Subdevice required for %s\n", __func__);
+ return -EINVAL;
+ } else if (!fmt) {
+ WFD_MSG_ERR("Invalid format\n");
+ return -EINVAL;
+ } else if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+ WFD_MSG_ERR("Invalid buffer type %d\n", fmt->type);
+ return -ENOTSUPP;
+ }
+
+ inst = (struct venc_inst *)sd->dev_priv;
+ fmt->fmt.pix.sizeimage = ALLOC_SIZE;
+ return 0;
+}
+
+static long venc_set_framerate(struct v4l2_subdev *sd, void *arg)
+{
+ return 0;
+}
+
+static int venc_map_user_to_kernel(struct venc_inst *inst,
+ struct mem_region *mregion)
+{
+ int rc = 0;
+ unsigned long flags = 0;
+ if (!mregion) {
+ rc = -EINVAL;
+ goto venc_map_fail;
+ }
+
+ mregion->ion_handle = ion_import_dma_buf(venc_ion_client, mregion->fd);
+ if (IS_ERR_OR_NULL(mregion->ion_handle)) {
+ rc = PTR_ERR(mregion->ion_handle);
+ WFD_MSG_ERR("Failed to get handle: %p, %d, %d, %d\n",
+ venc_ion_client, mregion->fd, mregion->offset, rc);
+ mregion->ion_handle = NULL;
+ goto venc_map_fail;
+ }
+
+ rc = ion_handle_get_flags(venc_ion_client, mregion->ion_handle, &flags);
+ if (rc) {
+ WFD_MSG_ERR("Failed to get ion flags %d\n", rc);
+ goto venc_map_fail;
+ }
+
+ mregion->paddr = mregion->kvaddr = ion_map_kernel(venc_ion_client,
+ mregion->ion_handle);
+
+ if (IS_ERR_OR_NULL(mregion->kvaddr)) {
+ WFD_MSG_ERR("Failed to map buffer into kernel\n");
+ rc = PTR_ERR(mregion->kvaddr);
+ mregion->kvaddr = NULL;
+ goto venc_map_fail;
+ }
+
+venc_map_fail:
+ return rc;
+}
+
+static int venc_unmap_user_to_kernel(struct venc_inst *inst,
+ struct mem_region *mregion)
+{
+ if (!mregion || !mregion->ion_handle)
+ return 0;
+
+ if (mregion->kvaddr) {
+ ion_unmap_kernel(venc_ion_client, mregion->ion_handle);
+ mregion->kvaddr = NULL;
+ }
+
+
+ return 0;
+}
+
+#ifdef CONFIG_MSM_VIDC_V4L2
+static int encode_memcpy(uint8_t *dst, uint8_t *src, int size)
+{
+ int y_stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, DEFAULT_WIDTH),
+ y_scan = VENUS_Y_SCANLINES(COLOR_FMT_NV12, DEFAULT_HEIGHT),
+ uv_stride = VENUS_UV_STRIDE(COLOR_FMT_NV12, DEFAULT_WIDTH),
+ uv_scan = VENUS_UV_SCANLINES(COLOR_FMT_NV12, DEFAULT_HEIGHT);
+ int y_size = y_stride * y_scan;
+ int c = 0, dst_offset = 0, src_offset = 0;
+
+ /* copy the luma */
+ for (c = 0; c < DEFAULT_HEIGHT; ++c) {
+ memcpy(dst + dst_offset, src + src_offset, DEFAULT_WIDTH);
+ src_offset += y_stride;
+ dst_offset += DEFAULT_WIDTH;
+ }
+
+ /* skip over padding between luma and chroma */
+ src_offset = y_size;
+ /* now do the chroma */
+ for (c = 0; c < DEFAULT_HEIGHT / 2; ++c) {
+ memcpy(dst + dst_offset, src + src_offset, DEFAULT_WIDTH);
+ src_offset += uv_stride;
+ dst_offset += DEFAULT_WIDTH;
+ }
+
+ (void)uv_scan;
+ return dst_offset;
+}
+#else
+static int encode_memcpy(uint8_t *dst, uint8_t *src, int size)
+{
+ memcpy(dst, src, size);
+ return size;
+}
+#endif
+
+static void encode(struct work_struct *work)
+{
+ struct encode_task *et = NULL;
+ struct venc_inst *inst = NULL;
+ struct mem_region *input, *output;
+ struct vb2_buffer *vb;
+ int bytes_copied = 0;
+ if (!work)
+ return;
+
+ et = container_of(work, struct encode_task, work);
+ inst = et->inst;
+
+ mutex_lock(&inst->lock);
+ if (list_empty(&inst->input_bufs.list)) {
+ WFD_MSG_ERR("Can't find an input buffer");
+ mutex_unlock(&inst->lock);
+ return;
+ }
+
+ if (list_empty(&inst->output_bufs.list)) {
+ WFD_MSG_ERR("Can't find an output buffer");
+ mutex_unlock(&inst->lock);
+ return;
+ }
+
+ /* Grab an i/p & o/p buffer pair */
+ input = list_first_entry(&inst->input_bufs.list,
+ struct mem_region, list);
+ list_del(&input->list);
+
+ output = list_first_entry(&inst->output_bufs.list,
+ struct mem_region, list);
+ list_del(&output->list);
+ mutex_unlock(&inst->lock);
+
+ /* This is our "encode" */
+ bytes_copied = encode_memcpy(output->kvaddr, input->kvaddr,
+ min(output->size, input->size));
+
+ vb = (struct vb2_buffer *)output->cookie;
+ vb->v4l2_planes[0].bytesused = bytes_copied;
+ inst->vmops.op_buffer_done(
+ inst->vmops.cbdata, 0, vb);
+
+ inst->vmops.ip_buffer_done(
+ inst->vmops.cbdata,
+ 0, input);
+
+ venc_unmap_user_to_kernel(inst, output);
+ kfree(input);
+ kfree(output);
+ kfree(et);
+}
+
+static void prepare_for_encode(struct venc_inst *inst)
+{
+ struct encode_task *et = kzalloc(sizeof(*et), GFP_KERNEL);
+ et->inst = inst;
+ INIT_WORK(&et->work, encode);
+ queue_work(inst->wq, &et->work);
+}
+
+static long venc_fill_outbuf(struct v4l2_subdev *sd, void *arg)
+{
+ struct venc_inst *inst = NULL;
+ struct mem_region *mregion = NULL;
+
+ if (!sd) {
+ WFD_MSG_ERR("Subdevice required for %s\n", __func__);
+ return -EINVAL;
+ } else if (!arg) {
+ WFD_MSG_ERR("Invalid output buffer in %s", __func__);
+ return -EINVAL;
+ }
+
+ inst = (struct venc_inst *)sd->dev_priv;
+
+ /* check for dupes */
+ list_for_each_entry(mregion, &inst->output_bufs.list, list) {
+ struct mem_region *temp = arg;
+ if (mem_region_equals(temp, mregion)) {
+ WFD_MSG_ERR("Attempt to queue dupe buffer\n");
+ return -EEXIST;
+ }
+ }
+
+ mregion = kzalloc(sizeof(*mregion), GFP_KERNEL);
+ if (!mregion) {
+ WFD_MSG_ERR("Invalid output buffer in %s", __func__);
+ return -EINVAL;
+ }
+
+ *mregion = *(struct mem_region *)arg;
+
+ if (venc_map_user_to_kernel(inst, mregion)) {
+ WFD_MSG_ERR("unable to map buffer into kernel\n");
+ return -EFAULT;
+ }
+
+ mutex_lock(&inst->lock);
+ list_add_tail(&mregion->list, &inst->output_bufs.list);
+
+ if (!list_empty(&inst->input_bufs.list))
+ prepare_for_encode(inst);
+ mutex_unlock(&inst->lock);
+
+ return 0;
+}
+
+static long venc_encode_frame(struct v4l2_subdev *sd, void *arg)
+{
+ struct venc_inst *inst = NULL;
+ struct venc_buf_info *venc_buf = arg;
+ struct mem_region *mregion = NULL;
+
+ if (!sd) {
+ WFD_MSG_ERR("Subdevice required for %s\n", __func__);
+ return -EINVAL;
+ } else if (!venc_buf) {
+ WFD_MSG_ERR("Invalid output buffer ot fill\n");
+ return -EINVAL;
+ }
+
+ mregion = kzalloc(sizeof(*mregion), GFP_KERNEL);
+ if (!mregion) {
+ WFD_MSG_ERR("Invalid output buffer in %s", __func__);
+ return -EINVAL;
+ }
+
+ inst = (struct venc_inst *)sd->dev_priv;
+ *mregion = *venc_buf->mregion;
+
+ mutex_lock(&inst->lock);
+ list_add_tail(&mregion->list, &inst->input_bufs.list);
+
+ if (!list_empty(&inst->output_bufs.list))
+ prepare_for_encode(inst);
+ mutex_unlock(&inst->lock);
+ return 0;
+}
+
+static long venc_alloc_recon_buffers(struct v4l2_subdev *sd, void *arg)
+{
+ return 0;
+}
+
+static long venc_free_output_buffer(struct v4l2_subdev *sd, void *arg)
+{
+ return 0;
+}
+
+static long venc_flush_buffers(struct v4l2_subdev *sd, void *arg)
+{
+ return 0;
+}
+
+static long venc_free_input_buffer(struct v4l2_subdev *sd, void *arg)
+{
+ return 0;
+}
+
+static long venc_free_recon_buffers(struct v4l2_subdev *sd, void *arg)
+{
+ return 0;
+}
+
+static long venc_set_property(struct v4l2_subdev *sd, void *arg)
+{
+ return 0;
+}
+
+static long venc_get_property(struct v4l2_subdev *sd, void *arg)
+{
+ return 0;
+}
+
+static long venc_mmap(struct v4l2_subdev *sd, void *arg)
+{
+ struct mem_region_map *mmap = arg;
+ struct mem_region *mregion;
+
+ mregion = mmap->mregion;
+ mregion->paddr = mregion->kvaddr;
+ return 0;
+}
+
+static long venc_munmap(struct v4l2_subdev *sd, void *arg)
+{
+ return 0;
+}
+
+static long venc_set_framerate_mode(struct v4l2_subdev *sd,
+ void *arg)
+{
+ return 0;
+}
+
+long venc_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
+{
+ long rc = 0;
+ switch (cmd) {
+ case OPEN:
+ rc = venc_open(sd, arg);
+ break;
+ case CLOSE:
+ rc = venc_close(sd, arg);
+ break;
+ case ENCODE_START:
+ rc = venc_start(sd);
+ break;
+ case ENCODE_FRAME:
+ venc_encode_frame(sd, arg);
+ break;
+ case ENCODE_STOP:
+ rc = venc_stop(sd);
+ break;
+ case SET_PROP:
+ rc = venc_set_property(sd, arg);
+ break;
+ case GET_PROP:
+ rc = venc_get_property(sd, arg);
+ break;
+ case GET_BUFFER_REQ:
+ rc = venc_get_buffer_req(sd, arg);
+ break;
+ case SET_BUFFER_REQ:
+ rc = venc_set_buffer_req(sd, arg);
+ break;
+ case FREE_BUFFER:
+ break;
+ case FILL_OUTPUT_BUFFER:
+ rc = venc_fill_outbuf(sd, arg);
+ break;
+ case SET_FORMAT:
+ rc = venc_set_format(sd, arg);
+ break;
+ case SET_FRAMERATE:
+ rc = venc_set_framerate(sd, arg);
+ break;
+ case SET_INPUT_BUFFER:
+ rc = venc_set_input_buffer(sd, arg);
+ break;
+ case SET_OUTPUT_BUFFER:
+ rc = venc_set_output_buffer(sd, arg);
+ break;
+ case ALLOC_RECON_BUFFERS:
+ rc = venc_alloc_recon_buffers(sd, arg);
+ break;
+ case FREE_OUTPUT_BUFFER:
+ rc = venc_free_output_buffer(sd, arg);
+ break;
+ case FREE_INPUT_BUFFER:
+ rc = venc_free_input_buffer(sd, arg);
+ break;
+ case FREE_RECON_BUFFERS:
+ rc = venc_free_recon_buffers(sd, arg);
+ break;
+ case ENCODE_FLUSH:
+ rc = venc_flush_buffers(sd, arg);
+ break;
+ case ENC_MMAP:
+ rc = venc_mmap(sd, arg);
+ break;
+ case ENC_MUNMAP:
+ rc = venc_munmap(sd, arg);
+ break;
+ case SET_FRAMERATE_MODE:
+ rc = venc_set_framerate_mode(sd, arg);
+ break;
+ default:
+ WFD_MSG_ERR("Unknown ioctl %d to enc-subdev\n", cmd);
+ rc = -ENOTSUPP;
+ break;
+ }
+ return rc;
+}
diff --git a/drivers/media/platform/msm/wfd/enc-venus-subdev.c b/drivers/media/platform/msm/wfd/enc-venus-subdev.c
index e6568f1..6f87482 100644
--- a/drivers/media/platform/msm/wfd/enc-venus-subdev.c
+++ b/drivers/media/platform/msm/wfd/enc-venus-subdev.c
@@ -266,13 +266,24 @@
static long set_default_properties(struct venc_inst *inst)
{
struct v4l2_control ctrl = {0};
+ int rc;
/* Set the IDR period as 1. The venus core doesn't give
* the sps/pps for I-frames, only IDR. */
ctrl.id = V4L2_CID_MPEG_VIDC_VIDEO_IDR_PERIOD;
ctrl.value = 1;
+ rc = msm_vidc_s_ctrl(inst->vidc_context, &ctrl);
+ if (rc)
+ WFD_MSG_WARN("Failed to set IDR period\n");
- return msm_vidc_s_ctrl(inst->vidc_context, &ctrl);
+ /* Set the default rc mode to VBR/VFR, client can change later */
+ ctrl.id = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL;
+ ctrl.value = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_VBR_VFR;
+ rc = msm_vidc_s_ctrl(inst->vidc_context, &ctrl);
+ if (rc)
+ WFD_MSG_WARN("Failed to set rc mode\n");
+
+ return 0;
}
static int subscribe_events(struct venc_inst *inst)
@@ -666,6 +677,33 @@
return rc;
}
+#ifdef CONFIG_MSM_WFD_DEBUG
+static void *venc_map_kernel(struct ion_client *client,
+ struct ion_handle *handle)
+{
+ return ion_map_kernel(client, handle);
+}
+
+static void venc_unmap_kernel(struct ion_client *client,
+ struct ion_handle *handle)
+{
+ ion_unmap_kernel(client, handle);
+}
+#else
+
+static void *venc_map_kernel(struct ion_client *client,
+ struct ion_handle *handle)
+{
+ return NULL;
+}
+
+static void venc_unmap_kernel(struct ion_client *client,
+ struct ion_handle *handle)
+{
+ return;
+}
+#endif
+
static int venc_map_user_to_kernel(struct venc_inst *inst,
struct mem_region *mregion)
{
@@ -700,18 +738,8 @@
goto venc_map_fail;
}
- if (!inst->secure) {
- mregion->kvaddr = ion_map_kernel(venc_ion_client,
- mregion->ion_handle);
- if (IS_ERR_OR_NULL(mregion->kvaddr)) {
- WFD_MSG_ERR("Failed to map buffer into kernel\n");
- rc = PTR_ERR(mregion->kvaddr);
- mregion->kvaddr = NULL;
- goto venc_map_fail;
- }
- } else {
- mregion->kvaddr = NULL;
- }
+ mregion->kvaddr = inst->secure ? NULL :
+ venc_map_kernel(venc_ion_client, mregion->ion_handle);
if (inst->secure) {
rc = msm_ion_secure_buffer(venc_ion_client,
@@ -748,8 +776,8 @@
if (inst->secure)
msm_ion_unsecure_buffer(venc_ion_client, mregion->ion_handle);
venc_map_iommu_map_fail:
- if (!inst->secure)
- ion_unmap_kernel(venc_ion_client, mregion->ion_handle);
+ if (!inst->secure && !IS_ERR_OR_NULL(mregion->kvaddr))
+ venc_unmap_kernel(venc_ion_client, mregion->ion_handle);
venc_map_fail:
return rc;
}
@@ -782,8 +810,8 @@
mregion->paddr = NULL;
}
- if (mregion->kvaddr) {
- ion_unmap_kernel(venc_ion_client, mregion->ion_handle);
+ if (!IS_ERR_OR_NULL(mregion->kvaddr)) {
+ venc_unmap_kernel(venc_ion_client, mregion->ion_handle);
mregion->kvaddr = NULL;
}
diff --git a/drivers/media/platform/msm/wfd/mdp-5-subdev.c b/drivers/media/platform/msm/wfd/mdp-5-subdev.c
index 6399117..97204ae 100644
--- a/drivers/media/platform/msm/wfd/mdp-5-subdev.c
+++ b/drivers/media/platform/msm/wfd/mdp-5-subdev.c
@@ -73,7 +73,7 @@
mops->cookie = inst;
return 0;
mdp_secure_fail:
- msm_fb_writeback_terminate(inst->mdp);
+ msm_fb_writeback_terminate(fbi);
mdp_open_fail:
kfree(inst);
return rc;
@@ -83,19 +83,12 @@
{
struct mdp_instance *inst = arg;
int rc = 0;
- struct fb_info *fbi = NULL;
if (inst) {
rc = msm_fb_writeback_start(inst->mdp);
if (rc) {
WFD_MSG_ERR("Failed to start MDP mode\n");
goto exit;
}
- fbi = msm_fb_get_writeback_fb();
- if (!fbi) {
- WFD_MSG_ERR("Failed to acquire mdp instance\n");
- rc = -ENODEV;
- goto exit;
- }
}
exit:
return rc;
@@ -105,7 +98,6 @@
{
struct mdp_instance *inst = arg;
int rc = 0;
- struct fb_info *fbi = NULL;
if (inst) {
rc = msm_fb_writeback_stop(inst->mdp);
if (rc) {
@@ -113,7 +105,6 @@
return rc;
}
- fbi = (struct fb_info *)inst->mdp;
}
return 0;
}
@@ -121,12 +112,10 @@
static int mdp_close(struct v4l2_subdev *sd, void *arg)
{
struct mdp_instance *inst = arg;
- struct fb_info *fbi = NULL;
if (inst) {
- fbi = (struct fb_info *)inst->mdp;
if (inst->secure)
msm_fb_writeback_set_secure(inst->mdp, false);
- msm_fb_writeback_terminate(fbi);
+ msm_fb_writeback_terminate(inst->mdp);
kfree(inst);
}
return 0;
diff --git a/drivers/media/platform/msm/wfd/mdp-dummy-subdev.c b/drivers/media/platform/msm/wfd/mdp-dummy-subdev.c
index 10ba3c3..46977a6 100644
--- a/drivers/media/platform/msm/wfd/mdp-dummy-subdev.c
+++ b/drivers/media/platform/msm/wfd/mdp-dummy-subdev.c
@@ -19,6 +19,10 @@
#include "mdp-subdev.h"
#include "wfd-util.h"
+#ifndef CONFIG_MSM_WFD_DEBUG
+#error "Dummy subdevice must only be used when CONFIG_MSM_WFD_DEBUG=y"
+#endif
+
struct mdp_buf_queue {
struct mdp_buf_info mdp_buf_info;
struct list_head node;
diff --git a/drivers/media/platform/msm/wfd/wfd-ioctl.c b/drivers/media/platform/msm/wfd/wfd-ioctl.c
index cc309aa..30a666d 100644
--- a/drivers/media/platform/msm/wfd/wfd-ioctl.c
+++ b/drivers/media/platform/msm/wfd/wfd-ioctl.c
@@ -158,11 +158,36 @@
return (unsigned long)NULL;
}
+#ifdef CONFIG_MSM_WFD_DEBUG
+static void *wfd_map_kernel(struct ion_client *client,
+ struct ion_handle *handle)
+{
+ return ion_map_kernel(client, handle);
+}
+
+static void wfd_unmap_kernel(struct ion_client *client,
+ struct ion_handle *handle)
+{
+ ion_unmap_kernel(client, handle);
+}
+#else
+static void *wfd_map_kernel(struct ion_client *client,
+ struct ion_handle *handle)
+{
+ return NULL;
+}
+
+static void wfd_unmap_kernel(struct ion_client *client,
+ struct ion_handle *handle)
+{
+ return;
+}
+#endif
+
static int wfd_allocate_ion_buffer(struct ion_client *client,
bool secure, struct mem_region *mregion)
{
struct ion_handle *handle = NULL;
- void *kvaddr = NULL;
unsigned int alloc_regions = 0, ion_flags = 0, align = 0;
int rc = 0;
@@ -184,26 +209,14 @@
goto alloc_fail;
}
- if (!secure) {
- kvaddr = ion_map_kernel(client, handle);
-
- if (IS_ERR_OR_NULL(kvaddr)) {
- WFD_MSG_ERR("Failed to get virtual addr\n");
- rc = PTR_ERR(kvaddr);
- goto alloc_fail;
- }
- } else {
- kvaddr = NULL;
- }
-
- mregion->kvaddr = kvaddr;
+ mregion->kvaddr = secure ? NULL :
+ wfd_map_kernel(client, handle);
mregion->ion_handle = handle;
-
return rc;
alloc_fail:
if (!IS_ERR_OR_NULL(handle)) {
- if (!IS_ERR_OR_NULL(kvaddr))
- ion_unmap_kernel(client, handle);
+ if (!IS_ERR_OR_NULL(mregion->kvaddr))
+ wfd_unmap_kernel(client, handle);
ion_free(client, handle);
@@ -223,8 +236,10 @@
"Invalid client or region");
return -EINVAL;
}
- if (mregion->kvaddr)
- ion_unmap_kernel(client, mregion->ion_handle);
+
+ if (!IS_ERR_OR_NULL(mregion->kvaddr))
+ wfd_unmap_kernel(client, mregion->ion_handle);
+
ion_free(client, mregion->ion_handle);
return 0;
}
diff --git a/drivers/of/of_slimbus.c b/drivers/of/of_slimbus.c
index 9692185..234a5eb 100644
--- a/drivers/of/of_slimbus.c
+++ b/drivers/of/of_slimbus.c
@@ -22,6 +22,7 @@
{
struct device_node *node;
struct slim_boardinfo *binfo = NULL;
+ struct slim_boardinfo *temp;
int n = 0;
int ret = 0;
@@ -58,14 +59,16 @@
}
memcpy(slim->e_addr, prop->value, 6);
- binfo = krealloc(binfo, (n + 1) * sizeof(struct slim_boardinfo),
+ temp = krealloc(binfo, (n + 1) * sizeof(struct slim_boardinfo),
GFP_KERNEL);
- if (!binfo) {
+ if (!temp) {
dev_err(&ctrl->dev, "out of memory");
kfree(name);
kfree(slim);
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto of_slim_err;
}
+ binfo = temp;
slim->dev.of_node = of_node_get(node);
slim->name = (const char *)name;
@@ -73,13 +76,15 @@
binfo[n].slim_slave = slim;
n++;
}
- return slim_register_board_info(binfo, n);
+ ret = slim_register_board_info(binfo, n);
+ if (!ret)
+ goto of_slim_ret;
of_slim_err:
- n--;
- while (n >= 0) {
+ while (n-- > 0) {
kfree(binfo[n].slim_slave->name);
kfree(binfo[n].slim_slave);
}
+of_slim_ret:
kfree(binfo);
return ret;
}
diff --git a/drivers/platform/msm/usb_bam.c b/drivers/platform/msm/usb_bam.c
index 55cbfe9..6b77609 100644
--- a/drivers/platform/msm/usb_bam.c
+++ b/drivers/platform/msm/usb_bam.c
@@ -968,6 +968,8 @@
(int)hsic_host_dev);
pm_runtime_put(hsic_host_dev);
info.in_lpm[HSIC_BAM] = true;
+ /* In case consumer release before resume happned */
+ hsic_host_dev_resumed_from_cons_request = false;
}
}
diff --git a/drivers/power/qpnp-charger.c b/drivers/power/qpnp-charger.c
index 9a53367..476aaa2 100644
--- a/drivers/power/qpnp-charger.c
+++ b/drivers/power/qpnp-charger.c
@@ -2063,6 +2063,8 @@
chip->flags |= CHG_FLAGS_VCP_WA;
if (chip->type == SMBB)
chip->flags |= BOOST_FLASH_WA;
+ if (chip->type == SMBBP)
+ chip->flags |= BOOST_FLASH_WA;
}
static int
diff --git a/drivers/slimbus/slim-msm-ngd.c b/drivers/slimbus/slim-msm-ngd.c
index 86ae8db..6962d53 100644
--- a/drivers/slimbus/slim-msm-ngd.c
+++ b/drivers/slimbus/slim-msm-ngd.c
@@ -9,7 +9,6 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
-
#include <linux/irq.h>
#include <linux/kernel.h>
#include <linux/init.h>
@@ -222,7 +221,7 @@
u8 *puc;
int ret = 0;
u8 la = txn->la;
- u8 wbuf[SLIM_RX_MSGQ_BUF_LEN];
+ u8 wbuf[SLIM_MSGQ_BUF_LEN];
if (!pm_runtime_enabled(dev->dev) && dev->state == MSM_CTRL_ASLEEP &&
txn->mc != SLIM_USR_MC_REPORT_SATELLITE) {
@@ -235,17 +234,14 @@
*/
ngd_slim_runtime_resume(dev->dev);
}
- if (txn->mc == (SLIM_MSG_CLK_PAUSE_SEQ_FLG |
- SLIM_MSG_MC_RECONFIGURE_NOW)) {
- if (dev->use_rx_msgqs == MSM_MSGQ_ENABLED) {
- ret = sps_disconnect(dev->rx_msgq.sps);
- dev->use_rx_msgqs = MSM_MSGQ_RESET;
- }
- if (!ret)
- ret = msm_slim_qmi_power_request(dev, false);
- else
- pr_err("SPS pipe disconnect error:%d", ret);
- return ret;
+ if ((txn->mc == (SLIM_MSG_CLK_PAUSE_SEQ_FLG |
+ SLIM_MSG_MC_RECONFIGURE_NOW)) &&
+ dev->state <= MSM_CTRL_SLEEPING) {
+ msm_slim_disconnect_endp(dev, &dev->rx_msgq,
+ &dev->use_rx_msgqs);
+ msm_slim_disconnect_endp(dev, &dev->tx_msgq,
+ &dev->use_tx_msgqs);
+ return msm_slim_qmi_power_request(dev, false);
}
else if (txn->mc & SLIM_MSG_CLK_PAUSE_SEQ_FLG)
return 0;
@@ -389,10 +385,19 @@
NGD_BASE(dev->ctrl.nr, dev->ver) + NGD_TX_MSG);
if (!ret) {
int timeout = wait_for_completion_timeout(&tx_sent, HZ);
- if (!timeout)
+ if (!timeout) {
ret = -ETIMEDOUT;
- else
+ /*
+ * disconnect/recoonect pipe so that subsequent
+ * transactions don't timeout due to unavailable
+ * descriptors
+ */
+ msm_slim_disconnect_endp(dev, &dev->tx_msgq,
+ &dev->use_tx_msgqs);
+ msm_slim_connect_endp(dev, &dev->tx_msgq, NULL);
+ } else {
ret = dev->err;
+ }
}
dev->wr_comp = NULL;
if (ret) {
@@ -469,7 +474,7 @@
struct slim_msg_txn txn;
struct slim_controller *ctrl = sb->ctrl;
DECLARE_COMPLETION_ONSTACK(done);
- u8 wbuf[SLIM_RX_MSGQ_BUF_LEN];
+ u8 wbuf[SLIM_MSGQ_BUF_LEN];
*clkgear = ctrl->clkgear;
*subfrmc = 0;
@@ -631,24 +636,26 @@
return ret;
}
-static void ngd_slim_setup_rx_path(struct msm_slim_ctrl *dev)
+static void ngd_slim_setup_msg_path(struct msm_slim_ctrl *dev)
{
- int ret;
if (dev->state == MSM_CTRL_DOWN) {
msm_slim_sps_init(dev, dev->bam_mem,
NGD_BASE(dev->ctrl.nr,
dev->ver) + NGD_STATUS, true);
} else {
if (dev->use_rx_msgqs == MSM_MSGQ_DISABLED)
- return;
- ret = msm_slim_connect_endp(dev, &dev->rx_msgq,
+ goto setup_tx_msg_path;
+ msm_slim_connect_endp(dev, &dev->rx_msgq,
&dev->rx_msgq_notify);
- if (!ret)
- dev->use_rx_msgqs = MSM_MSGQ_ENABLED;
- else
- pr_err("RX msgq not being used:%d", ret);
+
+setup_tx_msg_path:
+ if (dev->use_tx_msgqs == MSM_MSGQ_DISABLED)
+ return;
+ msm_slim_connect_endp(dev, &dev->tx_msgq,
+ NULL);
}
}
+
static void ngd_slim_rx(struct msm_slim_ctrl *dev, u8 *buf)
{
u8 mc, mt, len;
@@ -677,9 +684,11 @@
txn.len = 4;
pr_info("SLIM SAT: Received master capability");
if (dev->state >= MSM_CTRL_ASLEEP) {
- ngd_slim_setup_rx_path(dev);
+ ngd_slim_setup_msg_path(dev);
if (dev->use_rx_msgqs == MSM_MSGQ_ENABLED)
msgq_en |= NGD_CFG_RX_MSGQ_EN;
+ if (dev->use_tx_msgqs == MSM_MSGQ_ENABLED)
+ msgq_en |= NGD_CFG_TX_MSGQ_EN;
writel_relaxed(msgq_en, dev->base +
NGD_BASE(dev->ctrl.nr, dev->ver));
/* make sure NGD MSG-Q config goes through */
@@ -793,7 +802,7 @@
* ADSP power collapse case, where HW wasn't reset.
* Reconnect BAM pipes if disconnected
*/
- ngd_slim_setup_rx_path(dev);
+ ngd_slim_setup_msg_path(dev);
return 0;
} else if (cur_state != MSM_CTRL_DOWN) {
pr_info("ADSP P.C. CTRL state:%d NGD not enumerated:0x%x",
@@ -806,6 +815,12 @@
sps_free_endpoint(endpoint->sps);
dev->use_rx_msgqs = MSM_MSGQ_RESET;
}
+ if (dev->use_tx_msgqs == MSM_MSGQ_DOWN) {
+ struct msm_slim_endp *endpoint = &dev->tx_msgq;
+ sps_disconnect(endpoint->sps);
+ sps_free_endpoint(endpoint->sps);
+ dev->use_tx_msgqs = MSM_MSGQ_RESET;
+ }
/*
* ADSP power collapse case (OR SSR), where HW was reset
* BAM programming will happen when capability message is received
@@ -957,6 +972,8 @@
/* disconnect BAM pipes */
if (dev->use_rx_msgqs == MSM_MSGQ_ENABLED)
dev->use_rx_msgqs = MSM_MSGQ_DOWN;
+ if (dev->use_tx_msgqs == MSM_MSGQ_ENABLED)
+ dev->use_tx_msgqs = MSM_MSGQ_DOWN;
msm_slim_sps_exit(dev, false);
mutex_lock(&ctrl->m_ctrl);
/* device up should be called again after SSR */
@@ -1083,6 +1100,10 @@
dev->use_rx_msgqs = MSM_MSGQ_DISABLED;
else
dev->use_rx_msgqs = MSM_MSGQ_RESET;
+
+ /* Enable TX message queues by default as recommended by HW */
+ dev->use_tx_msgqs = MSM_MSGQ_RESET;
+
init_completion(&dev->rx_msgq_notify);
/* Register with framework */
diff --git a/drivers/slimbus/slim-msm.c b/drivers/slimbus/slim-msm.c
index 30341e2..0166196 100644
--- a/drivers/slimbus/slim-msm.c
+++ b/drivers/slimbus/slim-msm.c
@@ -269,16 +269,66 @@
return ret;
}
+/* Queue up Tx message buffer */
+static int msm_slim_post_tx_msgq(struct msm_slim_ctrl *dev, u8 *buf, int len)
+{
+ int ret;
+ struct msm_slim_endp *endpoint = &dev->tx_msgq;
+ struct sps_mem_buffer *mem = &endpoint->buf;
+ struct sps_pipe *pipe = endpoint->sps;
+ int ix = (buf - (u8 *)mem->base) / SLIM_MSGQ_BUF_LEN;
+
+ u32 phys_addr = mem->phys_base + (SLIM_MSGQ_BUF_LEN * ix);
+
+ for (ret = 0; ret < ((len + 3) >> 2); ret++)
+ pr_debug("BAM TX buf[%d]:0x%x", ret, ((u32 *)buf)[ret]);
+
+ ret = sps_transfer_one(pipe, phys_addr, ((len + 3) & 0xFC), NULL,
+ SPS_IOVEC_FLAG_EOT);
+ if (ret)
+ dev_err(dev->dev, "transfer_one() failed 0x%x, %d\n", ret, ix);
+
+ return ret;
+}
+
+static u32 *msm_slim_tx_msgq_return(struct msm_slim_ctrl *dev)
+{
+ struct msm_slim_endp *endpoint = &dev->tx_msgq;
+ struct sps_mem_buffer *mem = &endpoint->buf;
+ struct sps_pipe *pipe = endpoint->sps;
+ struct sps_iovec iovec;
+ int ret;
+
+ /* first transaction after establishing connection */
+ if (dev->tx_idx == -1) {
+ dev->tx_idx = 0;
+ return mem->base;
+ }
+ ret = sps_get_iovec(pipe, &iovec);
+ if (ret || iovec.addr == 0) {
+ dev_err(dev->dev, "sps_get_iovec() failed 0x%x\n", ret);
+ return NULL;
+ }
+
+ /* Calculate buffer index */
+ dev->tx_idx = (iovec.addr - mem->phys_base) / SLIM_MSGQ_BUF_LEN;
+
+ return (u32 *)((u8 *)mem->base + (dev->tx_idx * SLIM_MSGQ_BUF_LEN));
+}
+
int msm_send_msg_buf(struct msm_slim_ctrl *dev, u32 *buf, u8 len, u32 tx_reg)
{
- int i;
- for (i = 0; i < (len + 3) >> 2; i++) {
- dev_dbg(dev->dev, "TX data:0x%x\n", buf[i]);
- writel_relaxed(buf[i], dev->base + tx_reg + (i * 4));
+ if (dev->use_tx_msgqs != MSM_MSGQ_ENABLED) {
+ int i;
+ for (i = 0; i < (len + 3) >> 2; i++) {
+ dev_dbg(dev->dev, "AHB TX data:0x%x\n", buf[i]);
+ writel_relaxed(buf[i], dev->base + tx_reg + (i * 4));
+ }
+ /* Guarantee that message is sent before returning */
+ mb();
+ return 0;
}
- /* Guarantee that message is sent before returning */
- mb();
- return 0;
+ return msm_slim_post_tx_msgq(dev, (u8 *)buf, len);
}
u32 *msm_get_msg_buf(struct msm_slim_ctrl *dev, int len)
@@ -287,7 +337,10 @@
* Currently we block a transaction until the current one completes.
* In case we need multiple transactions, use message Q
*/
- return dev->tx_buf;
+ if (dev->use_tx_msgqs != MSM_MSGQ_ENABLED)
+ return dev->tx_buf;
+
+ return msm_slim_tx_msgq_return(dev);
}
static void
@@ -394,15 +447,17 @@
memset(&sps_descr_event, 0x00, sizeof(sps_descr_event));
- sps_descr_event.mode = SPS_TRIGGER_CALLBACK;
- sps_descr_event.options = SPS_O_DESC_DONE;
- sps_descr_event.user = (void *)dev;
- sps_descr_event.xfer_done = notify;
+ if (notify) {
+ sps_descr_event.mode = SPS_TRIGGER_CALLBACK;
+ sps_descr_event.options = SPS_O_DESC_DONE;
+ sps_descr_event.user = (void *)dev;
+ sps_descr_event.xfer_done = notify;
- ret = sps_register_event(endpoint->sps, &sps_descr_event);
- if (ret) {
- dev_err(dev->dev, "sps_connect() failed 0x%x\n", ret);
- goto sps_reg_event_failed;
+ ret = sps_register_event(endpoint->sps, &sps_descr_event);
+ if (ret) {
+ dev_err(dev->dev, "sps_connect() failed 0x%x\n", ret);
+ goto sps_reg_event_failed;
+ }
}
/* Register callback for errors */
@@ -423,13 +478,20 @@
* Use (buf->size/4) - 1 for the number of buffer to post
*/
- /* Setup the transfer */
- for (i = 0; i < (MSM_SLIM_DESC_NUM - 1); i++) {
- ret = msm_slim_post_rx_msgq(dev, i);
- if (ret) {
- dev_err(dev->dev, "post_rx_msgq() failed 0x%x\n", ret);
- goto sps_transfer_failed;
+ if (endpoint == &dev->rx_msgq) {
+ /* Setup the transfer */
+ for (i = 0; i < (MSM_SLIM_DESC_NUM - 1); i++) {
+ ret = msm_slim_post_rx_msgq(dev, i);
+ if (ret) {
+ dev_err(dev->dev,
+ "post_rx_msgq() failed 0x%x\n", ret);
+ goto sps_transfer_failed;
+ }
}
+ dev->use_rx_msgqs = MSM_MSGQ_ENABLED;
+ } else {
+ dev->tx_idx = -1;
+ dev->use_tx_msgqs = MSM_MSGQ_ENABLED;
}
return 0;
@@ -440,6 +502,7 @@
sps_disconnect(endpoint->sps);
return ret;
}
+
static int msm_slim_init_rx_msgq(struct msm_slim_ctrl *dev, u32 pipe_reg)
{
int ret;
@@ -489,10 +552,8 @@
ret = msm_slim_connect_endp(dev, endpoint, notify);
- if (!ret) {
- dev->use_rx_msgqs = MSM_MSGQ_ENABLED;
+ if (!ret)
return 0;
- }
msm_slim_sps_mem_free(dev, mem);
alloc_buffer_failed:
@@ -504,6 +565,67 @@
return ret;
}
+static int msm_slim_init_tx_msgq(struct msm_slim_ctrl *dev, u32 pipe_reg)
+{
+ int ret;
+ u32 pipe_offset;
+ struct msm_slim_endp *endpoint = &dev->tx_msgq;
+ struct sps_connect *config = &endpoint->config;
+ struct sps_mem_buffer *descr = &config->desc;
+ struct sps_mem_buffer *mem = &endpoint->buf;
+
+ if (dev->use_tx_msgqs == MSM_MSGQ_DISABLED)
+ return 0;
+
+ /* Allocate the endpoint */
+ ret = msm_slim_init_endpoint(dev, endpoint);
+ if (ret) {
+ dev_err(dev->dev, "init_endpoint failed 0x%x\n", ret);
+ goto sps_init_endpoint_failed;
+ }
+
+ /* Get the pipe indices for the message queues */
+ pipe_offset = (readl_relaxed(dev->base + pipe_reg) & 0xfc) >> 2;
+ pipe_offset += 1;
+ dev_dbg(dev->dev, "TX Message queue pipe offset %d\n", pipe_offset);
+
+ config->mode = SPS_MODE_DEST;
+ config->source = SPS_DEV_HANDLE_MEM;
+ config->destination = dev->bam.hdl;
+ config->dest_pipe_index = pipe_offset;
+ config->src_pipe_index = 0;
+ config->options = SPS_O_ERROR | SPS_O_NO_Q |
+ SPS_O_ACK_TRANSFERS | SPS_O_AUTO_ENABLE;
+
+ /* Allocate memory for the FIFO descriptors */
+ ret = msm_slim_sps_mem_alloc(dev, descr,
+ MSM_TX_BUFS * sizeof(struct sps_iovec));
+ if (ret) {
+ dev_err(dev->dev, "unable to allocate SPS descriptors\n");
+ goto alloc_descr_failed;
+ }
+
+ /* Allocate memory for the message buffer(s), N descrs, 40-byte mesg */
+ ret = msm_slim_sps_mem_alloc(dev, mem, MSM_TX_BUFS * SLIM_MSGQ_BUF_LEN);
+ if (ret) {
+ dev_err(dev->dev, "dma_alloc_coherent failed\n");
+ goto alloc_buffer_failed;
+ }
+ ret = msm_slim_connect_endp(dev, endpoint, NULL);
+
+ if (!ret)
+ return 0;
+
+ msm_slim_sps_mem_free(dev, mem);
+alloc_buffer_failed:
+ msm_slim_sps_mem_free(dev, descr);
+alloc_descr_failed:
+ msm_slim_free_endpoint(endpoint);
+sps_init_endpoint_failed:
+ dev->use_tx_msgqs = MSM_MSGQ_DISABLED;
+ return ret;
+}
+
/* Registers BAM h/w resource with SPS driver and initializes msgq endpoints */
int msm_slim_sps_init(struct msm_slim_ctrl *dev, struct resource *bam_mem,
u32 pipe_reg, bool remote)
@@ -529,8 +651,10 @@
},
};
- if (dev->bam.hdl)
- goto init_rx_msgq;
+ if (dev->bam.hdl) {
+ bam_handle = dev->bam.hdl;
+ goto init_msgq;
+ }
bam_props.ee = dev->ee;
bam_props.virt_addr = dev->bam.base;
bam_props.phys_addr = bam_mem->start;
@@ -563,40 +687,68 @@
if (ret) {
dev_err(dev->dev, "disabling BAM: reg-bam failed 0x%x\n", ret);
dev->use_rx_msgqs = MSM_MSGQ_DISABLED;
- goto init_rx_msgq;
+ dev->use_tx_msgqs = MSM_MSGQ_DISABLED;
+ return ret;
}
dev->bam.hdl = bam_handle;
dev_dbg(dev->dev, "SLIM BAM registered, handle = 0x%x\n", bam_handle);
-init_rx_msgq:
+init_msgq:
ret = msm_slim_init_rx_msgq(dev, pipe_reg);
if (ret)
dev_err(dev->dev, "msm_slim_init_rx_msgq failed 0x%x\n", ret);
- if (ret && bam_handle) {
+ if (ret && bam_handle)
+ dev->use_rx_msgqs = MSM_MSGQ_DISABLED;
+
+ ret = msm_slim_init_tx_msgq(dev, pipe_reg);
+ if (ret)
+ dev_err(dev->dev, "msm_slim_init_tx_msgq failed 0x%x\n", ret);
+ if (ret && bam_handle)
+ dev->use_tx_msgqs = MSM_MSGQ_DISABLED;
+
+ if (dev->use_tx_msgqs == MSM_MSGQ_DISABLED &&
+ dev->use_rx_msgqs == MSM_MSGQ_DISABLED && bam_handle) {
sps_deregister_bam_device(bam_handle);
dev->bam.hdl = 0L;
}
+
return ret;
}
+void msm_slim_disconnect_endp(struct msm_slim_ctrl *dev,
+ struct msm_slim_endp *endpoint,
+ enum msm_slim_msgq *msgq_flag)
+{
+ if (*msgq_flag == MSM_MSGQ_ENABLED) {
+ sps_disconnect(endpoint->sps);
+ *msgq_flag = MSM_MSGQ_RESET;
+ }
+}
+
+static void msm_slim_remove_ep(struct msm_slim_ctrl *dev,
+ struct msm_slim_endp *endpoint,
+ enum msm_slim_msgq *msgq_flag)
+{
+ struct sps_connect *config = &endpoint->config;
+ struct sps_mem_buffer *descr = &config->desc;
+ struct sps_mem_buffer *mem = &endpoint->buf;
+ struct sps_register_event sps_event;
+ memset(&sps_event, 0x00, sizeof(sps_event));
+ msm_slim_sps_mem_free(dev, mem);
+ sps_register_event(endpoint->sps, &sps_event);
+ if (*msgq_flag == MSM_MSGQ_ENABLED) {
+ msm_slim_disconnect_endp(dev, endpoint, msgq_flag);
+ msm_slim_free_endpoint(endpoint);
+ }
+ msm_slim_sps_mem_free(dev, descr);
+}
+
void msm_slim_sps_exit(struct msm_slim_ctrl *dev, bool dereg)
{
- if (dev->use_rx_msgqs >= MSM_MSGQ_ENABLED) {
- struct msm_slim_endp *endpoint = &dev->rx_msgq;
- struct sps_connect *config = &endpoint->config;
- struct sps_mem_buffer *descr = &config->desc;
- struct sps_mem_buffer *mem = &endpoint->buf;
- struct sps_register_event sps_event;
- memset(&sps_event, 0x00, sizeof(sps_event));
- msm_slim_sps_mem_free(dev, mem);
- sps_register_event(endpoint->sps, &sps_event);
- if (dev->use_rx_msgqs == MSM_MSGQ_ENABLED) {
- sps_disconnect(endpoint->sps);
- msm_slim_free_endpoint(endpoint);
- dev->use_rx_msgqs = MSM_MSGQ_RESET;
- }
- msm_slim_sps_mem_free(dev, descr);
- }
+ if (dev->use_rx_msgqs >= MSM_MSGQ_ENABLED)
+ msm_slim_remove_ep(dev, &dev->rx_msgq, &dev->use_rx_msgqs);
+ if (dev->use_tx_msgqs >= MSM_MSGQ_ENABLED)
+ msm_slim_remove_ep(dev, &dev->tx_msgq, &dev->use_tx_msgqs);
if (dereg) {
sps_deregister_bam_device(dev->bam.hdl);
dev->bam.hdl = 0L;
diff --git a/drivers/slimbus/slim-msm.h b/drivers/slimbus/slim-msm.h
index cf2d26f..f8f625e 100644
--- a/drivers/slimbus/slim-msm.h
+++ b/drivers/slimbus/slim-msm.h
@@ -17,7 +17,9 @@
#include <mach/msm_qmi_interface.h>
/* Per spec.max 40 bytes per received message */
-#define SLIM_RX_MSGQ_BUF_LEN 40
+#define SLIM_MSGQ_BUF_LEN 40
+
+#define MSM_TX_BUFS 2
#define SLIM_USR_MC_GENERIC_ACK 0x25
#define SLIM_USR_MC_MASTER_CAPABILITY 0x0
@@ -200,7 +202,8 @@
u32 curr_bw;
u8 msg_cnt;
u32 tx_buf[10];
- u8 rx_msgs[MSM_CONCUR_MSG][SLIM_RX_MSGQ_BUF_LEN];
+ u8 rx_msgs[MSM_CONCUR_MSG][SLIM_MSGQ_BUF_LEN];
+ int tx_idx;
spinlock_t rx_lock;
int head;
int tail;
@@ -211,6 +214,7 @@
struct msm_slim_sat *satd[MSM_MAX_NSATS];
struct msm_slim_endp pipes[7];
struct msm_slim_sps_bam bam;
+ struct msm_slim_endp tx_msgq;
struct msm_slim_endp rx_msgq;
struct completion rx_msgq_notify;
struct task_struct *rx_msgq_thread;
@@ -219,6 +223,7 @@
struct mutex tx_lock;
u8 pgdla;
enum msm_slim_msgq use_rx_msgqs;
+ enum msm_slim_msgq use_tx_msgqs;
int pipe_b;
struct completion reconf;
bool reconf_busy;
@@ -285,6 +290,9 @@
int msm_slim_connect_endp(struct msm_slim_ctrl *dev,
struct msm_slim_endp *endpoint,
struct completion *notify);
+void msm_slim_disconnect_endp(struct msm_slim_ctrl *dev,
+ struct msm_slim_endp *endpoint,
+ enum msm_slim_msgq *msgq_flag);
void msm_slim_qmi_exit(struct msm_slim_ctrl *dev);
int msm_slim_qmi_init(struct msm_slim_ctrl *dev, bool apps_is_master);
int msm_slim_qmi_power_request(struct msm_slim_ctrl *dev, bool active);
diff --git a/drivers/thermal/msm_thermal.c b/drivers/thermal/msm_thermal.c
index 51a11a4..03c58a2 100644
--- a/drivers/thermal/msm_thermal.c
+++ b/drivers/thermal/msm_thermal.c
@@ -608,7 +608,8 @@
return ret;
}
-static void __cpuinit do_core_control(long temp)
+#ifdef CONFIG_SMP
+static void __ref do_core_control(long temp)
{
int i = 0;
int ret = 0;
@@ -657,6 +658,12 @@
}
mutex_unlock(&core_control_mutex);
}
+#else
+static void do_core_control(long temp)
+{
+ return;
+}
+#endif
static int do_vdd_restriction(void)
{
@@ -755,7 +762,7 @@
return ret;
}
-static void __cpuinit do_freq_control(long temp)
+static void __ref do_freq_control(long temp)
{
int ret = 0;
int cpu = 0;
@@ -798,7 +805,7 @@
}
-static void __cpuinit check_temp(struct work_struct *work)
+static void __ref check_temp(struct work_struct *work)
{
static int limit_init;
struct tsens_device tsens_dev;
@@ -832,7 +839,7 @@
msecs_to_jiffies(msm_thermal_info.poll_ms));
}
-static int __cpuinit msm_thermal_cpu_callback(struct notifier_block *nfb,
+static int __ref msm_thermal_cpu_callback(struct notifier_block *nfb,
unsigned long action, void *hcpu)
{
unsigned int cpu = (unsigned long)hcpu;
@@ -894,7 +901,7 @@
* status will be carried over to the process stopping the msm_thermal, as
* we dont want to online a core and bring in the thermal issues.
*/
-static void __cpuinit disable_msm_thermal(void)
+static void __ref disable_msm_thermal(void)
{
int cpu = 0;
@@ -910,7 +917,7 @@
}
}
-static int __cpuinit set_enabled(const char *val, const struct kernel_param *kp)
+static int __ref set_enabled(const char *val, const struct kernel_param *kp)
{
int ret = 0;
@@ -935,8 +942,9 @@
MODULE_PARM_DESC(enabled, "enforce thermal limit on cpu");
+#ifdef CONFIG_SMP
/* Call with core_control_mutex locked */
-static int __cpuinit update_offline_cores(int val)
+static int __ref update_offline_cores(int val)
{
int cpu = 0;
int ret = 0;
@@ -957,6 +965,12 @@
}
return ret;
}
+#else
+static int update_offline_cores(int val)
+{
+ return 0;
+}
+#endif
static ssize_t show_cc_enabled(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
@@ -964,7 +978,7 @@
return snprintf(buf, PAGE_SIZE, "%d\n", core_control_enabled);
}
-static ssize_t __cpuinit store_cc_enabled(struct kobject *kobj,
+static ssize_t __ref store_cc_enabled(struct kobject *kobj,
struct kobj_attribute *attr, const char *buf, size_t count)
{
int ret = 0;
@@ -1001,7 +1015,7 @@
return snprintf(buf, PAGE_SIZE, "%d\n", cpus_offlined);
}
-static ssize_t __cpuinit store_cpus_offlined(struct kobject *kobj,
+static ssize_t __ref store_cpus_offlined(struct kobject *kobj,
struct kobj_attribute *attr, const char *buf, size_t count)
{
int ret = 0;
@@ -1029,19 +1043,19 @@
return count;
}
-static __cpuinitdata struct kobj_attribute cc_enabled_attr =
+static __refdata struct kobj_attribute cc_enabled_attr =
__ATTR(enabled, 0644, show_cc_enabled, store_cc_enabled);
-static __cpuinitdata struct kobj_attribute cpus_offlined_attr =
+static __refdata struct kobj_attribute cpus_offlined_attr =
__ATTR(cpus_offlined, 0644, show_cpus_offlined, store_cpus_offlined);
-static __cpuinitdata struct attribute *cc_attrs[] = {
+static __refdata struct attribute *cc_attrs[] = {
&cc_enabled_attr.attr,
&cpus_offlined_attr.attr,
NULL,
};
-static __cpuinitdata struct attribute_group cc_attr_group = {
+static __refdata struct attribute_group cc_attr_group = {
.attrs = cc_attrs,
};
@@ -1079,15 +1093,15 @@
return count;
}
-static __cpuinitdata struct kobj_attribute timer_attr =
+static __refdata struct kobj_attribute timer_attr =
__ATTR(wakeup_ms, 0644, show_wakeup_ms, store_wakeup_ms);
-static __cpuinitdata struct attribute *tt_attrs[] = {
+static __refdata struct attribute *tt_attrs[] = {
&timer_attr.attr,
NULL,
};
-static __cpuinitdata struct attribute_group tt_attr_group = {
+static __refdata struct attribute_group tt_attr_group = {
.attrs = tt_attrs,
};
@@ -1176,11 +1190,13 @@
return -EINVAL;
enabled = 1;
- core_control_enabled = 1;
+ if (num_possible_cpus() > 1)
+ core_control_enabled = 1;
INIT_DELAYED_WORK(&check_temp_work, check_temp);
schedule_delayed_work(&check_temp_work, 0);
- register_cpu_notifier(&msm_thermal_cpu_notifier);
+ if (num_possible_cpus() > 1)
+ register_cpu_notifier(&msm_thermal_cpu_notifier);
return ret;
}
@@ -1690,7 +1706,8 @@
int __init msm_thermal_late_init(void)
{
- msm_thermal_add_cc_nodes();
+ if (num_possible_cpus() > 1)
+ msm_thermal_add_cc_nodes();
msm_thermal_add_psm_nodes();
msm_thermal_add_vdd_rstr_nodes();
alarm_init(&thermal_rtc, ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP,
diff --git a/drivers/usb/gadget/ci13xxx_udc.c b/drivers/usb/gadget/ci13xxx_udc.c
index a258c30..939eb6d 100644
--- a/drivers/usb/gadget/ci13xxx_udc.c
+++ b/drivers/usb/gadget/ci13xxx_udc.c
@@ -1979,6 +1979,7 @@
for (i = 1; i < 5; i++)
mReq->ptr->page[i] = (mReq->req.dma + i * CI13XXX_PAGE_SIZE) &
~TD_RESERVED_MASK;
+ wmb();
/* Remote Wakeup */
if (udc->suspended) {
diff --git a/drivers/usb/gadget/ci13xxx_udc.h b/drivers/usb/gadget/ci13xxx_udc.h
index 1530474..4c5b38d 100644
--- a/drivers/usb/gadget/ci13xxx_udc.h
+++ b/drivers/usb/gadget/ci13xxx_udc.h
@@ -57,7 +57,7 @@
#define TD_CURR_OFFSET (0x0FFFUL << 0)
#define TD_FRAME_NUM (0x07FFUL << 0)
#define TD_RESERVED_MASK (0x0FFFUL << 0)
-} __attribute__ ((packed));
+} __attribute__ ((packed, aligned(4)));
/* DMA layout of queue heads */
struct ci13xxx_qh {
@@ -75,7 +75,7 @@
/* 9 */
u32 RESERVED;
struct usb_ctrlrequest setup;
-} __attribute__ ((packed));
+} __attribute__ ((packed, aligned(4)));
/* cache of larger request's original attributes */
struct ci13xxx_multi_req {
diff --git a/drivers/usb/host/ehci-msm.c b/drivers/usb/host/ehci-msm.c
index 521ace0..c2e8943 100644
--- a/drivers/usb/host/ehci-msm.c
+++ b/drivers/usb/host/ehci-msm.c
@@ -103,6 +103,7 @@
.bus_resume = ehci_bus_resume,
};
+static u64 msm_ehci_dma_mask = DMA_BIT_MASK(64);
static int ehci_msm_probe(struct platform_device *pdev)
{
struct usb_hcd *hcd;
@@ -111,6 +112,11 @@
dev_dbg(&pdev->dev, "ehci_msm proble\n");
+ if (!pdev->dev.dma_mask)
+ pdev->dev.dma_mask = &msm_ehci_dma_mask;
+ if (!pdev->dev.coherent_dma_mask)
+ pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
+
hcd = usb_create_hcd(&msm_hc_driver, &pdev->dev, dev_name(&pdev->dev));
if (!hcd) {
dev_err(&pdev->dev, "Unable to create HCD\n");
diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c
index 44a7aee..c2c783c 100644
--- a/drivers/usb/otg/msm_otg.c
+++ b/drivers/usb/otg/msm_otg.c
@@ -1498,7 +1498,7 @@
vbus_otg = devm_regulator_get(motg->phy.dev, "vbus_otg");
if (IS_ERR(vbus_otg)) {
pr_err("Unable to get vbus_otg\n");
- return -ENODEV;
+ return PTR_ERR(vbus_otg);
}
}
diff --git a/drivers/video/msm/mdss/dsi_host_v2.c b/drivers/video/msm/mdss/dsi_host_v2.c
index 585f5c4..96f0f8c 100644
--- a/drivers/video/msm/mdss/dsi_host_v2.c
+++ b/drivers/video/msm/mdss/dsi_host_v2.c
@@ -35,8 +35,7 @@
struct completion dma_comp;
int irq_enabled;
spinlock_t irq_lock;
- spinlock_t mdp_lock;
- int mdp_busy;
+
int irq_no;
unsigned char *dsi_base;
struct device dis_dev;
@@ -57,7 +56,6 @@
init_completion(&dsi_host_private->dma_comp);
spin_lock_init(&dsi_host_private->irq_lock);
- spin_lock_init(&dsi_host_private->mdp_lock);
return 0;
}
@@ -140,14 +138,10 @@
unsigned long flags;
spin_lock_irqsave(&dsi_host_private->irq_lock, flags);
- if (dsi_host_private->irq_enabled) {
- pr_debug("%s: IRQ aleady enabled\n", __func__);
- spin_unlock_irqrestore(&dsi_host_private->irq_lock, flags);
- return;
- }
+ dsi_host_private->irq_enabled++;
+ if (dsi_host_private->irq_enabled == 1)
+ enable_irq(dsi_host_private->irq_no);
- enable_irq(dsi_host_private->irq_no);
- dsi_host_private->irq_enabled = 1;
spin_unlock_irqrestore(&dsi_host_private->irq_lock, flags);
}
@@ -156,26 +150,19 @@
unsigned long flags;
spin_lock_irqsave(&dsi_host_private->irq_lock, flags);
- if (dsi_host_private->irq_enabled == 0) {
- pr_debug("%s: IRQ already disabled\n", __func__);
- spin_unlock_irqrestore(&dsi_host_private->irq_lock, flags);
- return;
- }
- disable_irq(dsi_host_private->irq_no);
- dsi_host_private->irq_enabled = 0;
+ dsi_host_private->irq_enabled--;
+ if (dsi_host_private->irq_enabled == 0)
+ disable_irq(dsi_host_private->irq_no);
+
spin_unlock_irqrestore(&dsi_host_private->irq_lock, flags);
}
void msm_dsi_disable_irq_nosync(void)
{
spin_lock(&dsi_host_private->irq_lock);
- if (dsi_host_private->irq_enabled == 0) {
- pr_debug("%s: IRQ cannot be disabled\n", __func__);
- spin_unlock(&dsi_host_private->irq_lock);
- return;
- }
- disable_irq_nosync(dsi_host_private->irq_no);
- dsi_host_private->irq_enabled = 0;
+ dsi_host_private->irq_enabled--;
+ if (dsi_host_private->irq_enabled == 0)
+ disable_irq_nosync(dsi_host_private->irq_no);
spin_unlock(&dsi_host_private->irq_lock);
}
@@ -192,13 +179,6 @@
if (isr & DSI_INTR_CMD_DMA_DONE)
complete(&dsi_host_private->dma_comp);
- if (isr & DSI_INTR_CMD_MDP_DONE) {
- spin_lock(&dsi_host_private->mdp_lock);
- dsi_host_private->mdp_busy = false;
- msm_dsi_disable_irq_nosync();
- spin_unlock(&dsi_host_private->mdp_lock);
- }
-
return IRQ_HANDLED;
}
@@ -448,16 +428,6 @@
wmb();
}
-void msm_dsi_cmd_mdp_start(void)
-{
- unsigned long flag;
-
- spin_lock_irqsave(&dsi_host_private->mdp_lock, flag);
- msm_dsi_enable_irq();
- dsi_host_private->mdp_busy = true;
- spin_unlock_irqrestore(&dsi_host_private->mdp_lock, flag);
-}
-
int msm_dsi_cmd_reg_tx(u32 data)
{
unsigned char *ctrl_base = dsi_host_private->dsi_base;
@@ -551,7 +521,6 @@
struct dsi_cmd_desc *cm;
u32 dsi_ctrl, ctrl;
int i, video_mode;
- unsigned long flag;
unsigned char *ctrl_base = dsi_host_private->dsi_base;
/* turn on cmd mode
@@ -566,13 +535,9 @@
MIPI_OUTP(ctrl_base + DSI_CTRL, ctrl);
}
- spin_lock_irqsave(&dsi_host_private->mdp_lock, flag);
msm_dsi_enable_irq();
- dsi_host_private->mdp_busy = true;
- spin_unlock_irqrestore(&dsi_host_private->mdp_lock, flag);
cm = cmds;
- dsi_buf_init(tp);
for (i = 0; i < cnt; i++) {
dsi_buf_init(tp);
dsi_cmd_dma_add(tp, cm);
@@ -582,10 +547,7 @@
cm++;
}
- spin_lock_irqsave(&dsi_host_private->mdp_lock, flag);
- dsi_host_private->mdp_busy = false;
msm_dsi_disable_irq();
- spin_unlock_irqrestore(&dsi_host_private->mdp_lock, flag);
if (video_mode)
MIPI_OUTP(ctrl_base + DSI_CTRL, dsi_ctrl);
@@ -617,7 +579,6 @@
struct dsi_cmd_desc *cmds, int rlen)
{
int cnt, len, diff, pkt_size;
- unsigned long flag;
char cmd;
if (pdata->panel_info.mipi.no_max_pkt_size)
@@ -645,10 +606,7 @@
cnt = len + 6; /* 4 bytes header + 2 bytes crc */
}
- spin_lock_irqsave(&dsi_host_private->mdp_lock, flag);
msm_dsi_enable_irq();
- dsi_host_private->mdp_busy = true;
- spin_unlock_irqrestore(&dsi_host_private->mdp_lock, flag);
if (!pdata->panel_info.mipi.no_max_pkt_size) {
/* packet size need to be set at every read */
@@ -681,10 +639,7 @@
msm_dsi_cmd_dma_rx(rp, cnt);
- spin_lock_irqsave(&dsi_host_private->mdp_lock, flag);
- dsi_host_private->mdp_busy = false;
msm_dsi_disable_irq();
- spin_unlock_irqrestore(&dsi_host_private->mdp_lock, flag);
if (pdata->panel_info.mipi.no_max_pkt_size) {
/*
diff --git a/drivers/video/msm/mdss/mdp3_dma.c b/drivers/video/msm/mdss/mdp3_dma.c
index fa2e9eb..94ad9be 100644
--- a/drivers/video/msm/mdss/mdp3_dma.c
+++ b/drivers/video/msm/mdss/mdp3_dma.c
@@ -28,8 +28,6 @@
pr_debug("mdp3_vsync_intr_handler\n");
spin_lock(&dma->dma_lock);
vsync_client = dma->vsync_client;
- if (!vsync_client.handler)
- dma->cb_type &= ~MDP3_DMA_CALLBACK_TYPE_VSYNC;
complete(&dma->vsync_comp);
spin_unlock(&dma->dma_lock);
if (vsync_client.handler)
@@ -43,10 +41,6 @@
struct mdp3_dma *dma = (struct mdp3_dma *)arg;
pr_debug("mdp3_dma_done_intr_handler\n");
- spin_lock(&dma->dma_lock);
- dma->busy = false;
- dma->cb_type &= ~MDP3_DMA_CALLBACK_TYPE_DMA_DONE;
- spin_unlock(&dma->dma_lock);
complete(&dma->dma_comp);
mdp3_irq_disable_nosync(type);
}
@@ -54,19 +48,9 @@
void mdp3_dma_callback_enable(struct mdp3_dma *dma, int type)
{
int irq_bit;
- unsigned long flag;
pr_debug("mdp3_dma_callback_enable type=%d\n", type);
- spin_lock_irqsave(&dma->dma_lock, flag);
- if (dma->cb_type & type) {
- spin_unlock_irqrestore(&dma->dma_lock, flag);
- return;
- } else {
- dma->cb_type |= type;
- spin_unlock_irqrestore(&dma->dma_lock, flag);
- }
-
if (dma->output_config.out_sel == MDP3_DMA_OUTPUT_SEL_DSI_VIDEO ||
dma->output_config.out_sel == MDP3_DMA_OUTPUT_SEL_LCDC) {
if (type & MDP3_DMA_CALLBACK_TYPE_VSYNC)
@@ -92,19 +76,9 @@
void mdp3_dma_callback_disable(struct mdp3_dma *dma, int type)
{
int irq_bit;
- unsigned long flag;
pr_debug("mdp3_dma_callback_disable type=%d\n", type);
- spin_lock_irqsave(&dma->dma_lock, flag);
- if ((dma->cb_type & type) == 0) {
- spin_unlock_irqrestore(&dma->dma_lock, flag);
- return;
- } else {
- dma->cb_type &= ~type;
- spin_unlock_irqrestore(&dma->dma_lock, flag);
- }
-
if (dma->output_config.out_sel == MDP3_DMA_OUTPUT_SEL_DSI_VIDEO ||
dma->output_config.out_sel == MDP3_DMA_OUTPUT_SEL_LCDC) {
if (type & MDP3_DMA_CALLBACK_TYPE_VSYNC)
@@ -443,7 +417,6 @@
static int mdp3_dmap_update(struct mdp3_dma *dma, void *buf)
{
- int wait_for_dma_done = 0;
unsigned long flag;
int cb_type = MDP3_DMA_CALLBACK_TYPE_VSYNC;
@@ -451,22 +424,15 @@
if (dma->output_config.out_sel == MDP3_DMA_OUTPUT_SEL_DSI_CMD) {
cb_type |= MDP3_DMA_CALLBACK_TYPE_DMA_DONE;
- spin_lock_irqsave(&dma->dma_lock, flag);
- if (dma->busy)
- wait_for_dma_done = 1;
- spin_unlock_irqrestore(&dma->dma_lock, flag);
-
- if (wait_for_dma_done)
- wait_for_completion_killable(&dma->dma_comp);
+ wait_for_completion_killable(&dma->dma_comp);
}
spin_lock_irqsave(&dma->dma_lock, flag);
MDP3_REG_WRITE(MDP3_REG_DMA_P_IBUF_ADDR, (u32)buf);
dma->source_config.buf = buf;
- if (dma->output_config.out_sel == MDP3_DMA_OUTPUT_SEL_DSI_CMD) {
+ if (dma->output_config.out_sel == MDP3_DMA_OUTPUT_SEL_DSI_CMD)
MDP3_REG_WRITE(MDP3_REG_DMA_P_START, 1);
- dma->busy = true;
- }
+
wmb();
init_completion(&dma->vsync_comp);
spin_unlock_irqrestore(&dma->dma_lock, flag);
@@ -480,28 +446,19 @@
static int mdp3_dmas_update(struct mdp3_dma *dma, void *buf)
{
- int wait_for_dma_done = 0;
unsigned long flag;
int cb_type = MDP3_DMA_CALLBACK_TYPE_VSYNC;
if (dma->output_config.out_sel == MDP3_DMA_OUTPUT_SEL_DSI_CMD) {
cb_type |= MDP3_DMA_CALLBACK_TYPE_DMA_DONE;
- spin_lock_irqsave(&dma->dma_lock, flag);
- if (dma->busy)
- wait_for_dma_done = 1;
- spin_unlock_irqrestore(&dma->dma_lock, flag);
-
- if (wait_for_dma_done)
- wait_for_completion_killable(&dma->dma_comp);
+ wait_for_completion_killable(&dma->dma_comp);
}
spin_lock_irqsave(&dma->dma_lock, flag);
MDP3_REG_WRITE(MDP3_REG_DMA_S_IBUF_ADDR, (u32)buf);
dma->source_config.buf = buf;
- if (dma->output_config.out_sel == MDP3_DMA_OUTPUT_SEL_DSI_CMD) {
+ if (dma->output_config.out_sel == MDP3_DMA_OUTPUT_SEL_DSI_CMD)
MDP3_REG_WRITE(MDP3_REG_DMA_S_START, 1);
- dma->busy = true;
- }
wmb();
init_completion(&dma->vsync_comp);
spin_unlock_irqrestore(&dma->dma_lock, flag);
@@ -613,7 +570,6 @@
if (dma->output_config.out_sel == MDP3_DMA_OUTPUT_SEL_DSI_CMD) {
cb_type |= MDP3_DMA_CALLBACK_TYPE_DMA_DONE;
MDP3_REG_WRITE(dma_start_offset, 1);
- dma->busy = true;
}
intf->start(intf);
@@ -653,7 +609,6 @@
mdp3_dma_callback_disable(dma, MDP3_DMA_CALLBACK_TYPE_VSYNC |
MDP3_DMA_CALLBACK_TYPE_DMA_DONE);
- dma->busy = false;
return ret;
}
@@ -666,8 +621,6 @@
pr_debug("mdp3_dma_init\n");
switch (dma->dma_sel) {
case MDP3_DMA_P:
- dma->busy = 0;
-
ret = mdp3_dmap_config(dma, source_config, output_config);
if (ret < 0)
return ret;
@@ -687,7 +640,6 @@
dma->stop = mdp3_dma_stop;
break;
case MDP3_DMA_S:
- dma->busy = 0;
ret = mdp3_dmas_config(dma, source_config, output_config);
if (ret < 0)
return ret;
@@ -715,7 +667,6 @@
spin_lock_init(&dma->dma_lock);
init_completion(&dma->vsync_comp);
init_completion(&dma->dma_comp);
- dma->cb_type = 0;
dma->vsync_client.handler = NULL;
dma->vsync_client.arg = NULL;
diff --git a/drivers/video/msm/mdss/mdp3_dma.h b/drivers/video/msm/mdss/mdp3_dma.h
index cef749b..f86bea9 100644
--- a/drivers/video/msm/mdss/mdp3_dma.h
+++ b/drivers/video/msm/mdss/mdp3_dma.h
@@ -226,13 +226,11 @@
u32 capability;
int in_use;
int available;
- int busy;
spinlock_t dma_lock;
struct completion vsync_comp;
struct completion dma_comp;
struct mdp3_vsync_notification vsync_client;
- u32 cb_type;
struct mdp3_dma_output_config output_config;
struct mdp3_dma_source source_config;
diff --git a/drivers/video/msm/mdss/mdss_fb.c b/drivers/video/msm/mdss/mdss_fb.c
index fbd9ef6..61fb41c 100644
--- a/drivers/video/msm/mdss/mdss_fb.c
+++ b/drivers/video/msm/mdss/mdss_fb.c
@@ -668,22 +668,16 @@
}
mdss_fb_pan_idle(mfd);
- if (off >= len) {
- /* memory mapped io */
- off -= len;
- if (info->var.accel_flags) {
- mutex_unlock(&info->lock);
- return -EINVAL;
- }
- start = info->fix.mmio_start;
- len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.mmio_len);
- }
/* Set VM flags. */
start &= PAGE_MASK;
- if ((vma->vm_end - vma->vm_start + off) > len)
+ if ((vma->vm_end <= vma->vm_start) ||
+ (off >= len) ||
+ ((vma->vm_end - vma->vm_start) > (len - off)))
return -EINVAL;
off += start;
+ if (off < start)
+ return -EINVAL;
vma->vm_pgoff = off >> PAGE_SHIFT;
/* This is an IO map - tell maydump to skip this VMA */
vma->vm_flags |= VM_IO | VM_RESERVED;
diff --git a/drivers/video/msm/mdss/mdss_fb.h b/drivers/video/msm/mdss/mdss_fb.h
index 05fdec4..31e4d86 100644
--- a/drivers/video/msm/mdss/mdss_fb.h
+++ b/drivers/video/msm/mdss/mdss_fb.h
@@ -26,7 +26,7 @@
#define MSM_FB_MAX_DEV_LIST 32
#define MSM_FB_ENABLE_DBGFS
-#define WAIT_FENCE_FIRST_TIMEOUT MSEC_PER_SEC
+#define WAIT_FENCE_FIRST_TIMEOUT (3 * MSEC_PER_SEC)
#define WAIT_FENCE_FINAL_TIMEOUT (10 * MSEC_PER_SEC)
/* Display op timeout should be greater than total timeout */
#define WAIT_DISP_OP_TIMEOUT ((WAIT_FENCE_FIRST_TIMEOUT + \
diff --git a/drivers/video/msm/mdss/mdss_mdp_overlay.c b/drivers/video/msm/mdss/mdss_mdp_overlay.c
index 0152d87..0c48696 100644
--- a/drivers/video/msm/mdss/mdss_mdp_overlay.c
+++ b/drivers/video/msm/mdss/mdss_mdp_overlay.c
@@ -197,6 +197,25 @@
return -EINVAL;
}
}
+
+ if (req->flags & MDP_DEINTERLACE) {
+ if (req->flags & MDP_SOURCE_ROTATED_90) {
+ if ((req->src_rect.w % 4) != 0) {
+ pr_err("interlaced rect not h/4\n");
+ return -EINVAL;
+ }
+ } else if ((req->src_rect.h % 4) != 0) {
+ pr_err("interlaced rect not h/4\n");
+ return -EINVAL;
+ }
+ }
+ } else {
+ if (req->flags & MDP_DEINTERLACE) {
+ if ((req->src_rect.h % 4) != 0) {
+ pr_err("interlaced rect h not multiple of 4\n");
+ return -EINVAL;
+ }
+ }
}
if (fmt->is_yuv) {
@@ -207,13 +226,6 @@
}
}
- if (req->flags & MDP_DEINTERLACE) {
- if ((req->src.width % 4 != 0) || (req->src.height % 4 != 0)) {
- pr_err("interlaced fmt w,h need to be even post div\n");
- return -EINVAL;
- }
- }
-
return 0;
}
@@ -300,7 +312,7 @@
struct mdss_mdp_format_params *fmt;
struct mdss_mdp_pipe *pipe;
struct mdss_mdp_mixer *mixer = NULL;
- u32 pipe_type, mixer_mux, len, src_format;
+ u32 pipe_type, mixer_mux, len;
struct mdss_overlay_private *mdp5_data = mfd_to_mdp5_data(mfd);
struct mdp_histogram_start_req hist;
int ret;
@@ -328,13 +340,13 @@
pr_debug("pipe ctl=%u req id=%x mux=%d\n", mdp5_data->ctl->num, req->id,
mixer_mux);
- src_format = req->src.format;
if (req->flags & (MDP_SOURCE_ROTATED_90 | MDP_BWC_EN))
- src_format = mdss_mdp_get_rotator_dst_format(src_format);
+ req->src.format =
+ mdss_mdp_get_rotator_dst_format(req->src.format);
- fmt = mdss_mdp_get_format_params(src_format);
+ fmt = mdss_mdp_get_format_params(req->src.format);
if (!fmt) {
- pr_err("invalid pipe format %d\n", src_format);
+ pr_err("invalid pipe format %d\n", req->src.format);
return -EINVAL;
}
diff --git a/drivers/video/msm/mdss/mdss_mdp_pp.c b/drivers/video/msm/mdss/mdss_mdp_pp.c
index 13c01af..b6f91f4 100644
--- a/drivers/video/msm/mdss/mdss_mdp_pp.c
+++ b/drivers/video/msm/mdss/mdss_mdp_pp.c
@@ -1022,6 +1022,8 @@
int i, ret = 0;
struct mdss_data_type *mdata;
struct mdss_mdp_ctl *ctl;
+ u32 mixer_cnt;
+ u32 mixer_id[MDSS_MDP_INTF_MAX_LAYERMIXER];
if (!mixer || !mixer->ctl || !mixer->ctl->mdata)
return -EINVAL;
@@ -1046,7 +1048,9 @@
else
flags = 0;
- if (dspp_num < mdata->nad_cfgs) {
+ mixer_cnt = mdss_mdp_get_ctl_mixers(disp_num, mixer_id);
+ if (dspp_num < mdata->nad_cfgs && (mixer_cnt != 2) &&
+ ctl->mfd->panel_info->type != MIPI_CMD_PANEL) {
ret = mdss_mdp_ad_setup(ctl->mfd);
if (ret < 0)
pr_warn("ad_setup(dspp%d) returns %d", dspp_num, ret);
@@ -2755,6 +2759,13 @@
{
struct mdss_ad_info *ad;
struct mdss_ad_input input;
+ struct mdss_mdp_ctl *ctl;
+
+ if (!mfd)
+ return -EINVAL;
+ ctl = mfd_to_ctl(mfd);
+ if (!ctl)
+ return -EINVAL;
ad = mdss_mdp_get_ad(mfd);
if (!ad || ad->cfg.mode == MDSS_AD_MODE_AUTO_BL)
diff --git a/include/linux/sync.h b/include/linux/sync.h
index 31ba6ec..f4ac10e 100644
--- a/include/linux/sync.h
+++ b/include/linux/sync.h
@@ -101,7 +101,7 @@
struct sync_timeline {
struct kref kref;
const struct sync_timeline_ops *ops;
- char name[32];
+ char name[64];
/* protected by child_list_lock */
bool destroyed;
diff --git a/include/media/msmb_camera.h b/include/media/msmb_camera.h
index 21a1c44..388b308 100644
--- a/include/media/msmb_camera.h
+++ b/include/media/msmb_camera.h
@@ -14,6 +14,9 @@
#define MSM_CAM_V4L2_IOCTL_CMD_ACK \
_IOW('V', BASE_VIDIOC_PRIVATE + 32, struct v4l2_event)
+#define MSM_CAM_V4L2_IOCTL_NOTIFY_ERROR \
+ _IOW('V', BASE_VIDIOC_PRIVATE + 33, struct v4l2_event)
+
#define QCAMERA_DEVICE_GROUP_ID 1
#define QCAMERA_VNODE_GROUP_ID 2
#define MSM_CAMERA_NAME "msm_camera"
diff --git a/include/media/msmb_isp.h b/include/media/msmb_isp.h
index 3775ddd..ca39705 100644
--- a/include/media/msmb_isp.h
+++ b/include/media/msmb_isp.h
@@ -161,12 +161,20 @@
ENABLE_STREAM_BUF_DIVERT,
DISABLE_STREAM_BUF_DIVERT,
UPDATE_STREAM_FRAMEDROP_PATTERN,
+ UPDATE_STREAM_AXI_CONFIG,
+};
+
+struct msm_vfe_axi_stream_cfg_update_info {
+ uint32_t stream_handle;
+ uint32_t output_format;
+ enum msm_vfe_frame_skip_pattern skip_pattern;
+ struct msm_vfe_axi_plane_cfg plane_cfg[MAX_PLANES_PER_STREAM];
};
struct msm_vfe_axi_stream_update_cmd {
- uint32_t stream_handle;
+ uint32_t num_streams;
enum msm_vfe_axi_stream_update_type update_type;
- enum msm_vfe_frame_skip_pattern skip_pattern;
+ struct msm_vfe_axi_stream_cfg_update_info update_info[MAX_NUM_STREAM];
};
enum msm_isp_stats_type {
@@ -317,6 +325,7 @@
uint32_t session_id;
uint32_t stream_id;
uint32_t handle;
+ uint32_t output_format;
int8_t buf_idx;
};
struct msm_isp_stats_event {
@@ -362,6 +371,8 @@
#define V4L2_PIX_FMT_QGBRG12 v4l2_fourcc('Q', 'G', 'B', '2')
#define V4L2_PIX_FMT_QGRBG12 v4l2_fourcc('Q', 'G', 'R', '2')
#define V4L2_PIX_FMT_QRGGB12 v4l2_fourcc('Q', 'R', 'G', '2')
+#define V4L2_PIX_FMT_NV14 v4l2_fourcc('N', 'V', '1', '4')
+#define V4L2_PIX_FMT_NV41 v4l2_fourcc('N', 'V', '4', '1')
#define VIDIOC_MSM_VFE_REG_CFG \
_IOWR('V', BASE_VIDIOC_PRIVATE, struct msm_vfe_cfg_cmd2)
diff --git a/include/trace/events/kmem.h b/include/trace/events/kmem.h
index 909e1b9..f36e4d5 100644
--- a/include/trace/events/kmem.h
+++ b/include/trace/events/kmem.h
@@ -314,7 +314,7 @@
TP_ARGS(client_name, heap_name, len, mask, flags),
TP_STRUCT__entry(
- __field(const char *, client_name)
+ __array(char, client_name, 64)
__field(const char *, heap_name)
__field(size_t, len)
__field(unsigned int, mask)
@@ -322,7 +322,7 @@
),
TP_fast_assign(
- __entry->client_name = client_name;
+ strlcpy(__entry->client_name, client_name, 64);
__entry->heap_name = heap_name;
__entry->len = len;
__entry->mask = mask;
diff --git a/kernel/signal.c b/kernel/signal.c
index 17afcaf..7a06651 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -482,6 +482,9 @@
if (force_default || ka->sa.sa_handler != SIG_IGN)
ka->sa.sa_handler = SIG_DFL;
ka->sa.sa_flags = 0;
+#ifdef SA_RESTORER
+ ka->sa.sa_restorer = NULL;
+#endif
sigemptyset(&ka->sa.sa_mask);
ka++;
}
diff --git a/scripts/gcc-wrapper.py b/scripts/gcc-wrapper.py
index 2010c57..548d655 100755
--- a/scripts/gcc-wrapper.py
+++ b/scripts/gcc-wrapper.py
@@ -40,10 +40,7 @@
# force LANG to be set to en_US.UTF-8 to get consistent warnings.
allowed_warnings = set([
- "alignment.c:327",
- "mmu.c:602",
"return_address.c:62",
- "extents.c:2091",
])
# Capture the name of the object file, can find it.
diff --git a/sound/soc/codecs/msm8x10-wcd.c b/sound/soc/codecs/msm8x10-wcd.c
index 435f285..75881cf 100644
--- a/sound/soc/codecs/msm8x10-wcd.c
+++ b/sound/soc/codecs/msm8x10-wcd.c
@@ -540,7 +540,7 @@
struct device *dev)
{
struct msm8x10_wcd_pdata *pdata;
- int ret, i;
+ int ret = 0, i;
char **codec_supplies;
u32 num_of_supplies = 0;
diff --git a/sound/soc/msm/msm-pcm-q6.c b/sound/soc/msm/msm-pcm-q6.c
index c37e932..a05a216 100644
--- a/sound/soc/msm/msm-pcm-q6.c
+++ b/sound/soc/msm/msm-pcm-q6.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -165,7 +165,7 @@
/* assume data size = 0 during flushing */
if (in_frame_info[token][0]) {
- prtd->pcm_irq_pos += in_frame_info[token][0];
+ prtd->pcm_irq_pos += prtd->pcm_count;
pr_debug("pcm_irq_pos=%d\n", prtd->pcm_irq_pos);
if (atomic_read(&prtd->start))
snd_pcm_period_elapsed(substream);
diff --git a/sound/soc/msm/msm8974.c b/sound/soc/msm/msm8974.c
index c25eb86..daa2eca 100644
--- a/sound/soc/msm/msm8974.c
+++ b/sound/soc/msm/msm8974.c
@@ -2097,6 +2097,58 @@
/* this dainlink has playback support */
.be_id = MSM_FRONTEND_DAI_MULTIMEDIA8,
},
+ /* HDMI Hostless */
+ {
+ .name = "HDMI_RX_HOSTLESS",
+ .stream_name = "HDMI_RX_HOSTLESS",
+ .cpu_dai_name = "HDMI_HOSTLESS",
+ .platform_name = "msm-pcm-hostless",
+ .dynamic = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ },
+ {
+ .name = LPASS_BE_SLIMBUS_4_TX,
+ .stream_name = "Slimbus4 Capture",
+ .cpu_dai_name = "msm-dai-q6-dev.16393",
+ .platform_name = "msm-pcm-hostless",
+ .codec_name = "taiko_codec",
+ .codec_dai_name = "taiko_vifeedback",
+ .be_id = MSM_BACKEND_DAI_SLIMBUS_4_TX,
+ .be_hw_params_fixup = msm_slim_4_tx_be_hw_params_fixup,
+ .ops = &msm8974_be_ops,
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ },
+ /* Ultrasound RX Back End DAI Link */
+ {
+ .name = "SLIMBUS_2 Hostless Playback",
+ .stream_name = "SLIMBUS_2 Hostless Playback",
+ .cpu_dai_name = "msm-dai-q6-dev.16388",
+ .platform_name = "msm-pcm-hostless",
+ .codec_name = "taiko_codec",
+ .codec_dai_name = "taiko_rx2",
+ .ignore_suspend = 1,
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ops = &msm8974_slimbus_2_be_ops,
+ },
+ /* Ultrasound TX Back End DAI Link */
+ {
+ .name = "SLIMBUS_2 Hostless Capture",
+ .stream_name = "SLIMBUS_2 Hostless Capture",
+ .cpu_dai_name = "msm-dai-q6-dev.16389",
+ .platform_name = "msm-pcm-hostless",
+ .codec_name = "taiko_codec",
+ .codec_dai_name = "taiko_tx2",
+ .ignore_suspend = 1,
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ops = &msm8974_slimbus_2_be_ops,
+ },
/* Backend BT/FM DAI Links */
{
.name = LPASS_BE_INT_BT_SCO_RX,
@@ -2177,21 +2229,6 @@
.be_hw_params_fixup = msm_proxy_tx_be_hw_params_fixup,
.ignore_suspend = 1,
},
- /* HDMI Hostless */
- {
- .name = "HDMI_RX_HOSTLESS",
- .stream_name = "HDMI_RX_HOSTLESS",
- .cpu_dai_name = "HDMI_HOSTLESS",
- .platform_name = "msm-pcm-hostless",
- .dynamic = 1,
- .trigger = {SND_SOC_DPCM_TRIGGER_POST,
- SND_SOC_DPCM_TRIGGER_POST},
- .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
- .ignore_suspend = 1,
- .ignore_pmdown_time = 1,
- .codec_dai_name = "snd-soc-dummy-dai",
- .codec_name = "snd-soc-dummy",
- },
/* Primary AUX PCM Backend DAI Links */
{
.name = LPASS_BE_AUXPCM_RX,
@@ -2351,19 +2388,6 @@
.ignore_pmdown_time = 1,
.ignore_suspend = 1,
},
- {
- .name = LPASS_BE_SLIMBUS_4_TX,
- .stream_name = "Slimbus4 Capture",
- .cpu_dai_name = "msm-dai-q6-dev.16393",
- .platform_name = "msm-pcm-hostless",
- .codec_name = "taiko_codec",
- .codec_dai_name = "taiko_vifeedback",
- .be_id = MSM_BACKEND_DAI_SLIMBUS_4_TX,
- .be_hw_params_fixup = msm_slim_4_tx_be_hw_params_fixup,
- .ops = &msm8974_be_ops,
- .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
- .ignore_suspend = 1,
- },
/* Incall Record Uplink BACK END DAI Link */
{
.name = LPASS_BE_INCALL_RECORD_TX,
@@ -2416,30 +2440,6 @@
.be_hw_params_fixup = msm_be_hw_params_fixup,
.ignore_suspend = 1,
},
- /* Ultrasound RX Back End DAI Link */
- {
- .name = "SLIMBUS_2 Hostless Playback",
- .stream_name = "SLIMBUS_2 Hostless Playback",
- .cpu_dai_name = "msm-dai-q6-dev.16388",
- .platform_name = "msm-pcm-hostless",
- .codec_name = "taiko_codec",
- .codec_dai_name = "taiko_rx2",
- .ignore_suspend = 1,
- .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
- .ops = &msm8974_slimbus_2_be_ops,
- },
- /* Ultrasound TX Back End DAI Link */
- {
- .name = "SLIMBUS_2 Hostless Capture",
- .stream_name = "SLIMBUS_2 Hostless Capture",
- .cpu_dai_name = "msm-dai-q6-dev.16389",
- .platform_name = "msm-pcm-hostless",
- .codec_name = "taiko_codec",
- .codec_dai_name = "taiko_tx2",
- .ignore_suspend = 1,
- .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
- .ops = &msm8974_slimbus_2_be_ops,
- },
};
static struct snd_soc_dai_link msm8974_hdmi_dai_link[] = {