Merge "common: DMA-mapping: Add strongly ordered memory attribute"
diff --git a/Documentation/devicetree/bindings/leds/leds-qpnp.txt b/Documentation/devicetree/bindings/leds/leds-qpnp.txt
index ef77e1e..d7290e0 100644
--- a/Documentation/devicetree/bindings/leds/leds-qpnp.txt
+++ b/Documentation/devicetree/bindings/leds/leds-qpnp.txt
@@ -4,9 +4,7 @@
controlling LEDs that are part of PMIC on Qualcomm reference
platforms. The PMIC is connected to Host processor via
SPMI bus. This driver supports various LED modules such as
-WLED (white LED), RGB LED and flash LED. The first version of
-the driver supports WLED and other features are added in the
-next versions.
+WLED (white LED), RGB LED and flash LED.
Required Properties:
- compatible : should be "qcom,leds-qpnp"
@@ -48,27 +46,60 @@
- 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"
+RGB Led is a tri-colored led, Red, Blue & Green.
+
+Required properties for RGB led:
+- qcom,mode: mode the led should operate in, options 0 = PWM, 1 = LPG
+- qcom,pwm-channel: pwm channel the led will operate on
+- qcom,pwm-us: time the pwm device will modulate at (us)
+
+Required properties for LPG mode only:
+- qcom,duty-ms: duty cycle time the led will operate at (ms)
+- qcom,duty-pcts: array of values for duty cycle to go through
+- qcom,start-idx: starting point duty-pcts array
+
+Optional properties for RGB led:
+- 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"
+
Example:
- qcom,leds@d800 {
- compatible = "qcom,leds-qpnp";
- status = "okay";
- qcom,wled_0 {
- linux,default-trigger = "bkl-trigger"
- label = "wled";
- qcom,cs-out-en;
- qcom,op-fdbck;
- qcom,default-state "off";
- qcom,max-current = <25>;
- qcom,ctrl-delay-us = <0>;
- qcom,boost-curr-lim = <3>;
- qcom,cp-sel = <0>;
- qcom,switch-freq = <2>;
- qcom,ovp-val = <2>;
- qcom,num-strings = <1>;
- qcom,id = <0>;
- linux,name = "led:wled_backlight";
- };
+ qcom,leds@d000 {
+ status = "okay";
+ qcom,rgb_pwm {
+ label = "rgb";
+ linux,name = "led:rgb_red";
+ qcom,mode = <0>;
+ qcom,pwm-channel = <6>;
+ qcom,pwm-us = <1000>;
+ qcom,duty-ms = <20>;
+ qcom,start-idx = <1>;
+ qcom,idx-len = <10>;
+ qcom,duty-pcts = [00 19 32 4B 64
+ 64 4B 32 19 00];
+ qcom,max-current = <12>;
+ qcom,default-state = "off";
+ qcom,id = <3>;
+ linux,default-trigger =
+ "battery-charging";
+ };
+
+ qcom,rgb_lpg {
+ label = "rgb";
+ linux,name = "led:rgb_blue";
+ qcom,mode = <1>;
+ qcom,pwm-channel = <4>;
+ qcom,pwm-us = <1000>;
+ qcom,duty-ms = <20>;
+ qcom,start-idx = <1>;
+ qcom,idx-len = <10>;
+ qcom,duty-pcts = [00 19 32 4B 64
+ 64 4B 32 19 00];
+ qcom,max-current = <12>;
+ qcom,default-state = "off";
+ qcom,id = <5>;
+ linux,default-trigger = "none";
+ };
};
qcom,leds@d300 {
@@ -90,3 +121,24 @@
qcom,id = <1>;
};
};
+
+ qcom,leds@d800 {
+ compatible = "qcom,leds-qpnp";
+ status = "okay";
+ qcom,wled_0 {
+ linux,default-trigger = "bkl-trigger"
+ label = "wled";
+ qcom,cs-out-en;
+ qcom,op-fdbck;
+ qcom,default-state "off";
+ qcom,max-current = <25>;
+ qcom,ctrl-delay-us = <0>;
+ qcom,boost-curr-lim = <3>;
+ qcom,cp-sel = <0>;
+ qcom,switch-freq = <2>;
+ qcom,ovp-val = <2>;
+ qcom,num-strings = <1>;
+ qcom,id = <0>;
+ linux,name = "led:wled_backlight";
+ };
+ };
diff --git a/Documentation/devicetree/bindings/mmc/msm_sdcc.txt b/Documentation/devicetree/bindings/mmc/msm_sdcc.txt
index aac998f..a981eed 100644
--- a/Documentation/devicetree/bindings/mmc/msm_sdcc.txt
+++ b/Documentation/devicetree/bindings/mmc/msm_sdcc.txt
@@ -10,7 +10,8 @@
"reg-names" examples are "core_mem", "dml_mem" and "bam_mem"
- interrupts : should contain SDCC core interrupt.
- interrupt-names : indicates interrupts passed to driver (via interrupts property) by name.
- "interrupt-names" examples are "core_irq", "bam_irq" and "status_irq"
+ "core_irq" is mandatory, "bam_irq" is mandatory only when BAM DMA engine is used,
+ "status_irq" and "sdiowakeup_irq" are optional.
- qcom,sdcc-clk-rates : specifies supported SDCC clock frequencies, Units - Hz.
- qcom,sdcc-sup-voltages: specifies supported voltage ranges for card. Should always be
specified in pairs (min, max), Units - mV.
@@ -28,6 +29,8 @@
- qcom,sdcc-bus-speed-mode - specifies supported bus speed modes by host.
- qcom,sdcc-current-limit - specifies max. current the host can drive.
- qcom,sdcc-xpc - specifies if the host can supply more than 150mA for SDXC cards.
+ - qcom,dat1-mpm-int - specifies MPM interrupt number corresponding to DAT1 line of SDCC
+ (used only if slot has dedicated DAT1 MSM pin (not GPIO))
In the following, <supply> can be vdd (flash core voltage) or vdd-io (I/O voltage).
- qcom,sdcc-<supply>-always_on - specifies whether supply should be kept "on" always.
diff --git a/Documentation/devicetree/bindings/regulator/krait-regulator.txt b/Documentation/devicetree/bindings/regulator/krait-regulator.txt
new file mode 100644
index 0000000..fddae80
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/krait-regulator.txt
@@ -0,0 +1,27 @@
+Krait Voltage regulators
+
+Required properties:
+- compatible: Must be "qcom,krait-regulator"
+- reg: Specifies the address and size for this regulator device
+- qcom,headroom-voltage: The minimum required voltage drop between the input
+ voltage and the output voltage for the LDO to be
+ operational, in microvolts
+- qcom,retention-voltage: The value for retention voltage in microvolts
+- qcom,ldo-default-voltage: The default value for LDO voltage in microvolts
+- qcom,ldo-threshold-voltage: The voltage value above which LDO is nonfunctional
+
+Any property defined as part of the core regulator
+binding, defined in regulator.txt, can also be used.
+
+Example:
+ krait0_vreg: regulator@f9088000 {
+ compatible = "qcom,krait-regulator";
+ regulator-name = "krait0";
+ reg = <0xf9088000 0x1000>;
+ regulator-min-microvolt = <500000>;
+ regulator-max-microvolt = <1100000>;
+ qcom,headroom-voltage = <150000>;
+ qcom,retention-voltage = <745000>;
+ qcom,ldo-default-voltage = <745000>;
+ qcom,ldo-threshold-voltage = <750000>;
+ };
diff --git a/Documentation/devicetree/bindings/usb/msm-hsusb.txt b/Documentation/devicetree/bindings/usb/msm-hsusb.txt
index 186a58d..7bff0f2 100644
--- a/Documentation/devicetree/bindings/usb/msm-hsusb.txt
+++ b/Documentation/devicetree/bindings/usb/msm-hsusb.txt
@@ -81,13 +81,16 @@
- compatible: should be "qcom,android-usb"
Optional properties :
-- reg : offset and length of memory region that is used by driver to
+- reg : offset and length of memory region that is used by device to
update USB PID and serial numbers used by bootloader in DLOAD mode.
+- qcom,android-usb-swfi-latency : value to be used by device to vote
+ for DMA latency in microsecs.
Example Android USB device node :
android_usb@fc42b0c8 {
compatible = "qcom,android-usb";
reg = <0xfc42b0c8 0xc8>;
+ qcom,android-usb-swfi-latency = <1>;
};
diff --git a/Documentation/devicetree/bindings/usb/msm-ssusb.txt b/Documentation/devicetree/bindings/usb/msm-ssusb.txt
index 99274d5..57d776f 100644
--- a/Documentation/devicetree/bindings/usb/msm-ssusb.txt
+++ b/Documentation/devicetree/bindings/usb/msm-ssusb.txt
@@ -28,8 +28,10 @@
- interrupt-names : Optional interrupt resource entries are:
"hs_phy_irq" : Interrupt from HSPHY for asynchronous events in LPM.
This is not used if wakeup events are received externally (e.g. PMIC)
-- qcom,dwc-usb3-msm-otg-capability: If present then depends on PMIC
- for VBUS notifications, otherwise depends on PHY.
+- qcom,otg-capability: If present then depend on PMIC for VBUS notifications,
+ otherwise depend on PHY.
+- qcom,charging-disabled: If present then battery charging using USB
+ is disabled.
Example MSM USB3.0 controller device node :
usb@f9200000 {
diff --git a/arch/arm/boot/dts/msm-pm8941.dtsi b/arch/arm/boot/dts/msm-pm8941.dtsi
index 341b49b..21d8c8c 100644
--- a/arch/arm/boot/dts/msm-pm8941.dtsi
+++ b/arch/arm/boot/dts/msm-pm8941.dtsi
@@ -993,6 +993,24 @@
status = "disabled";
};
+ qcom,leds@d000 {
+ compatible = "qcom,leds-qpnp";
+ reg = <0xd000 0x100>;
+ label = "rgb";
+ };
+
+ qcom,leds@d100 {
+ compatible = "qcom,leds-qpnp";
+ reg = <0xd100 0x100>;
+ label = "rgb";
+ };
+
+ qcom,leds@d200 {
+ compatible = "qcom,leds-qpnp";
+ reg = <0xd200 0x100>;
+ label = "rgb";
+ };
+
qcom,leds@d300 {
compatible = "qcom,leds-qpnp";
reg = <0xd300 0x100>;
diff --git a/arch/arm/boot/dts/msm8974-mtp.dtsi b/arch/arm/boot/dts/msm8974-mtp.dtsi
index f4be0dc..6553fc0 100644
--- a/arch/arm/boot/dts/msm8974-mtp.dtsi
+++ b/arch/arm/boot/dts/msm8974-mtp.dtsi
@@ -172,7 +172,7 @@
};
&usb3 {
- qcom,dwc-usb3-msm-otg-capability;
+ qcom,otg-capability;
};
&pm8941_chg {
diff --git a/arch/arm/boot/dts/msm8974-regulator.dtsi b/arch/arm/boot/dts/msm8974-regulator.dtsi
index de9e98c..495d3fb 100644
--- a/arch/arm/boot/dts/msm8974-regulator.dtsi
+++ b/arch/arm/boot/dts/msm8974-regulator.dtsi
@@ -456,6 +456,10 @@
reg = <0xf9088000 0x1000>;
regulator-min-microvolt = <500000>;
regulator-max-microvolt = <1100000>;
+ qcom,headroom-voltage = <150000>;
+ qcom,retention-voltage = <745000>;
+ qcom,ldo-default-voltage = <745000>;
+ qcom,ldo-threshold-voltage = <750000>;
};
krait1_vreg: regulator@f9098000 {
@@ -464,6 +468,10 @@
reg = <0xf9098000 0x1000>;
regulator-min-microvolt = <500000>;
regulator-max-microvolt = <1100000>;
+ qcom,headroom-voltage = <150000>;
+ qcom,retention-voltage = <745000>;
+ qcom,ldo-default-voltage = <745000>;
+ qcom,ldo-threshold-voltage = <750000>;
};
krait2_vreg: regulator@f90a8000 {
@@ -472,6 +480,10 @@
reg = <0xf90a8000 0x1000>;
regulator-min-microvolt = <500000>;
regulator-max-microvolt = <1100000>;
+ qcom,headroom-voltage = <150000>;
+ qcom,retention-voltage = <745000>;
+ qcom,ldo-default-voltage = <745000>;
+ qcom,ldo-threshold-voltage = <750000>;
};
krait3_vreg: regulator@f90b8000 {
@@ -480,6 +492,10 @@
reg = <0xf90b8000 0x1000>;
regulator-min-microvolt = <500000>;
regulator-max-microvolt = <1100000>;
+ qcom,headroom-voltage = <150000>;
+ qcom,retention-voltage = <745000>;
+ qcom,ldo-default-voltage = <745000>;
+ qcom,ldo-threshold-voltage = <750000>;
};
spi_eth_vreg: spi_eth_phy_vreg {
diff --git a/arch/arm/boot/dts/msm8974.dtsi b/arch/arm/boot/dts/msm8974.dtsi
index 18f14a2..83e1141 100644
--- a/arch/arm/boot/dts/msm8974.dtsi
+++ b/arch/arm/boot/dts/msm8974.dtsi
@@ -122,6 +122,7 @@
android_usb@fc42b0c8 {
compatible = "qcom,android-usb";
reg = <0xfc42b0c8 0xc8>;
+ qcom,android-usb-swfi-latency = <1>;
};
sdcc1: qcom,sdcc@f9824000 {
@@ -168,6 +169,7 @@
<78 512 106496 212992>, /* 208 MB/s */
<78 512 2147483647 4294967295>; /* Max. bandwidth */
qcom,bus-bw-vectors-bps = <0 13631488 27262976 54525952 109051904 218103808 4294967295>;
+ qcom,dat1-mpm-int = <42>;
};
sdcc2: qcom,sdcc@f98a4000 {
@@ -214,6 +216,7 @@
<81 512 106496 212992>, /* 208 MB/s */
<81 512 2147483647 4294967295>; /* Max. bandwidth */
qcom,bus-bw-vectors-bps = <0 13631488 27262976 54525952 109051904 218103808 4294967295>;
+ qcom,dat1-mpm-int = <44>;
};
sdcc3: qcom,sdcc@f9864000 {
@@ -223,8 +226,15 @@
<0xf9864800 0x100>,
<0xf9844000 0x7000>;
reg-names = "core_mem", "dml_mem", "bam_mem";
- interrupts = <0 127 0>, <0 223 0>;
- interrupt-names = "core_irq", "bam_irq";
+ #address-cells = <0>;
+ interrupt-parent = <&sdcc3>;
+ interrupts = <0 1 2>;
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0xffffffff>;
+ interrupt-map = <0 &intc 0 127 0
+ 1 &intc 0 223 0
+ 2 &msmgpio 37 0x8>;
+ interrupt-names = "core_irq", "bam_irq", "sdiowakeup_irq";
gpios = <&msmgpio 40 0>, /* CLK */
<&msmgpio 39 0>, /* CMD */
@@ -261,8 +271,15 @@
<0xf98e4800 0x100>,
<0xf98c4000 0x7000>;
reg-names = "core_mem", "dml_mem", "bam_mem";
- interrupts = <0 129 0>, <0 226 0>;
- interrupt-names = "core_irq", "bam_irq";
+ #address-cells = <0>;
+ interrupt-parent = <&sdcc4>;
+ interrupts = <0 1 2>;
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0xffffffff>;
+ interrupt-map = <0 &intc 0 129 0
+ 1 &intc 0 226 0
+ 2 &msmgpio 95 0x8>;
+ interrupt-names = "core_irq", "bam_irq", "sdiowakeup_irq";
gpios = <&msmgpio 93 0>, /* CLK */
<&msmgpio 91 0>, /* CMD */
diff --git a/arch/arm/boot/dts/msm9625-coresight.dtsi b/arch/arm/boot/dts/msm9625-coresight.dtsi
new file mode 100644
index 0000000..f01fe63
--- /dev/null
+++ b/arch/arm/boot/dts/msm9625-coresight.dtsi
@@ -0,0 +1,118 @@
+/* Copyright (c) 2012, 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.
+ */
+
+/ {
+ tmc_etr: tmc@fc322000 {
+ compatible = "arm,coresight-tmc";
+ reg = <0xfc322000 0x1000>,
+ <0xfc37c000 0x3000>;
+
+ qcom,memory-reservation-type = "EBI1";
+ qcom,memory-reservation-size = <0x100000>; /* 1M EBI1 buffer */
+
+ coresight-id = <0>;
+ coresight-name = "coresight-tmc-etr";
+ coresight-nr-inports = <1>;
+ };
+
+ tpiu: tpiu@fc318000 {
+ compatible = "arm,coresight-tpiu";
+ reg = <0xfc318000 0x1000>;
+
+ coresight-id = <1>;
+ coresight-name = "coresight-tpiu";
+ coresight-nr-inports = <1>;
+ };
+
+ replicator: replicator@fc31c000 {
+ compatible = "qcom,coresight-replicator";
+ reg = <0xfc31c000 0x1000>;
+
+ coresight-id = <2>;
+ coresight-name = "coresight-replicator";
+ coresight-nr-inports = <1>;
+ coresight-outports = <0 1>;
+ coresight-child-list = <&tmc_etr &tpiu>;
+ coresight-child-ports = <0 0>;
+ };
+
+ tmc_etf: tmc@fc307000 {
+ compatible = "arm,coresight-tmc";
+ reg = <0xfc307000 0x1000>;
+
+ coresight-id = <3>;
+ coresight-name = "coresight-tmc-etf";
+ coresight-nr-inports = <1>;
+ coresight-outports = <0>;
+ coresight-child-list = <&replicator>;
+ coresight-child-ports = <0>;
+ coresight-default-sink;
+ };
+
+ funnel_merg: funnel@fc31b000 {
+ compatible = "arm,coresight-funnel";
+ reg = <0xfc31b000 0x1000>;
+
+ coresight-id = <4>;
+ coresight-name = "coresight-funnel-merg";
+ coresight-nr-inports = <2>;
+ coresight-outports = <0>;
+ coresight-child-list = <&tmc_etf>;
+ coresight-child-ports = <0>;
+ };
+
+ funnel_in0: funnel@fc319000 {
+ compatible = "arm,coresight-funnel";
+ reg = <0xfc319000 0x1000>;
+
+ coresight-id = <5>;
+ coresight-name = "coresight-funnel-in0";
+ coresight-nr-inports = <8>;
+ coresight-outports = <0>;
+ coresight-child-list = <&funnel_merg>;
+ coresight-child-ports = <0>;
+ };
+
+ funnel_in1: funnel@fc31a000 {
+ compatible = "arm,coresight-funnel";
+ reg = <0xfc31a000 0x1000>;
+
+ coresight-id = <6>;
+ coresight-name = "coresight-funnel-in1";
+ coresight-nr-inports = <8>;
+ coresight-outports = <0>;
+ coresight-child-list = <&funnel_merg>;
+ coresight-child-ports = <1>;
+ };
+
+ stm: stm@fc321000 {
+ compatible = "arm,coresight-stm";
+ reg = <0xfc321000 0x1000>,
+ <0xfa280000 0x180000>;
+
+ coresight-id = <7>;
+ coresight-name = "coresight-stm";
+ coresight-nr-inports = <0>;
+ coresight-outports = <0>;
+ coresight-child-list = <&funnel_in1>;
+ coresight-child-ports = <7>;
+ };
+
+ csr: csr@fc302000 {
+ compatible = "qcom,coresight-csr";
+ reg = <0xfc302000 0x1000>;
+
+ coresight-id = <8>;
+ coresight-name = "coresight-csr";
+ coresight-nr-inports = <0>;
+ };
+};
diff --git a/arch/arm/boot/dts/msm9625.dtsi b/arch/arm/boot/dts/msm9625.dtsi
index 7b01020..3d2515d 100644
--- a/arch/arm/boot/dts/msm9625.dtsi
+++ b/arch/arm/boot/dts/msm9625.dtsi
@@ -13,6 +13,7 @@
/include/ "skeleton.dtsi"
/include/ "msm9625-ion.dtsi"
/include/ "msm9625-pm.dtsi"
+/include/ "msm9625-coresight.dtsi"
/ {
model = "Qualcomm MSM 9625";
@@ -141,7 +142,6 @@
/* 190,ee0_krait_hlos_spmi_periph_irq */
/* 187,channel_0_krait_hlos_trans_done_irq */
interrupts = <0 190 0 0 187 0>;
- qcom,not-wakeup;
qcom,pmic-arb-ee = <0>;
qcom,pmic-arb-channel = <0>;
qcom,pmic-arb-ppid-map = <0x02400000>, /* TEMP_ALARM */
@@ -241,7 +241,6 @@
compatible = "qcom,bam_dmux";
reg = <0xfc834000 0x7000>;
interrupts = <0 29 1>;
- qcom,satellite-mode;
};
qcom,acpuclk@f9010000 {
@@ -258,6 +257,16 @@
reg = <0xfc400404 0x4>;
regulator-name = "gdsc_usb_hsic";
};
+
+ tsens@fc4a8000 {
+ compatible = "qcom,msm-tsens";
+ reg = <0xfc4a8000 0x2000>,
+ <0xfc4b8000 0x1000>;
+ reg-names = "tsens_physical", "tsens_eeprom_physical";
+ interrupts = <0 184 0>;
+ qcom,sensors = <5>;
+ qcom,slope = <3200 3200 3200 3200 3200>;
+ };
};
/include/ "msm-pm8019-rpm-regulator.dtsi"
diff --git a/arch/arm/configs/msm7627a-perf_defconfig b/arch/arm/configs/msm7627a-perf_defconfig
index 76650e0..8e948c2 100644
--- a/arch/arm/configs/msm7627a-perf_defconfig
+++ b/arch/arm/configs/msm7627a-perf_defconfig
@@ -42,6 +42,7 @@
# CONFIG_MSM_SMD_NMEA is not set
# CONFIG_MSM_SMD_QMI is not set
CONFIG_MSM_ONCRPCROUTER=y
+CONFIG_MSM_IPC_ROUTER=y
# CONFIG_MSM_RPCSERVER_TIME_REMOTE is not set
CONFIG_MSM_RMT_STORAGE_CLIENT=y
# CONFIG_MSM_HW3D is not set
diff --git a/arch/arm/configs/msm7627a_defconfig b/arch/arm/configs/msm7627a_defconfig
index 8ab57de..d403cec 100644
--- a/arch/arm/configs/msm7627a_defconfig
+++ b/arch/arm/configs/msm7627a_defconfig
@@ -42,6 +42,7 @@
# CONFIG_MSM_SMD_NMEA is not set
# CONFIG_MSM_SMD_QMI is not set
CONFIG_MSM_ONCRPCROUTER=y
+CONFIG_MSM_IPC_ROUTER=y
# CONFIG_MSM_RPCSERVER_TIME_REMOTE is not set
CONFIG_MSM_RMT_STORAGE_CLIENT=y
# CONFIG_MSM_HW3D is not set
diff --git a/arch/arm/configs/msm8660-perf_defconfig b/arch/arm/configs/msm8660-perf_defconfig
index 2ee3f3b..828484a 100644
--- a/arch/arm/configs/msm8660-perf_defconfig
+++ b/arch/arm/configs/msm8660-perf_defconfig
@@ -295,7 +295,6 @@
CONFIG_GPIO_SYSFS=y
CONFIG_GPIO_SX150X=y
CONFIG_POWER_SUPPLY=y
-# CONFIG_BATTERY_MSM is not set
CONFIG_BATTERY_MSM8X60=y
CONFIG_PM8058_CHARGER=y
CONFIG_ISL9519_CHARGER=y
diff --git a/arch/arm/configs/msm8660_defconfig b/arch/arm/configs/msm8660_defconfig
index 25c5207..28d7b12 100644
--- a/arch/arm/configs/msm8660_defconfig
+++ b/arch/arm/configs/msm8660_defconfig
@@ -295,7 +295,6 @@
CONFIG_GPIO_SYSFS=y
CONFIG_GPIO_SX150X=y
CONFIG_POWER_SUPPLY=y
-# CONFIG_BATTERY_MSM is not set
CONFIG_BATTERY_MSM8X60=y
CONFIG_PM8058_CHARGER=y
CONFIG_ISL9519_CHARGER=y
diff --git a/arch/arm/configs/msm8910_defconfig b/arch/arm/configs/msm8910_defconfig
index 7e4e7705..fe6a7da 100644
--- a/arch/arm/configs/msm8910_defconfig
+++ b/arch/arm/configs/msm8910_defconfig
@@ -34,15 +34,16 @@
CONFIG_EFI_PARTITION=y
CONFIG_ARCH_MSM=y
CONFIG_ARCH_MSM8910=y
+CONFIG_ARCH_MSM8226=y
# CONFIG_MSM_STACKED_MEMORY is not set
CONFIG_CPU_HAS_L2_PMU=y
# CONFIG_MSM_FIQ_SUPPORT is not set
# CONFIG_MSM_PROC_COMM is not set
CONFIG_MSM_SMD=y
+# CONFIG_MSM_HW3D is not set
CONFIG_MSM_DIRECT_SCLK_ACCESS=y
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
-CONFIG_SMP=y
# CONFIG_SMP_ON_UP is not set
CONFIG_ARM_ARCH_TIMER=y
CONFIG_HOTPLUG_CPU=y
@@ -92,7 +93,6 @@
CONFIG_INPUT_MISC=y
CONFIG_INPUT_UINPUT=y
CONFIG_INPUT_GPIO=m
-CONFIG_SERIO_LIBPS2=y
CONFIG_SERIAL_MSM_HSL=y
CONFIG_SERIAL_MSM_HSL_CONSOLE=y
CONFIG_DIAG_CHAR=y
@@ -104,7 +104,6 @@
CONFIG_REGULATOR_STUB=y
CONFIG_FB=y
CONFIG_FB_VIRTUAL=y
-# CONFIG_MSM_HW3D is not set
CONFIG_SOUND=y
CONFIG_SND=y
CONFIG_SND_SOC=y
@@ -122,7 +121,6 @@
CONFIG_MMC_BLOCK_MINORS=32
CONFIG_MMC_TEST=m
CONFIG_MMC_MSM=y
-CONFIG_MMC_MSM_SPS_SUPPORT=y
CONFIG_STAGING=y
CONFIG_ANDROID=y
CONFIG_ANDROID_BINDER_IPC=y
@@ -152,19 +150,11 @@
CONFIG_DYNAMIC_DEBUG=y
CONFIG_DEBUG_USER=y
CONFIG_KEYS=y
-CONFIG_CRYPTO_AUTHENC=y
-CONFIG_CRYPTO_CBC=y
-CONFIG_CRYPTO_HMAC=y
CONFIG_CRYPTO_MD4=y
-CONFIG_CRYPTO_MD5=y
-CONFIG_CRYPTO_SHA1=y
CONFIG_CRYPTO_SHA256=y
CONFIG_CRYPTO_AES=y
CONFIG_CRYPTO_ARC4=y
-CONFIG_CRYPTO_DES=y
CONFIG_CRYPTO_TWOFISH=y
-CONFIG_CRYPTO_DEFLATE=y
# CONFIG_CRYPTO_HW is not set
CONFIG_CRC_CCITT=y
-CONFIG_CRC16=y
CONFIG_LIBCRC32C=y
diff --git a/arch/arm/configs/msm8960-perf_defconfig b/arch/arm/configs/msm8960-perf_defconfig
index ec00b68..a613932 100644
--- a/arch/arm/configs/msm8960-perf_defconfig
+++ b/arch/arm/configs/msm8960-perf_defconfig
@@ -315,7 +315,6 @@
CONFIG_GPIO_SYSFS=y
CONFIG_GPIO_SX150X=y
CONFIG_POWER_SUPPLY=y
-# CONFIG_BATTERY_MSM is not set
CONFIG_ISL9519_CHARGER=y
CONFIG_SMB349_CHARGER=y
CONFIG_PM8921_CHARGER=y
@@ -356,6 +355,7 @@
CONFIG_MSM_CAMERA_FLASH_SC628A=y
CONFIG_MSM_CAMERA_FLASH_TPS61310=y
CONFIG_OV2720=y
+CONFIG_IMX135=y
CONFIG_MSM_CAMERA_SENSOR=y
CONFIG_MSM_ACTUATOR=y
CONFIG_MSM_EEPROM=y
@@ -367,14 +367,12 @@
CONFIG_S5K3L1YX=y
CONFIG_IMX091=y
CONFIG_MSM_WFD=y
-CONFIG_IMX135=y
CONFIG_RADIO_IRIS=y
CONFIG_RADIO_IRIS_TRANSPORT=m
# CONFIG_DVB_FE_CUSTOMISE is not set
CONFIG_DVB_MPQ=m
CONFIG_DVB_MPQ_DEMUX=m
CONFIG_DVB_MPQ_VIDEO=m
-CONFIG_DVB_MPQ_TSPP1=y
CONFIG_ION=y
CONFIG_ION_MSM=y
CONFIG_MSM_KGSL=y
diff --git a/arch/arm/configs/msm8960_defconfig b/arch/arm/configs/msm8960_defconfig
index 33f7987..0d63836 100644
--- a/arch/arm/configs/msm8960_defconfig
+++ b/arch/arm/configs/msm8960_defconfig
@@ -320,7 +320,6 @@
CONFIG_GPIO_SYSFS=y
CONFIG_GPIO_SX150X=y
CONFIG_POWER_SUPPLY=y
-# CONFIG_BATTERY_MSM is not set
CONFIG_ISL9519_CHARGER=y
CONFIG_SMB349_CHARGER=y
CONFIG_PM8921_CHARGER=y
@@ -360,6 +359,7 @@
CONFIG_IMX074_ACT=y
CONFIG_MSM_CAMERA_FLASH_SC628A=y
CONFIG_OV2720=y
+CONFIG_IMX135=y
CONFIG_MSM_CAMERA_SENSOR=y
CONFIG_MSM_ACTUATOR=y
CONFIG_MSM_EEPROM=y
@@ -371,14 +371,12 @@
CONFIG_S5K3L1YX=y
CONFIG_IMX091=y
CONFIG_MSM_WFD=y
-CONFIG_IMX135=y
CONFIG_RADIO_IRIS=y
CONFIG_RADIO_IRIS_TRANSPORT=m
# CONFIG_DVB_FE_CUSTOMISE is not set
CONFIG_DVB_MPQ=m
CONFIG_DVB_MPQ_DEMUX=m
CONFIG_DVB_MPQ_VIDEO=m
-CONFIG_DVB_MPQ_TSPP1=y
CONFIG_ION=y
CONFIG_ION_MSM=y
CONFIG_MSM_KGSL=y
diff --git a/arch/arm/configs/msm8974-perf_defconfig b/arch/arm/configs/msm8974-perf_defconfig
index 156e348..7bfe3fe 100644
--- a/arch/arm/configs/msm8974-perf_defconfig
+++ b/arch/arm/configs/msm8974-perf_defconfig
@@ -53,7 +53,6 @@
CONFIG_MSM_SYSMON_COMM=y
CONFIG_MSM_PIL_LPASS_QDSP6V5=y
CONFIG_MSM_PIL_MSS_QDSP6V5=y
-CONFIG_MSM_PIL_MBA=y
CONFIG_MSM_PIL_VENUS=y
CONFIG_MSM_PIL_PRONTO=y
CONFIG_MSM_TZ_LOG=y
@@ -75,7 +74,6 @@
CONFIG_STRICT_MEMORY_RWX=y
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
-CONFIG_SMP=y
# CONFIG_SMP_ON_UP is not set
CONFIG_ARM_ARCH_TIMER=y
CONFIG_PREEMPT=y
@@ -239,8 +237,8 @@
CONFIG_MSM_RMNET_BAM=y
CONFIG_SLIP=y
CONFIG_SLIP_COMPRESSED=y
-CONFIG_USB_USBNET=y
CONFIG_SLIP_MODE_SLIP6=y
+CONFIG_USB_USBNET=y
CONFIG_WCNSS_CORE=y
CONFIG_WCNSS_CORE_PRONTO=y
CONFIG_INPUT_EVDEV=y
@@ -273,10 +271,11 @@
CONFIG_POWER_SUPPLY=y
CONFIG_BATTERY_BQ28400=y
CONFIG_QPNP_CHARGER=y
+CONFIG_BATTERY_BCL=y
CONFIG_QPNP_BMS=y
+CONFIG_SENSORS_EPM_ADC=y
CONFIG_SENSORS_QPNP_ADC_VOLTAGE=y
CONFIG_SENSORS_QPNP_ADC_CURRENT=y
-CONFIG_SENSORS_EPM_ADC=y
CONFIG_THERMAL=y
CONFIG_THERMAL_TSENS8974=y
CONFIG_THERMAL_QPNP=y
@@ -411,4 +410,3 @@
CONFIG_CRYPTO_DEV_QCE=m
CONFIG_CRYPTO_DEV_QCEDEV=m
CONFIG_CRC_CCITT=y
-CONFIG_BATTERY_BCL=y
diff --git a/arch/arm/configs/msm8974_defconfig b/arch/arm/configs/msm8974_defconfig
index aef30fb..af832cb 100644
--- a/arch/arm/configs/msm8974_defconfig
+++ b/arch/arm/configs/msm8974_defconfig
@@ -51,7 +51,6 @@
CONFIG_MSM_SYSMON_COMM=y
CONFIG_MSM_PIL_LPASS_QDSP6V5=y
CONFIG_MSM_PIL_MSS_QDSP6V5=y
-CONFIG_MSM_PIL_MBA=y
CONFIG_MSM_PIL_VENUS=y
CONFIG_MSM_PIL_PRONTO=y
CONFIG_MSM_TZ_LOG=y
@@ -240,8 +239,8 @@
CONFIG_MSM_RMNET_BAM=y
CONFIG_SLIP=y
CONFIG_SLIP_COMPRESSED=y
-CONFIG_USB_USBNET=y
CONFIG_SLIP_MODE_SLIP6=y
+CONFIG_USB_USBNET=y
CONFIG_WCNSS_CORE=y
CONFIG_WCNSS_CORE_PRONTO=y
CONFIG_INPUT_EVDEV=y
@@ -272,13 +271,14 @@
CONFIG_GPIO_QPNP_PIN=y
CONFIG_GPIO_QPNP_PIN_DEBUG=y
CONFIG_POWER_SUPPLY=y
-CONFIG_BATTERY_BQ28400=y
CONFIG_SMB350_CHARGER=y
+CONFIG_BATTERY_BQ28400=y
CONFIG_QPNP_CHARGER=y
+CONFIG_BATTERY_BCL=y
CONFIG_QPNP_BMS=y
+CONFIG_SENSORS_EPM_ADC=y
CONFIG_SENSORS_QPNP_ADC_VOLTAGE=y
CONFIG_SENSORS_QPNP_ADC_CURRENT=y
-CONFIG_SENSORS_EPM_ADC=y
CONFIG_THERMAL=y
CONFIG_THERMAL_TSENS8974=y
CONFIG_THERMAL_QPNP=y
@@ -427,4 +427,3 @@
CONFIG_CRYPTO_DEV_QCE=m
CONFIG_CRYPTO_DEV_QCEDEV=m
CONFIG_CRC_CCITT=y
-CONFIG_BATTERY_BCL=y
diff --git a/arch/arm/configs/msm9615_defconfig b/arch/arm/configs/msm9615_defconfig
index 81b853d..a052609 100644
--- a/arch/arm/configs/msm9615_defconfig
+++ b/arch/arm/configs/msm9615_defconfig
@@ -199,7 +199,6 @@
CONFIG_DEBUG_GPIO=y
CONFIG_GPIO_SYSFS=y
CONFIG_POWER_SUPPLY=y
-# CONFIG_BATTERY_MSM is not set
CONFIG_SENSORS_PM8XXX_ADC=y
CONFIG_THERMAL=y
CONFIG_THERMAL_TSENS8960=y
diff --git a/arch/arm/configs/msm9625_defconfig b/arch/arm/configs/msm9625_defconfig
index 783be1b..6297ef5 100644
--- a/arch/arm/configs/msm9625_defconfig
+++ b/arch/arm/configs/msm9625_defconfig
@@ -21,6 +21,7 @@
CONFIG_BLK_DEV_INITRD=y
CONFIG_RD_BZIP2=y
CONFIG_RD_LZMA=y
+CONFIG_PANIC_TIMEOUT=5
CONFIG_KALLSYMS_ALL=y
CONFIG_EMBEDDED=y
CONFIG_PROFILING=y
@@ -43,6 +44,7 @@
CONFIG_MSM_RPM_REGULATOR_SMD=y
CONFIG_MSM_DIRECT_SCLK_ACCESS=y
CONFIG_MSM_WATCHDOG_V2=y
+CONFIG_MSM_DLOAD_MODE=y
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
CONFIG_ARM_ARCH_TIMER=y
@@ -51,12 +53,12 @@
CONFIG_HIGHMEM=y
CONFIG_VMALLOC_RESERVE=0x19000000
CONFIG_USE_OF=y
-CONFIG_CPU_IDLE=y
CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_GOV_POWERSAVE=y
CONFIG_CPU_FREQ_GOV_USERSPACE=y
CONFIG_CPU_FREQ_GOV_ONDEMAND=y
CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
+CONFIG_CPU_IDLE=y
CONFIG_VFP=y
CONFIG_NEON=y
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
@@ -66,15 +68,6 @@
CONFIG_UNIX=y
CONFIG_INET=y
CONFIG_IPV6=y
-CONFIG_NET_SCHED=y
-CONFIG_NET_SCH_HTB=y
-CONFIG_NET_SCH_PRIO=y
-CONFIG_NET_CLS_FW=y
-# CONFIG_WIRELESS is not set
-CONFIG_MTD=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_OF_PARTS=y
-CONFIG_MTD_BLOCK=y
CONFIG_NETFILTER=y
CONFIG_NETFILTER_DEBUG=y
CONFIG_NETFILTER_NETLINK_QUEUE=y
@@ -86,14 +79,16 @@
CONFIG_NF_CONNTRACK_PPTP=y
CONFIG_NF_CONNTRACK_SIP=y
CONFIG_NF_CONNTRACK_TFTP=y
-CONFIG_NETFILTER_XT_MARK=y
-CONFIG_NETFILTER_XT_CONNMARK=y
-CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=y
-CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y
-CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
-CONFIG_NETFILTER_XT_MATCH_IPRANGE=y
-CONFIG_NETFILTER_XT_MATCH_MULTIPORT=y
-CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_HTB=y
+CONFIG_NET_SCH_PRIO=y
+CONFIG_NET_CLS_FW=y
+CONFIG_CFG80211=m
+CONFIG_NL80211_TESTMODE=y
+CONFIG_MTD=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_OF_PARTS=y
+CONFIG_MTD_BLOCK=y
# CONFIG_MTD_MSM_NAND is not set
CONFIG_MTD_MSM_QPIC_NAND=y
CONFIG_BLK_DEV_LOOP=y
@@ -104,13 +99,6 @@
# CONFIG_NET_VENDOR_CIRRUS is not set
# CONFIG_NET_VENDOR_FARADAY is not set
# CONFIG_NET_VENDOR_INTEL is not set
-CONFIG_WIRELESS=y
-CONFIG_CFG80211=m
-CONFIG_NL80211_TESTMODE=y
-CONFIG_ATH_COMMON=m
-CONFIG_ATH6KL=m
-CONFIG_ATH6KL_SDIO=m
-CONFIG_ATH6KL_DEBUG=y
CONFIG_KS8851=y
# CONFIG_NET_VENDOR_MICROCHIP is not set
# CONFIG_MSM_RMNET is not set
@@ -123,6 +111,7 @@
# CONFIG_INPUT_MOUSEDEV is not set
# CONFIG_INPUT_KEYBOARD is not set
# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_EVDEV=y
CONFIG_INPUT_MISC=y
CONFIG_INPUT_UINPUT=y
CONFIG_INPUT_GPIO=m
@@ -141,15 +130,16 @@
CONFIG_SPMI=y
CONFIG_SPMI_MSM_PMIC_ARB=y
CONFIG_MSM_QPNP_INT=y
-CONFIG_REGULATOR_FIXED_VOLTAGE=y
CONFIG_DEBUG_GPIO=y
CONFIG_GPIO_SYSFS=y
CONFIG_GPIO_QPNP_PIN=y
CONFIG_GPIO_QPNP_PIN_DEBUG=y
CONFIG_POWER_SUPPLY=y
-CONFIG_HWMON=y
CONFIG_SENSORS_QPNP_ADC_VOLTAGE=y
+CONFIG_THERMAL=y
+CONFIG_THERMAL_TSENS8974=y
CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
CONFIG_REGULATOR_QPNP=y
CONFIG_ION=y
CONFIG_ION_MSM=y
@@ -210,5 +200,3 @@
# CONFIG_CRYPTO_HW is not set
CONFIG_CRC_CCITT=y
CONFIG_LIBCRC32C=y
-CONFIG_PANIC_TIMEOUT=5
-CONFIG_MSM_DLOAD_MODE=y
diff --git a/arch/arm/include/asm/mach/mmc.h b/arch/arm/include/asm/mach/mmc.h
index d341ea9..e7de62e 100644
--- a/arch/arm/include/asm/mach/mmc.h
+++ b/arch/arm/include/asm/mach/mmc.h
@@ -149,7 +149,7 @@
int status_gpio;
/* Indicates the polarity of the GPIO line when card is inserted */
bool is_status_gpio_active_low;
- unsigned int sdiowakeup_irq;
+ int sdiowakeup_irq;
unsigned long irq_flags;
unsigned long mmc_bus_width;
int (*wpswitch) (struct device *);
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index 7a443ec..176696c 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -279,30 +279,6 @@
select SPARSE_IRQ
select MSM_NOPM
-config ARCH_MSM8226
- bool "MSM8226"
- select ARCH_MSM_KRAITMP
- select GPIO_MSM_V3
- select ARM_GIC
- select CPU_V7
- select MSM_SCM if SMP
- select MSM_GPIOMUX
- select MULTI_IRQ_HANDLER
- select MSM_MULTIMEDIA_USE_ION
- select MSM_PIL
- select MSM_SPM_V2
- select MSM_L2_SPM
- select MSM_PM8X60 if PM
- select MAY_HAVE_SPARSE_IRQ
- select SPARSE_IRQ
- select MSM_RPM_SMD
- select REGULATOR
- select MSM_QDSP6_APRV2
- select MSM_QDSP6V2_CODECS
- select MSM_AUDIO_QDSP6V2 if SND_SOC
- select MSM_RPM_REGULATOR_SMD
- select ARM_HAS_SG_CHAIN
-
config ARCH_FSM9XXX
bool "FSM9XXX"
select ARCH_MSM_SCORPION
@@ -387,6 +363,20 @@
select MSM_GPIOMUX
select MSM_NATIVE_RESTART
select MSM_RESTART_V2
+
+config ARCH_MSM8226
+ bool "MSM8226"
+ select ARM_GIC
+ select GIC_SECURE
+ select SMP
+ select ARCH_MSM_CORTEXMP
+ select CPU_V7
+ select MSM_SCM if SMP
+ select MAY_HAVE_SPARSE_IRQ
+ select SPARSE_IRQ
+ select MULTI_IRQ_HANDLER
+ select GPIO_MSM_V3
+ select MSM_GPIOMUX
endmenu
choice
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index b9a16fa..403c32c 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -299,7 +299,7 @@
obj-$(CONFIG_ARCH_MSM8930) += acpuclock-8930.o acpuclock-8627.o acpuclock-8930aa.o
obj-$(CONFIG_ARCH_MPQ8092) += board-8092.o board-8092-gpiomux.o
obj-$(CONFIG_ARCH_MSM8226) += board-8226.o board-8226-gpiomux.o
-obj-$(CONFIG_ARCH_MSM8910) += board-8910.o
+obj-$(CONFIG_ARCH_MSM8910) += board-8910.o board-8910-gpiomux.o
obj-$(CONFIG_MACH_SAPPHIRE) += board-sapphire.o board-sapphire-gpio.o
obj-$(CONFIG_MACH_SAPPHIRE) += board-sapphire-keypad.o board-sapphire-panel.o
diff --git a/arch/arm/mach-msm/board-8064-pmic.c b/arch/arm/mach-msm/board-8064-pmic.c
index c973bd5..a358bba 100644
--- a/arch/arm/mach-msm/board-8064-pmic.c
+++ b/arch/arm/mach-msm/board-8064-pmic.c
@@ -395,7 +395,6 @@
#define CHG_TERM_MA 100
static struct pm8921_charger_platform_data
apq8064_pm8921_chg_pdata __devinitdata = {
- .safety_time = 180,
.update_time = 60000,
.max_voltage = MAX_VOLTAGE_MV,
.min_voltage = 3200,
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index c6bcb6b..4ea9d8e 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -1257,29 +1257,20 @@
* clock is running at 100KHz and voltage levels are at 3.3
* and 5 volts
*/
-static int enable_100KHz_ls(int enable)
+static int enable_100KHz_ls(int enable, int gpio)
{
- int ret = 0;
- if (enable) {
- ret = gpio_request(SX150X_GPIO(1, 10),
- "cs8427_100KHZ_ENABLE");
- if (ret) {
- pr_err("%s: Failed to request gpio %d\n", __func__,
- SX150X_GPIO(1, 10));
- return ret;
- }
- gpio_direction_output(SX150X_GPIO(1, 10), 1);
- } else {
- gpio_direction_output(SX150X_GPIO(1, 10), 0);
- gpio_free(SX150X_GPIO(1, 10));
- }
- return ret;
+ if (enable)
+ gpio_direction_output(gpio, 1);
+ else
+ gpio_direction_output(gpio, 0);
+ return 0;
}
static struct cs8427_platform_data cs8427_i2c_platform_data = {
.irq = SX150X_GPIO(1, 4),
.reset_gpio = SX150X_GPIO(1, 6),
.enable = enable_100KHz_ls,
+ .ls_gpio = SX150X_GPIO(1, 10),
};
static struct i2c_board_info cs8427_device_info[] __initdata = {
@@ -2703,7 +2694,7 @@
};
static struct msm_spi_platform_data mpq8064_qup_spi_gsbi6_pdata = {
- .max_clock_speed = 1100000,
+ .max_clock_speed = 10800000,
};
static struct ci_bridge_platform_data mpq8064_ci_bridge_pdata = {
diff --git a/arch/arm/mach-msm/board-8226.c b/arch/arm/mach-msm/board-8226.c
index 33f18a2..980f312 100644
--- a/arch/arm/mach-msm/board-8226.c
+++ b/arch/arm/mach-msm/board-8226.c
@@ -50,7 +50,7 @@
CLK_DUMMY("core_clk", HSUSB_CORE_CLK, "f9a55000.usb", OFF),
};
-struct clock_init_data msm_dummy_clock_init_data __initdata = {
+static struct clock_init_data msm_dummy_clock_init_data __initdata = {
.table = msm_clocks_dummy,
.size = ARRAY_SIZE(msm_clocks_dummy),
};
@@ -66,7 +66,6 @@
of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
}
-
static const char *msm8226_dt_match[] __initconst = {
"qcom,msm8226",
NULL
diff --git a/arch/arm/mach-msm/board-8910-gpiomux.c b/arch/arm/mach-msm/board-8910-gpiomux.c
new file mode 100644
index 0000000..a67f916
--- /dev/null
+++ b/arch/arm/mach-msm/board-8910-gpiomux.c
@@ -0,0 +1,29 @@
+/* Copyright (c) 2012, 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/init.h>
+#include <linux/ioport.h>
+#include <mach/board.h>
+#include <mach/gpio.h>
+#include <mach/gpiomux.h>
+
+void __init msm8910_init_gpiomux(void)
+{
+ int rc;
+
+ rc = msm_gpiomux_init(NR_GPIO_IRQS);
+ if (rc) {
+ pr_err(KERN_ERR "msm_8910_init_gpiomux failed %d\n", rc);
+ return;
+ }
+}
diff --git a/arch/arm/mach-msm/board-8910.c b/arch/arm/mach-msm/board-8910.c
index b79ee0b..b031dac 100644
--- a/arch/arm/mach-msm/board-8910.c
+++ b/arch/arm/mach-msm/board-8910.c
@@ -54,7 +54,7 @@
CLK_DUMMY("bus_clk", NULL, "msm_sdcc.2", OFF),
};
-struct clock_init_data msm_dummy_clock_init_data __initdata = {
+static struct clock_init_data msm_dummy_clock_init_data __initdata = {
.table = msm_clocks_dummy,
.size = ARRAY_SIZE(msm_clocks_dummy),
};
@@ -71,6 +71,7 @@
{
struct of_dev_auxdata *adata = msm8910_auxdata_lookup;
+ msm8910_init_gpiomux();
msm_clock_init(&msm_dummy_clock_init_data);
if (socinfo_init() < 0)
diff --git a/arch/arm/mach-msm/board-8930-pmic.c b/arch/arm/mach-msm/board-8930-pmic.c
index 0c7666b..d35a907 100644
--- a/arch/arm/mach-msm/board-8930-pmic.c
+++ b/arch/arm/mach-msm/board-8930-pmic.c
@@ -315,7 +315,6 @@
#define MAX_VOLTAGE_MV 4200
#define CHG_TERM_MA 100
static struct pm8921_charger_platform_data pm8921_chg_pdata __devinitdata = {
- .safety_time = 180,
.update_time = 60000,
.max_voltage = MAX_VOLTAGE_MV,
.min_voltage = 3200,
diff --git a/arch/arm/mach-msm/board-8960-pmic.c b/arch/arm/mach-msm/board-8960-pmic.c
index 9efedb1..1a3d90d 100644
--- a/arch/arm/mach-msm/board-8960-pmic.c
+++ b/arch/arm/mach-msm/board-8960-pmic.c
@@ -396,7 +396,6 @@
#define MAX_VOLTAGE_MV 4200
#define CHG_TERM_MA 100
static struct pm8921_charger_platform_data pm8921_chg_pdata __devinitdata = {
- .safety_time = 180,
.update_time = 60000,
.max_voltage = MAX_VOLTAGE_MV,
.min_voltage = 3200,
diff --git a/arch/arm/mach-msm/board-9625.c b/arch/arm/mach-msm/board-9625.c
index 5c7eebe..a41fc06 100644
--- a/arch/arm/mach-msm/board-9625.c
+++ b/arch/arm/mach-msm/board-9625.c
@@ -108,6 +108,8 @@
"msm_sdcc.2", NULL),
OF_DEV_AUXDATA("qcom,msm-sdcc", 0xF9864000, \
"msm_sdcc.3", NULL),
+ OF_DEV_AUXDATA("qcom,msm-tsens", 0xFC4A8000, \
+ "msm-tsens", NULL),
{}
};
diff --git a/arch/arm/mach-msm/include/mach/board.h b/arch/arm/mach-msm/include/mach/board.h
index ff4776a..b2bf546 100644
--- a/arch/arm/mach-msm/include/mach/board.h
+++ b/arch/arm/mach-msm/include/mach/board.h
@@ -587,6 +587,7 @@
void msm_map_msm8226_io(void);
void msm8226_init_irq(void);
void msm8226_init_gpiomux(void);
+void msm8910_init_gpiomux(void);
void msm_map_msm8910_io(void);
void msm8910_init_irq(void);
diff --git a/arch/arm/mach-msm/include/mach/irqs-8226.h b/arch/arm/mach-msm/include/mach/irqs-8226.h
index fad7b90..7e174b9 100644
--- a/arch/arm/mach-msm/include/mach/irqs-8226.h
+++ b/arch/arm/mach-msm/include/mach/irqs-8226.h
@@ -24,15 +24,12 @@
#define GIC_PPI_START 16
#define GIC_SPI_START 32
-#define AVS_SVICINT (GIC_PPI_START + 6)
-#define AVS_SVICINTSWDONE (GIC_PPI_START + 7)
#define INT_ARMQC_PERFMON (GIC_PPI_START + 10)
/* PPI 15 is unused */
#define APCC_QGICL2PERFMONIRPTREQ (GIC_SPI_START + 1)
#define SC_SICL2PERFMONIRPTREQ APCC_QGICL2PERFMONIRPTREQ
#define TLMM_MSM_SUMMARY_IRQ (GIC_SPI_START + 208)
-#define SPS_BAM_DMA_IRQ (GIC_SPI_START + 105)
#define NR_MSM_IRQS 256
#define NR_GPIO_IRQS 146
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-8226.h b/arch/arm/mach-msm/include/mach/msm_iomap-8226.h
index 08bc981..c03b513 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-8226.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-8226.h
@@ -45,7 +45,4 @@
#define MSM_DEBUG_UART_PHYS 0xF991E000
#endif
-#define MSM8226_DBG_IMEM_PHYS 0xFE805000
-#define MSM8226_DBG_IMEM_SIZE SZ_4K
-
#endif
diff --git a/arch/arm/mach-msm/include/mach/msm_ipc_router.h b/arch/arm/mach-msm/include/mach/msm_ipc_router.h
new file mode 100644
index 0000000..45a7e19
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/msm_ipc_router.h
@@ -0,0 +1,181 @@
+/* Copyright (c) 2012, 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.
+ */
+
+#ifndef _MSM_IPC_ROUTER_H
+#define _MSM_IPC_ROUTER_H
+
+#include <linux/types.h>
+#include <linux/socket.h>
+#include <linux/errno.h>
+#include <linux/mm.h>
+#include <linux/list.h>
+#include <linux/wakelock.h>
+#include <linux/msm_ipc.h>
+
+#define MAX_WAKELOCK_NAME_SZ 32
+
+/**
+ * enum msm_ipc_router_event - Events that will be generated by IPC Router
+ */
+enum msm_ipc_router_event {
+ MSM_IPC_ROUTER_READ_CB = 0,
+ MSM_IPC_ROUTER_WRITE_DONE,
+};
+
+struct msm_ipc_port {
+ struct list_head list;
+
+ struct msm_ipc_port_addr this_port;
+ struct msm_ipc_port_name port_name;
+ uint32_t type;
+ unsigned flags;
+ spinlock_t port_lock;
+
+ struct list_head incomplete;
+ struct mutex incomplete_lock;
+
+ struct list_head port_rx_q;
+ struct mutex port_rx_q_lock;
+ char rx_wakelock_name[MAX_WAKELOCK_NAME_SZ];
+ struct wake_lock port_rx_wake_lock;
+ wait_queue_head_t port_rx_wait_q;
+
+ int restart_state;
+ spinlock_t restart_lock;
+ wait_queue_head_t restart_wait;
+
+ void *endpoint;
+ void (*notify)(unsigned event, void *priv);
+
+ uint32_t num_tx;
+ uint32_t num_rx;
+ unsigned long num_tx_bytes;
+ unsigned long num_rx_bytes;
+ void *priv;
+};
+
+#ifdef CONFIG_MSM_IPC_ROUTER
+/**
+ * msm_ipc_router_create_port() - Create a IPC Router port/endpoint
+ * @notify: Callback function to notify any event on the port.
+ * @priv: Private info to be passed while the notification is generated.
+ *
+ * @return: Pointer to the port on success, NULL on error.
+ */
+struct msm_ipc_port *msm_ipc_router_create_port(
+ void (*notify)(unsigned event, void *priv),
+ void *priv);
+
+/**
+ * msm_ipc_router_lookup_server_name() - Resolve server address
+ * @srv_name: Name<service:instance> of the server to be resolved.
+ * @srv_info: Buffer to hold the resolved address.
+ * @num_entries_in_array: Number of server info the buffer can hold.
+ * @lookup_mask: Mask to specify the range of instances to be resolved.
+ *
+ * @return: Number of server addresses resolved on success, < 0 on error.
+ */
+int msm_ipc_router_lookup_server_name(struct msm_ipc_port_name *srv_name,
+ struct msm_ipc_server_info *srv_info,
+ int num_entries_in_array,
+ uint32_t lookup_mask);
+
+/**
+ * msm_ipc_router_send_msg() - Send a message/packet
+ * @src: Sender's address/port.
+ * @dest: Destination address.
+ * @data: Pointer to the data to be sent.
+ * @data_len: Length of the data to be sent.
+ *
+ * @return: 0 on success, < 0 on error.
+ */
+int msm_ipc_router_send_msg(struct msm_ipc_port *src,
+ struct msm_ipc_addr *dest,
+ void *data, unsigned int data_len);
+
+/**
+ * msm_ipc_router_get_curr_pkt_size() - Get the packet size of the first
+ * packet in the rx queue
+ * @port_ptr: Port which owns the rx queue.
+ *
+ * @return: Returns the size of the first packet, if available.
+ * 0 if no packets available, < 0 on error.
+ */
+int msm_ipc_router_get_curr_pkt_size(struct msm_ipc_port *port_ptr);
+
+/**
+ * msm_ipc_router_read_msg() - Read a message/packet
+ * @port_ptr: Receiver's port/address.
+ * @data: Pointer containing the address of the received data.
+ * @src: Address of the sender/source.
+ * @len: Length of the data being read.
+ *
+ * @return: 0 on success, < 0 on error.
+ */
+int msm_ipc_router_read_msg(struct msm_ipc_port *port_ptr,
+ struct msm_ipc_addr *src,
+ unsigned char **data,
+ unsigned int *len);
+
+/**
+ * msm_ipc_router_close_port() - Close the port
+ * @port_ptr: Pointer to the port to be closed.
+ *
+ * @return: 0 on success, < 0 on error.
+ */
+int msm_ipc_router_close_port(struct msm_ipc_port *port_ptr);
+
+#else
+
+struct msm_ipc_port *msm_ipc_router_create_port(
+ void (*notify)(unsigned event, void *priv),
+ void *priv)
+{
+ return NULL;
+}
+
+int msm_ipc_router_lookup_server_name(struct msm_ipc_port_name *srv_name,
+ struct msm_ipc_server_info *srv_info,
+ int num_entries_in_array,
+ uint32_t lookup_mask)
+{
+ return -ENODEV;
+}
+
+int msm_ipc_router_send_msg(struct msm_ipc_port *src,
+ struct msm_ipc_addr *dest,
+ void *data, unsigned int data_len)
+{
+ return -ENODEV;
+}
+
+int msm_ipc_router_get_curr_pkt_size(struct msm_ipc_port *port_ptr)
+{
+ return -ENODEV;
+}
+
+int msm_ipc_router_read_msg(struct msm_ipc_port *port_ptr,
+ struct msm_ipc_addr *src,
+ unsigned char **data,
+ unsigned int *len)
+{
+ return -ENODEV;
+}
+
+int msm_ipc_router_close_port(struct msm_ipc_port *port_ptr)
+{
+ return -ENODEV;
+}
+
+#endif
+
+#endif
diff --git a/arch/arm/mach-msm/io.c b/arch/arm/mach-msm/io.c
index ae908e1..52bb8ef 100644
--- a/arch/arm/mach-msm/io.c
+++ b/arch/arm/mach-msm/io.c
@@ -519,7 +519,6 @@
MSM_CHIP_DEVICE(APCS_GCC, MSM8226),
MSM_CHIP_DEVICE(TLMM, MSM8226),
MSM_CHIP_DEVICE(IMEM, MSM8226),
- MSM_CHIP_DEVICE(DBG_IMEM, MSM8226),
{
.virtual = (unsigned long) MSM_SHARED_RAM_BASE,
.length = MSM_SHARED_RAM_SIZE,
diff --git a/arch/arm/mach-msm/ipc_router.c b/arch/arm/mach-msm/ipc_router.c
index ac33836..8f1d197 100644
--- a/arch/arm/mach-msm/ipc_router.c
+++ b/arch/arm/mach-msm/ipc_router.c
@@ -33,6 +33,7 @@
#include <mach/smem_log.h>
#include <mach/subsystem_notif.h>
+#include <mach/msm_ipc_router.h>
#include "ipc_router.h"
#include "modem_notifier.h"
@@ -111,11 +112,14 @@
struct msm_ipc_server {
struct list_head list;
struct msm_ipc_port_name name;
+ char pdev_name[32];
+ int next_pdev_id;
struct list_head server_port_list;
};
struct msm_ipc_server_port {
struct list_head list;
+ struct platform_device pdev;
struct msm_ipc_port_addr server_addr;
struct msm_ipc_router_xprt_info *xprt_info;
};
@@ -366,6 +370,102 @@
return;
}
+static struct sk_buff_head *msm_ipc_router_buf_to_skb(void *buf,
+ unsigned int buf_len)
+{
+ struct sk_buff_head *skb_head;
+ struct sk_buff *skb;
+ int first = 1, offset = 0;
+ int skb_size, data_size;
+ void *data;
+
+ skb_head = kmalloc(sizeof(struct sk_buff_head), GFP_KERNEL);
+ if (!skb_head) {
+ pr_err("%s: Couldnot allocate skb_head\n", __func__);
+ return NULL;
+ }
+ skb_queue_head_init(skb_head);
+
+ data_size = buf_len;
+ while (offset != buf_len) {
+ skb_size = data_size;
+ if (first)
+ skb_size += IPC_ROUTER_HDR_SIZE;
+
+ skb = alloc_skb(skb_size, GFP_KERNEL);
+ if (!skb) {
+ if (skb_size <= (PAGE_SIZE/2)) {
+ pr_err("%s: cannot allocate skb\n", __func__);
+ goto buf_to_skb_error;
+ }
+ data_size = data_size / 2;
+ continue;
+ }
+
+ if (first) {
+ skb_reserve(skb, IPC_ROUTER_HDR_SIZE);
+ first = 0;
+ }
+
+ data = skb_put(skb, data_size);
+ memcpy(skb->data, buf + offset, data_size);
+ skb_queue_tail(skb_head, skb);
+ offset += data_size;
+ data_size = buf_len - offset;
+ }
+ return skb_head;
+
+buf_to_skb_error:
+ while (!skb_queue_empty(skb_head)) {
+ skb = skb_dequeue(skb_head);
+ kfree_skb(skb);
+ }
+ kfree(skb_head);
+ return NULL;
+}
+
+static void *msm_ipc_router_skb_to_buf(struct sk_buff_head *skb_head,
+ unsigned int len)
+{
+ struct sk_buff *temp;
+ int offset = 0, buf_len = 0, copy_len;
+ void *buf;
+
+ if (!skb_head) {
+ pr_err("%s: NULL skb_head\n", __func__);
+ return NULL;
+ }
+
+ temp = skb_peek(skb_head);
+ buf_len = len;
+ buf = kmalloc(buf_len, GFP_KERNEL);
+ if (!buf) {
+ pr_err("%s: cannot allocate buf\n", __func__);
+ return NULL;
+ }
+ skb_queue_walk(skb_head, temp) {
+ copy_len = buf_len < temp->len ? buf_len : temp->len;
+ memcpy(buf + offset, temp->data, copy_len);
+ offset += copy_len;
+ buf_len -= copy_len;
+ }
+ return buf;
+}
+
+static void msm_ipc_router_free_skb(struct sk_buff_head *skb_head)
+{
+ struct sk_buff *temp_skb;
+
+ if (!skb_head)
+ return;
+
+ while (!skb_queue_empty(skb_head)) {
+ temp_skb = skb_dequeue(skb_head);
+ kfree_skb(temp_skb);
+ }
+ kfree(skb_head);
+}
+
static int post_control_ports(struct rr_packet *pkt)
{
struct msm_ipc_port *port_ptr;
@@ -437,8 +537,7 @@
}
struct msm_ipc_port *msm_ipc_router_create_raw_port(void *endpoint,
- void (*notify)(unsigned event, void *data,
- void *addr, void *priv),
+ void (*notify)(unsigned event, void *priv),
void *priv)
{
struct msm_ipc_port *port_ptr;
@@ -628,6 +727,10 @@
return NULL;
}
+static void dummy_release(struct device *dev)
+{
+}
+
/**
* msm_ipc_router_create_server() - Add server info to hash table
* @service: Service ID of the server info to be created.
@@ -660,7 +763,7 @@
goto create_srv_port;
}
- server = kmalloc(sizeof(struct msm_ipc_server), GFP_KERNEL);
+ server = kzalloc(sizeof(struct msm_ipc_server), GFP_KERNEL);
if (!server) {
pr_err("%s: Server allocation failed\n", __func__);
return NULL;
@@ -669,9 +772,12 @@
server->name.instance = instance;
INIT_LIST_HEAD(&server->server_port_list);
list_add_tail(&server->list, &server_list[key]);
+ scnprintf(server->pdev_name, sizeof(server->pdev_name),
+ "QMI%08x:%08x", service, instance);
+ server->next_pdev_id = 1;
create_srv_port:
- server_port = kmalloc(sizeof(struct msm_ipc_server_port), GFP_KERNEL);
+ server_port = kzalloc(sizeof(struct msm_ipc_server_port), GFP_KERNEL);
if (!server_port) {
if (list_empty(&server->server_port_list)) {
list_del(&server->list);
@@ -685,6 +791,11 @@
server_port->xprt_info = xprt_info;
list_add_tail(&server_port->list, &server->server_port_list);
+ server_port->pdev.name = server->pdev_name;
+ server_port->pdev.id = server->next_pdev_id++;
+ server_port->pdev.dev.release = dummy_release;
+ platform_device_register(&server_port->pdev);
+
return server;
}
@@ -714,6 +825,7 @@
break;
}
if (server_port) {
+ platform_device_unregister(&server_port->pdev);
list_del(&server_port->list);
kfree(server_port);
}
@@ -1079,6 +1191,7 @@
ctl.srv.port_id = svr_port->server_addr.port_id;
relay_ctl_msg(xprt_info, &ctl);
broadcast_ctl_msg_locally(&ctl);
+ platform_device_unregister(&svr_port->pdev);
list_del(&svr_port->list);
kfree(svr_port);
}
@@ -1432,7 +1545,6 @@
struct rr_packet *pkt = NULL;
struct msm_ipc_port *port_ptr;
struct sk_buff *head_skb;
- struct msm_ipc_port_addr *src_addr;
struct msm_ipc_router_remote_port *rport_ptr;
uint32_t resume_tx, resume_tx_node_id, resume_tx_port_id;
@@ -1527,30 +1639,15 @@
}
}
- if (!port_ptr->notify) {
- mutex_lock(&port_ptr->port_rx_q_lock);
- wake_lock(&port_ptr->port_rx_wake_lock);
- list_add_tail(&pkt->list, &port_ptr->port_rx_q);
- wake_up(&port_ptr->port_rx_wait_q);
- mutex_unlock(&port_ptr->port_rx_q_lock);
- mutex_unlock(&local_ports_lock);
- } else {
- mutex_lock(&port_ptr->port_rx_q_lock);
- src_addr = kmalloc(sizeof(struct msm_ipc_port_addr),
- GFP_KERNEL);
- if (src_addr) {
- src_addr->node_id = hdr->src_node_id;
- src_addr->port_id = hdr->src_port_id;
- }
- skb_pull(head_skb, IPC_ROUTER_HDR_SIZE);
- mutex_unlock(&local_ports_lock);
+ mutex_lock(&port_ptr->port_rx_q_lock);
+ wake_lock(&port_ptr->port_rx_wake_lock);
+ list_add_tail(&pkt->list, &port_ptr->port_rx_q);
+ wake_up(&port_ptr->port_rx_wait_q);
+ if (port_ptr->notify)
port_ptr->notify(MSM_IPC_ROUTER_READ_CB,
- pkt->pkt_fragment_q, src_addr, port_ptr->priv);
- mutex_unlock(&port_ptr->port_rx_q_lock);
- pkt->pkt_fragment_q = NULL;
- src_addr = NULL;
- release_pkt(pkt);
- }
+ port_ptr->priv);
+ mutex_unlock(&port_ptr->port_rx_q_lock);
+ mutex_unlock(&local_ports_lock);
process_done:
if (resume_tx) {
@@ -1904,6 +2001,28 @@
return ret;
}
+int msm_ipc_router_send_msg(struct msm_ipc_port *src,
+ struct msm_ipc_addr *dest,
+ void *data, unsigned int data_len)
+{
+ struct sk_buff_head *out_skb_head;
+ int ret;
+
+ out_skb_head = msm_ipc_router_buf_to_skb(data, data_len);
+ if (!out_skb_head) {
+ pr_err("%s: SKB conversion failed\n", __func__);
+ return -EFAULT;
+ }
+
+ ret = msm_ipc_router_send_to(src, out_skb_head, dest);
+ if (ret < 0) {
+ pr_err("%s: msm_ipc_router_send_to failed - ret: %d\n",
+ __func__, ret);
+ msm_ipc_router_free_skb(out_skb_head);
+ }
+ return 0;
+}
+
int msm_ipc_router_read(struct msm_ipc_port *port_ptr,
struct sk_buff_head **data,
size_t buf_len)
@@ -1939,7 +2058,7 @@
int msm_ipc_router_recv_from(struct msm_ipc_port *port_ptr,
struct sk_buff_head **data,
struct msm_ipc_addr *src,
- unsigned long timeout)
+ long timeout)
{
int ret, data_len, align_size;
struct sk_buff *temp_skb;
@@ -1996,11 +2115,42 @@
return data_len;
}
+int msm_ipc_router_read_msg(struct msm_ipc_port *port_ptr,
+ struct msm_ipc_addr *src,
+ unsigned char **data,
+ unsigned int *len)
+{
+ struct sk_buff_head *in_skb_head;
+ int ret;
+
+ ret = msm_ipc_router_recv_from(port_ptr, &in_skb_head, src, -1);
+ if (ret < 0) {
+ pr_err("%s: msm_ipc_router_recv_from failed - ret: %d\n",
+ __func__, ret);
+ return ret;
+ }
+
+ *data = msm_ipc_router_skb_to_buf(in_skb_head, ret);
+ if (!(*data))
+ pr_err("%s: Buf conversion failed\n", __func__);
+
+ *len = ret;
+ msm_ipc_router_free_skb(in_skb_head);
+ return 0;
+}
+
struct msm_ipc_port *msm_ipc_router_create_port(
- void (*notify)(unsigned event, void *data, void *addr, void *priv),
+ void (*notify)(unsigned event, void *priv),
void *priv)
{
struct msm_ipc_port *port_ptr;
+ int ret;
+
+ ret = wait_for_completion_interruptible(&msm_ipc_local_router_up);
+ if (ret < 0) {
+ pr_err("%s: Error waiting for local router\n", __func__);
+ return NULL;
+ }
port_ptr = msm_ipc_router_create_raw_port(NULL, notify, priv);
if (!port_ptr)
diff --git a/arch/arm/mach-msm/ipc_router.h b/arch/arm/mach-msm/ipc_router.h
index 07bc5e0..39038f2 100644
--- a/arch/arm/mach-msm/ipc_router.h
+++ b/arch/arm/mach-msm/ipc_router.h
@@ -18,22 +18,18 @@
#include <linux/errno.h>
#include <linux/mm.h>
#include <linux/list.h>
-#include <linux/cdev.h>
#include <linux/platform_device.h>
-#include <linux/wakelock.h>
#include <linux/msm_ipc.h>
#include <net/sock.h>
/* definitions for the R2R wire protcol */
#define IPC_ROUTER_VERSION 1
-#define IPC_ROUTER_PROCESSORS_MAX 4
#define IPC_ROUTER_CLIENT_BCAST_ID 0xffffffff
#define IPC_ROUTER_ADDRESS 0xfffffffe
#define IPC_ROUTER_NID_LOCAL 1
-#define IPC_ROUTER_NID_REMOTE 0
#define IPC_ROUTER_CTRL_CMD_DATA 1
#define IPC_ROUTER_CTRL_CMD_HELLO 2
@@ -51,18 +47,11 @@
#define IPC_ROUTER_XPRT_EVENT_OPEN 2
#define IPC_ROUTER_XPRT_EVENT_CLOSE 3
-#define NUM_NODES 2
-
#define IPC_ROUTER_INFINITY -1
#define DEFAULT_RCV_TIMEO IPC_ROUTER_INFINITY
#define ALIGN_SIZE(x) ((4 - ((x) & 3)) & 3)
-enum {
- MSM_IPC_ROUTER_READ_CB = 0,
- MSM_IPC_ROUTER_WRITE_DONE,
-};
-
union rr_control_msg {
uint32_t cmd;
struct {
@@ -92,10 +81,6 @@
#define IPC_ROUTER_HDR_SIZE sizeof(struct rr_header)
#define MAX_IPC_PKT_SIZE 66000
-/* internals */
-
-#define IPC_ROUTER_MAX_REMOTE_SERVERS 100
-#define MAX_WAKELOCK_NAME_SZ 32
struct rr_packet {
struct list_head list;
@@ -103,50 +88,12 @@
uint32_t length;
};
-struct msm_ipc_port {
- struct list_head list;
-
- struct msm_ipc_port_addr this_port;
- struct msm_ipc_port_name port_name;
- uint32_t type;
- unsigned flags;
- spinlock_t port_lock;
-
- struct list_head incomplete;
- struct mutex incomplete_lock;
-
- struct list_head port_rx_q;
- struct mutex port_rx_q_lock;
- char rx_wakelock_name[MAX_WAKELOCK_NAME_SZ];
- struct wake_lock port_rx_wake_lock;
- wait_queue_head_t port_rx_wait_q;
-
- int restart_state;
- spinlock_t restart_lock;
- wait_queue_head_t restart_wait;
-
- void *endpoint;
- void (*notify)(unsigned event, void *data, void *addr, void *priv);
-
- uint32_t num_tx;
- uint32_t num_rx;
- unsigned long num_tx_bytes;
- unsigned long num_rx_bytes;
- void *priv;
-};
-
struct msm_ipc_sock {
struct sock sk;
struct msm_ipc_port *port;
void *default_pil;
};
-enum write_data_type {
- HEADER = 1,
- PACKMARK,
- PAYLOAD,
-};
-
struct msm_ipc_router_xprt {
char *name;
uint32_t link_id;
@@ -161,8 +108,6 @@
int (*close)(struct msm_ipc_router_xprt *xprt);
};
-extern struct completion msm_ipc_remote_router_up;
-
void msm_ipc_router_xprt_notify(struct msm_ipc_router_xprt *xprt,
unsigned event,
void *data);
@@ -173,8 +118,7 @@
struct msm_ipc_port *msm_ipc_router_create_raw_port(void *endpoint,
- void (*notify)(unsigned event, void *data,
- void *addr, void *priv),
+ void (*notify)(unsigned event, void *priv),
void *priv);
int msm_ipc_router_send_to(struct msm_ipc_port *src,
struct sk_buff_head *data,
@@ -182,27 +126,16 @@
int msm_ipc_router_read(struct msm_ipc_port *port_ptr,
struct sk_buff_head **data,
size_t buf_len);
-int msm_ipc_router_get_curr_pkt_size(struct msm_ipc_port *port_ptr);
int msm_ipc_router_bind_control_port(struct msm_ipc_port *port_ptr);
-int msm_ipc_router_lookup_server_name(struct msm_ipc_port_name *srv_name,
- struct msm_ipc_server_info *srv_info,
- int num_entries_in_array,
- uint32_t lookup_mask);
-int msm_ipc_router_close_port(struct msm_ipc_port *port_ptr);
-struct msm_ipc_port *msm_ipc_router_create_port(
- void (*notify)(unsigned event, void *data,
- void *addr, void *priv),
- void *priv);
int msm_ipc_router_recv_from(struct msm_ipc_port *port_ptr,
struct sk_buff_head **data,
struct msm_ipc_addr *src_addr,
- unsigned long timeout);
+ long timeout);
int msm_ipc_router_register_server(struct msm_ipc_port *server_port,
struct msm_ipc_addr *name);
int msm_ipc_router_unregister_server(struct msm_ipc_port *server_port);
-
int msm_ipc_router_init_sockets(void);
void msm_ipc_router_exit_sockets(void);
diff --git a/arch/arm/mach-msm/ipc_socket.c b/arch/arm/mach-msm/ipc_socket.c
index d3917f1..3a6abbd 100644
--- a/arch/arm/mach-msm/ipc_socket.c
+++ b/arch/arm/mach-msm/ipc_socket.c
@@ -30,6 +30,8 @@
#include <net/sock.h>
+#include <mach/msm_ipc_router.h>
+
#include "ipc_router.h"
#define msm_ipc_sk(sk) ((struct msm_ipc_sock *)(sk))
diff --git a/arch/arm/mach-msm/krait-regulator.c b/arch/arm/mach-msm/krait-regulator.c
index aa9b344..a568b52 100644
--- a/arch/arm/mach-msm/krait-regulator.c
+++ b/arch/arm/mach-msm/krait-regulator.c
@@ -56,16 +56,10 @@
* |_________________|
*/
-#define V_RETENTION 600000
-#define V_LDO_HEADROOM 150000
-
#define PMIC_VOLTAGE_MIN 350000
#define PMIC_VOLTAGE_MAX 1355000
#define LV_RANGE_STEP 5000
-/* use LDO for core voltage below LDO_THRESH */
-#define CORE_VOLTAGE_LDO_THRESH 750000
-
#define LOAD_PER_PHASE 3200000
#define CORE_VOLTAGE_MIN 900000
@@ -161,6 +155,10 @@
int load_uA;
enum krait_supply_mode mode;
void __iomem *reg_base;
+ int ldo_default_uV;
+ int retention_uV;
+ int headroom_uV;
+ int ldo_threshold_uV;
};
static u32 version;
@@ -200,11 +198,22 @@
return uV;
}
-static int set_krait_ldo_uv(struct krait_power_vreg *kvreg)
+static int set_krait_retention_uv(struct krait_power_vreg *kvreg, int uV)
{
uint32_t reg_val;
- reg_val = kvreg->uV - KRAIT_LDO_VOLTAGE_OFFSET / KRAIT_LDO_STEP;
+ reg_val = DIV_ROUND_UP(uV - KRAIT_LDO_VOLTAGE_OFFSET, KRAIT_LDO_STEP);
+ krait_masked_write(kvreg, APC_LDO_VREF_SET, VREF_RET_MASK,
+ reg_val << VREF_RET_POS);
+
+ return 0;
+}
+
+static int set_krait_ldo_uv(struct krait_power_vreg *kvreg, int uV)
+{
+ uint32_t reg_val;
+
+ reg_val = DIV_ROUND_UP(uV - KRAIT_LDO_VOLTAGE_OFFSET, KRAIT_LDO_STEP);
krait_masked_write(kvreg, APC_LDO_VREF_SET, VREF_LDO_MASK,
reg_val << VREF_LDO_BIT_POS);
@@ -252,7 +261,7 @@
if (kvreg->mode == LDO_MODE)
switch_to_using_hs(kvreg);
- set_krait_ldo_uv(kvreg);
+ set_krait_ldo_uv(kvreg, kvreg->uV);
/*
* enable ldo - note that both LDO and BHS are are supplying voltage to
@@ -310,8 +319,8 @@
int rc = 0;
list_for_each_entry(kvreg, &pvreg->krait_power_vregs, link) {
- if (kvreg->uV > CORE_VOLTAGE_LDO_THRESH
- || kvreg->uV > vmax - V_LDO_HEADROOM) {
+ if (kvreg->uV > kvreg->ldo_threshold_uV
+ || kvreg->uV > vmax - kvreg->headroom_uV) {
rc = switch_to_using_hs(kvreg);
if (rc < 0) {
pr_err("could not switch %s to hs rc = %d\n",
@@ -510,7 +519,7 @@
* switch to LDO mode. Hence round the voltage as per the LDO
* resolution
*/
- if (min_uV < CORE_VOLTAGE_LDO_THRESH) {
+ if (min_uV < kvreg->ldo_threshold_uV) {
if (min_uV < KRAIT_LDO_VOLTAGE_MIN)
min_uV = KRAIT_LDO_VOLTAGE_MIN;
min_uV = ROUND_UP_VOLTAGE(min_uV, KRAIT_LDO_STEP);
@@ -638,6 +647,9 @@
/* BHS has six different segments, turn them all on */
krait_masked_write(kvreg, APC_PWR_GATE_CTL,
BHS_SEG_EN_MASK, BHS_SEG_EN_DEFAULT << BHS_SEG_EN_BIT_POS);
+
+ set_krait_retention_uv(kvreg, kvreg->retention_uV);
+ set_krait_ldo_uv(kvreg, kvreg->ldo_default_uV);
}
static void glb_init(struct platform_device *pdev)
@@ -649,12 +661,31 @@
pr_debug("version= 0x%x\n", version);
}
+static int is_between(int left, int right, int value)
+{
+ if (left >= right && left >= value && value >= right)
+ return 1;
+ if (left <= right && left <= value && value <= right)
+ return 1;
+ return 0;
+}
+
+#define LDO_HDROOM_MIN 50000
+#define LDO_HDROOM_MAX 250000
+
+#define LDO_UV_MIN 465000
+#define LDO_UV_MAX 750000
+
+#define LDO_TH_MIN 600000
+#define LDO_TH_MAX 800000
+
static int __devinit krait_power_probe(struct platform_device *pdev)
{
struct krait_power_vreg *kvreg;
struct resource *res;
struct regulator_init_data *init_data = pdev->dev.platform_data;
int rc = 0;
+ int headroom_uV, retention_uV, ldo_default_uV, ldo_threshold_uV;
/* Initialize the pmic gang if it hasn't been initialized already */
if (the_gang == NULL) {
@@ -679,6 +710,57 @@
|= REGULATOR_MODE_NORMAL | REGULATOR_MODE_IDLE
| REGULATOR_MODE_FAST;
init_data->constraints.input_uV = init_data->constraints.max_uV;
+ rc = of_property_read_u32(pdev->dev.of_node,
+ "qcom,headroom-voltage",
+ &headroom_uV);
+ if (rc < 0) {
+ pr_err("headroom-voltage missing rc=%d\n", rc);
+ return rc;
+ }
+ if (!is_between(LDO_HDROOM_MIN, LDO_HDROOM_MAX, headroom_uV)) {
+ pr_err("bad headroom-voltage = %d specified\n",
+ headroom_uV);
+ return -EINVAL;
+ }
+
+ rc = of_property_read_u32(pdev->dev.of_node,
+ "qcom,retention-voltage",
+ &retention_uV);
+ if (rc < 0) {
+ pr_err("retention-voltage missing rc=%d\n", rc);
+ return rc;
+ }
+ if (!is_between(LDO_UV_MIN, LDO_UV_MAX, retention_uV)) {
+ pr_err("bad retention-voltage = %d specified\n",
+ retention_uV);
+ return -EINVAL;
+ }
+
+ rc = of_property_read_u32(pdev->dev.of_node,
+ "qcom,ldo-default-voltage",
+ &ldo_default_uV);
+ if (rc < 0) {
+ pr_err("ldo-default-voltage missing rc=%d\n", rc);
+ return rc;
+ }
+ if (!is_between(LDO_UV_MIN, LDO_UV_MAX, ldo_default_uV)) {
+ pr_err("bad ldo-default-voltage = %d specified\n",
+ ldo_default_uV);
+ return -EINVAL;
+ }
+
+ rc = of_property_read_u32(pdev->dev.of_node,
+ "qcom,ldo-threshold-voltage",
+ &ldo_threshold_uV);
+ if (rc < 0) {
+ pr_err("ldo-threshold-voltage missing rc=%d\n", rc);
+ return rc;
+ }
+ if (!is_between(LDO_TH_MIN, LDO_TH_MAX, ldo_threshold_uV)) {
+ pr_err("bad ldo-threshold-voltage = %d specified\n",
+ ldo_threshold_uV);
+ return -EINVAL;
+ }
}
if (!init_data) {
@@ -708,15 +790,19 @@
kvreg->reg_base = devm_ioremap(&pdev->dev,
res->start, resource_size(res));
- kvreg->pvreg = the_gang;
- kvreg->name = init_data->constraints.name;
- kvreg->desc.name = kvreg->name;
- kvreg->desc.ops = &krait_power_ops;
- kvreg->desc.type = REGULATOR_VOLTAGE;
- kvreg->desc.owner = THIS_MODULE;
- kvreg->uV = CORE_VOLTAGE_MIN;
- kvreg->mode = HS_MODE;
- kvreg->desc.ops = &krait_power_ops;
+ kvreg->pvreg = the_gang;
+ kvreg->name = init_data->constraints.name;
+ kvreg->desc.name = kvreg->name;
+ kvreg->desc.ops = &krait_power_ops;
+ kvreg->desc.type = REGULATOR_VOLTAGE;
+ kvreg->desc.owner = THIS_MODULE;
+ kvreg->uV = CORE_VOLTAGE_MIN;
+ kvreg->mode = HS_MODE;
+ kvreg->desc.ops = &krait_power_ops;
+ kvreg->headroom_uV = headroom_uV;
+ kvreg->retention_uV = retention_uV;
+ kvreg->ldo_default_uV = ldo_default_uV;
+ kvreg->ldo_threshold_uV = ldo_threshold_uV;
platform_set_drvdata(pdev, kvreg);
diff --git a/arch/arm/mach-msm/wdog_debug.c b/arch/arm/mach-msm/wdog_debug.c
index 08dd9ce..8b39d26 100644
--- a/arch/arm/mach-msm/wdog_debug.c
+++ b/arch/arm/mach-msm/wdog_debug.c
@@ -43,6 +43,11 @@
value = readl_relaxed(wdog_data->base + GCC_WDOG_DEBUG_OFFSET);
value &= ~BIT(WDOG_DEBUG_EN);
writel_relaxed(value, wdog_data->base + GCC_WDOG_DEBUG_OFFSET);
+
+ /* Ensure the WDOG_DEBUG_EN status has changed */
+ while (readl_relaxed(wdog_data->base + GCC_WDOG_DEBUG_OFFSET) &
+ BIT(WDOG_DEBUG_EN))
+ ;
}
EXPORT_SYMBOL(msm_disable_wdog_debug);
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index b5d38d5..8994d6d 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -571,7 +571,6 @@
pm_callback_t callback = NULL;
char *info = NULL;
int error = 0;
- bool put = false;
TRACE_DEVICE(dev);
TRACE_RESUME(0);
@@ -589,7 +588,6 @@
goto Unlock;
pm_runtime_enable(dev);
- put = true;
if (dev->pm_domain) {
info = "power domain ";
@@ -642,9 +640,6 @@
TRACE_RESUME(error);
- if (put)
- pm_runtime_put_sync(dev);
-
return error;
}
@@ -779,6 +774,8 @@
}
device_unlock(dev);
+
+ pm_runtime_put_sync(dev);
}
/**
@@ -1064,12 +1061,16 @@
if (async_error)
return 0;
- pm_runtime_get_noresume(dev);
+ /*
+ * If a device configured to wake up the system from sleep states
+ * has been suspended at run time and there's a resume request pending
+ * for it, this is equivalent to the device signaling wakeup, so the
+ * system suspend operation should be aborted.
+ */
if (pm_runtime_barrier(dev) && device_may_wakeup(dev))
pm_wakeup_event(dev, 0);
if (pm_wakeup_pending()) {
- pm_runtime_put_sync(dev);
async_error = -EBUSY;
return 0;
}
@@ -1142,12 +1143,10 @@
complete_all(&dev->power.completion);
- if (error) {
- pm_runtime_put_sync(dev);
+ if (error)
async_error = error;
- } else if (dev->power.is_suspended) {
+ else if (dev->power.is_suspended)
__pm_runtime_disable(dev, false);
- }
return error;
}
@@ -1240,6 +1239,14 @@
char *info = NULL;
int error = 0;
+ /*
+ * If a device's parent goes into runtime suspend at the wrong time,
+ * it won't be possible to resume the device. To prevent this we
+ * block runtime suspend here, during the prepare phase, and allow
+ * it again during the complete phase.
+ */
+ pm_runtime_get_noresume(dev);
+
device_lock(dev);
dev->power.wakeup_path = device_may_wakeup(dev);
diff --git a/drivers/coresight/coresight-etm.c b/drivers/coresight/coresight-etm.c
index e2a16ad..f3fe70f 100644
--- a/drivers/coresight/coresight-etm.c
+++ b/drivers/coresight/coresight-etm.c
@@ -363,6 +363,7 @@
*/
etm_set_pwrup(drvdata);
etm_clr_pwrdwn(drvdata);
+ etm_clr_pwrup(drvdata);
ETM_LOCK(drvdata);
}
@@ -373,10 +374,8 @@
ETM_UNLOCK(drvdata);
- if (!drvdata->enable) {
+ if (!drvdata->enable)
etm_set_pwrdwn(drvdata);
- etm_clr_pwrup(drvdata);
- }
ETM_LOCK(drvdata);
}
@@ -400,6 +399,7 @@
* for trace enable.
*/
etm_clr_pwrdwn(drvdata);
+ etm_clr_pwrup(drvdata);
etm_set_prog(drvdata);
etmcr = etm_readl(drvdata, ETMCR);
@@ -495,10 +495,8 @@
/* program trace enable to low by using always false event */
etm_writel(drvdata, 0x6F | BIT(14), ETMTEEVR);
- if (!drvdata->pcsave_enable) {
+ if (!drvdata->pcsave_enable)
etm_set_pwrdwn(drvdata);
- etm_clr_pwrup(drvdata);
- }
ETM_LOCK(drvdata);
dev_dbg(drvdata->dev, "cpu: %d disable smp call done\n", drvdata->cpu);
@@ -1688,6 +1686,7 @@
* certain registers might be ignored.
*/
etm_clr_pwrdwn(drvdata);
+ etm_clr_pwrup(drvdata);
/* Set prog bit. It will be set from reset but this is included to
* ensure it is set
*/
@@ -1705,7 +1704,6 @@
drvdata->nr_ctxid_cmp = BMVAL(etmccr, 24, 25);
etm_set_pwrdwn(drvdata);
- etm_clr_pwrup(drvdata);
ETM_LOCK(drvdata);
}
diff --git a/drivers/crypto/msm/qce40.c b/drivers/crypto/msm/qce40.c
index 7a229a5..de060cc 100644
--- a/drivers/crypto/msm/qce40.c
+++ b/drivers/crypto/msm/qce40.c
@@ -1844,6 +1844,8 @@
*cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
*cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
*cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
+ *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
+ *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
*cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_byte_count);
*cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_result_20);
*cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
@@ -1860,6 +1862,8 @@
*cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
*cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
*cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
+ *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
+ *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
*cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_byte_count);
*cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_result_32);
*cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
@@ -1877,6 +1881,8 @@
*cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
*cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
*cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
+ *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
+ *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
*cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_byte_count);
*cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_result_20);
*cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
@@ -1894,6 +1900,8 @@
*cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->ce_data_in);
*cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
*cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
+ *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
+ *cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_status_wait);
*cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_byte_count);
*cmd_ptr_vaddr++ = QCE_SET_CMD_PTR(cmdlist->get_auth_result_32);
*cmd_ptr_vaddr++ = QCE_SET_LAST_CMD_PTR(cmdlist->get_status_ocu);
diff --git a/drivers/crypto/msm/qce50.c b/drivers/crypto/msm/qce50.c
index 1312448..4361263 100644
--- a/drivers/crypto/msm/qce50.c
+++ b/drivers/crypto/msm/qce50.c
@@ -487,7 +487,10 @@
pce->data = auth_cfg;
pce = cmdlistinfo->auth_seg_size;
- pce->data = totallen_in;
+ if (creq->dir == QCE_ENCRYPT)
+ pce->data = totallen_in;
+ else
+ pce->data = totallen_in - creq->authsize;
pce = cmdlistinfo->auth_seg_start;
pce->data = 0;
}
@@ -503,7 +506,8 @@
encr_cfg |= (CRYPTO_ENCR_MODE_XTS << CRYPTO_ENCR_MODE);
break;
case QCE_MODE_CCM:
- encr_cfg |= (CRYPTO_ENCR_MODE_CCM << CRYPTO_ENCR_MODE);
+ encr_cfg |= (CRYPTO_ENCR_MODE_CCM << CRYPTO_ENCR_MODE) |
+ (CRYPTO_LAST_CCM_XFR << CRYPTO_LAST_CCM);
break;
case QCE_MODE_CTR:
default:
@@ -1930,7 +1934,9 @@
auth_cfg &= ~(1 << CRYPTO_USE_HW_KEY_AUTH);
encr_cfg = (CRYPTO_ENCR_KEY_SZ_AES256 << CRYPTO_ENCR_KEY_SZ) |
(CRYPTO_ENCR_ALG_AES << CRYPTO_ENCR_ALG) |
- ((CRYPTO_ENCR_MODE_CCM << CRYPTO_ENCR_MODE));
+ (CRYPTO_ENCR_MODE_CCM << CRYPTO_ENCR_MODE) |
+ (CRYPTO_LAST_CCM_XFR << CRYPTO_LAST_CCM);
+
key_reg = 8;
}
qce_add_cmd_element(pdev, &ce_vaddr, CRYPTO_CONFIG_REG,
@@ -2161,8 +2167,10 @@
struct qce_cmdlist_info *cmdlistinfo = NULL;
struct qce_cmdlist_info *auth_cmdlistinfo = NULL;
- if (q_req->mode != QCE_MODE_CCM)
+ if (q_req->mode != QCE_MODE_CCM) {
ivsize = crypto_aead_ivsize(aead);
+ auth_cmdlistinfo = &pce_dev->ce_sps.cmdlistptr.aead_sha1_hmac;
+ }
ce_burst_size = pce_dev->ce_sps.ce_burst_size;
if (q_req->dir == QCE_ENCRYPT) {
@@ -2770,13 +2778,11 @@
ce_support->aes_xts = true;
ce_support->ota = false;
ce_support->bam = true;
- if (pce_dev->ce_sps.minor_version) {
+ ce_support->aes_ccm = true;
+ if (pce_dev->ce_sps.minor_version)
ce_support->aligned_only = false;
- ce_support->aes_ccm = true;
- } else {
+ else
ce_support->aligned_only = true;
- ce_support->aes_ccm = false;
- }
return 0;
}
EXPORT_SYMBOL(qce_hw_support);
diff --git a/drivers/crypto/msm/qcrypto.c b/drivers/crypto/msm/qcrypto.c
index 7fc5cab..10f83f3 100644
--- a/drivers/crypto/msm/qcrypto.c
+++ b/drivers/crypto/msm/qcrypto.c
@@ -919,7 +919,7 @@
for (sg = areq->dst; bytes != nbytes; sg++) {
memcpy(sg_virt(sg),
- ((char *)rctx->data + rctx->assoclen + bytes),
+ ((char *)rctx->data + areq->assoclen + bytes),
sg->length);
bytes += sg->length;
}
diff --git a/drivers/gpu/msm/adreno_ringbuffer.c b/drivers/gpu/msm/adreno_ringbuffer.c
index e5a790f..0d5e409 100644
--- a/drivers/gpu/msm/adreno_ringbuffer.c
+++ b/drivers/gpu/msm/adreno_ringbuffer.c
@@ -28,6 +28,14 @@
#define GSL_RB_NOP_SIZEDWORDS 2
+/*
+ * CP DEBUG settings for all cores:
+ * DYNAMIC_CLK_DISABLE [27] - turn off the dynamic clock control
+ * PROG_END_PTR_ENABLE [25] - Allow 128 bit writes to the VBIF
+ */
+
+#define CP_DEBUG_DEFAULT ((1 << 27) | (1 << 25))
+
void adreno_ringbuffer_submit(struct adreno_ringbuffer *rb)
{
BUG_ON(rb->wptr == 0);
@@ -231,7 +239,7 @@
KGSL_DRV_INFO(device, "loading pm4 ucode version: %d\n",
adreno_dev->pm4_fw[0]);
- adreno_regwrite(device, REG_CP_DEBUG, 0x02000000);
+ adreno_regwrite(device, REG_CP_DEBUG, CP_DEBUG_DEFAULT);
adreno_regwrite(device, REG_CP_ME_RAM_WADDR, 0);
for (i = 1; i < adreno_dev->pm4_fw_size; i++)
adreno_regwrite(device, REG_CP_ME_RAM_DATA,
@@ -537,6 +545,9 @@
if (adreno_is_a3xx(adreno_dev))
total_sizedwords += 7;
+ if (adreno_is_a2xx(adreno_dev))
+ total_sizedwords += 2; /* CP_WAIT_FOR_IDLE */
+
total_sizedwords += 2; /* scratchpad ts for recovery */
if (context && context->flags & CTXT_FLAGS_PER_CONTEXT_TS &&
!(flags & KGSL_CMD_FLAGS_INTERNAL_ISSUE)) {
@@ -602,6 +613,16 @@
}
timestamp = rb->timestamp[context_id];
+ /* HW Workaround for MMU Page fault
+ * due to memory getting free early before
+ * GPU completes it.
+ */
+ if (adreno_is_a2xx(adreno_dev)) {
+ GSL_RB_WRITE(ringcmds, rcmd_gpu,
+ cp_type3_packet(CP_WAIT_FOR_IDLE, 1));
+ GSL_RB_WRITE(ringcmds, rcmd_gpu, 0x00);
+ }
+
/* scratchpad ts for recovery */
GSL_RB_WRITE(ringcmds, rcmd_gpu, cp_type0_packet(REG_CP_TIMESTAMP, 1));
GSL_RB_WRITE(ringcmds, rcmd_gpu, rb->timestamp[KGSL_MEMSTORE_GLOBAL]);
diff --git a/drivers/leds/leds-qpnp.c b/drivers/leds/leds-qpnp.c
index ba122bb..d658217 100644
--- a/drivers/leds/leds-qpnp.c
+++ b/drivers/leds/leds-qpnp.c
@@ -21,6 +21,7 @@
#include <linux/of_platform.h>
#include <linux/of_device.h>
#include <linux/spmi.h>
+#include <linux/qpnp/pwm.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)
@@ -127,6 +128,21 @@
#define LED_TRIGGER_DEFAULT "none"
+#define RGB_LED_SRC_SEL(base) (base + 0x45)
+#define RGB_LED_EN_CTL(base) (base + 0x46)
+#define RGB_LED_ATC_CTL(base) (base + 0x47)
+
+#define RGB_MAX_LEVEL LED_FULL
+#define RGB_LED_ENABLE_RED 0x80
+#define RGB_LED_ENABLE_GREEN 0x40
+#define RGB_LED_ENABLE_BLUE 0x20
+#define RGB_LED_SOURCE_VPH_PWR 0x01
+#define RGB_LED_ENABLE_MASK 0xE0
+#define RGB_LED_SRC_MASK 0x03
+#define QPNP_LED_PWM_FLAGS (PM_PWM_LUT_LOOP | PM_PWM_LUT_RAMP_UP)
+#define PWM_LUT_MAX_SIZE 63
+#define RGB_LED_DISABLE 0x00
+
/**
* enum qpnp_leds - QPNP supported led ids
* @QPNP_ID_WLED - White led backlight
@@ -135,6 +151,9 @@
QPNP_ID_WLED = 0,
QPNP_ID_FLASH1_LED0,
QPNP_ID_FLASH1_LED1,
+ QPNP_ID_RGB_RED,
+ QPNP_ID_RGB_GREEN,
+ QPNP_ID_RGB_BLUE,
QPNP_ID_MAX,
};
@@ -180,6 +199,11 @@
DELAY_128us,
};
+enum rgb_mode {
+ RGB_MODE_PWM = 0,
+ RGB_MODE_LPG,
+};
+
static u8 wled_debug_regs[] = {
/* common registers */
0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4d, 0x4e, 0x4f,
@@ -197,7 +221,9 @@
0x4f, 0x46, 0x47,
};
-
+static u8 rgb_pwm_debug_regs[] = {
+ 0x45, 0x46, 0x47,
+};
/**
* wled_config_data - wled configuration data
* @num_strings - number of wled strings supported
@@ -248,6 +274,24 @@
};
/**
+ * rgb_config_data - rgb configuration data
+ * @lut_params - lut parameters to be used by pwm driver
+ * @pwm_device - pwm device
+ * @pwm_channel - pwm channel to be configured for led
+ * @pwm_period_us - period for pwm, in us
+ * @mode - mode the led operates in
+ */
+struct rgb_config_data {
+ struct lut_params lut_params;
+ struct pwm_device *pwm_dev;
+ int pwm_channel;
+ u32 pwm_period_us;
+ struct pwm_duty_cycles *duty_cycles;
+ u8 mode;
+ u8 enable;
+};
+
+/**
* struct qpnp_led_data - internal led data structure
* @led_classdev - led class device
* @id - led index
@@ -268,6 +312,7 @@
spinlock_t lock;
struct wled_config_data *wled_cfg;
struct flash_config_data *flash_cfg;
+ struct rgb_config_data *rgb_cfg;
int max_current;
bool default_on;
};
@@ -458,6 +503,51 @@
}
}
+ qpnp_dump_regs(led, flash_debug_regs, ARRAY_SIZE(flash_debug_regs));
+
+ return 0;
+}
+
+static int qpnp_rgb_set(struct qpnp_led_data *led)
+{
+ int duty_us;
+ int rc;
+
+ if (led->cdev.brightness) {
+ if (led->rgb_cfg->mode == RGB_MODE_PWM) {
+ duty_us = (led->rgb_cfg->pwm_period_us *
+ led->cdev.brightness) / LED_FULL;
+ rc = pwm_config(led->rgb_cfg->pwm_dev, duty_us,
+ led->rgb_cfg->pwm_period_us);
+ if (rc < 0) {
+ dev_err(&led->spmi_dev->dev, "Failed to " \
+ "configure pwm for new values\n");
+ return rc;
+ }
+ }
+ rc = qpnp_led_masked_write(led,
+ RGB_LED_EN_CTL(led->base),
+ led->rgb_cfg->enable, led->rgb_cfg->enable);
+ if (rc) {
+ dev_err(&led->spmi_dev->dev,
+ "Failed to write led enable reg\n");
+ return rc;
+ }
+ rc = pwm_enable(led->rgb_cfg->pwm_dev);
+ } else {
+ pwm_disable(led->rgb_cfg->pwm_dev);
+ rc = qpnp_led_masked_write(led,
+ RGB_LED_EN_CTL(led->base),
+ led->rgb_cfg->enable, RGB_LED_DISABLE);
+ if (rc) {
+ dev_err(&led->spmi_dev->dev,
+ "Failed to write led enable reg\n");
+ return rc;
+ }
+ }
+
+ qpnp_dump_regs(led, rgb_pwm_debug_regs, ARRAY_SIZE(rgb_pwm_debug_regs));
+
return 0;
}
@@ -490,6 +580,14 @@
dev_err(&led->spmi_dev->dev,
"FLASH set brightness failed (%d)\n", rc);
break;
+ case QPNP_ID_RGB_RED:
+ case QPNP_ID_RGB_GREEN:
+ case QPNP_ID_RGB_BLUE:
+ rc = qpnp_rgb_set(led);
+ if (rc < 0)
+ dev_err(&led->spmi_dev->dev,
+ "RGB set brightness failed (%d)\n", rc);
+ break;
default:
dev_err(&led->spmi_dev->dev, "Invalid LED(%d)\n", led->id);
break;
@@ -507,6 +605,11 @@
case QPNP_ID_FLASH1_LED1:
led->cdev.max_brightness = led->max_current;
break;
+ case QPNP_ID_RGB_RED:
+ case QPNP_ID_RGB_GREEN:
+ case QPNP_ID_RGB_BLUE:
+ led->cdev.max_brightness = RGB_MAX_LEVEL;
+ break;
default:
dev_err(&led->spmi_dev->dev, "Invalid LED(%d)\n", led->id);
return -EINVAL;
@@ -769,6 +872,74 @@
return 0;
}
+static int __devinit qpnp_rgb_init(struct qpnp_led_data *led)
+{
+ int rc, start_idx, idx_len;
+
+ rc = qpnp_led_masked_write(led, RGB_LED_SRC_SEL(led->base),
+ RGB_LED_SRC_MASK, RGB_LED_SOURCE_VPH_PWR);
+ if (rc) {
+ dev_err(&led->spmi_dev->dev,
+ "Failed to write led source select register\n");
+ return rc;
+ }
+
+ if (led->rgb_cfg->pwm_channel != -1) {
+ led->rgb_cfg->pwm_dev =
+ pwm_request(led->rgb_cfg->pwm_channel,
+ led->cdev.name);
+
+ if (IS_ERR_OR_NULL(led->rgb_cfg->pwm_dev)) {
+ dev_err(&led->spmi_dev->dev,
+ "could not acquire PWM Channel %d, " \
+ "error %ld\n",
+ led->rgb_cfg->pwm_channel,
+ PTR_ERR(led->rgb_cfg->pwm_dev));
+ led->rgb_cfg->pwm_dev = NULL;
+ return -ENODEV;
+ }
+
+ if (led->rgb_cfg->mode == RGB_MODE_LPG) {
+ start_idx =
+ led->rgb_cfg->duty_cycles->start_idx;
+ idx_len =
+ led->rgb_cfg->duty_cycles->num_duty_pcts;
+
+ if (idx_len >= PWM_LUT_MAX_SIZE &&
+ start_idx) {
+ dev_err(&led->spmi_dev->dev,
+ "Wrong LUT size or index\n");
+ return -EINVAL;
+ }
+ if ((start_idx + idx_len) >
+ PWM_LUT_MAX_SIZE) {
+ dev_err(&led->spmi_dev->dev,
+ "Exceed LUT limit\n");
+ return -EINVAL;
+ }
+ rc = pwm_lut_config(led->rgb_cfg->pwm_dev,
+ led->rgb_cfg->pwm_period_us,
+ led->rgb_cfg->duty_cycles->duty_pcts,
+ led->rgb_cfg->lut_params);
+ if (rc < 0) {
+ dev_err(&led->spmi_dev->dev, "Failed to " \
+ "configure pwm LUT\n");
+ return rc;
+ }
+ }
+ } else {
+ dev_err(&led->spmi_dev->dev,
+ "Invalid PWM channel\n");
+ return -EINVAL;
+ }
+
+ /* Initialize led for use in auto trickle charging mode */
+ rc = qpnp_led_masked_write(led, RGB_LED_ATC_CTL(led->base),
+ led->rgb_cfg->enable, led->rgb_cfg->enable);
+
+ return 0;
+}
+
static int __devinit qpnp_led_initialize(struct qpnp_led_data *led)
{
int rc;
@@ -787,12 +958,20 @@
dev_err(&led->spmi_dev->dev,
"FLASH initialize failed(%d)\n", rc);
break;
+ case QPNP_ID_RGB_RED:
+ case QPNP_ID_RGB_GREEN:
+ case QPNP_ID_RGB_BLUE:
+ rc = qpnp_rgb_init(led);
+ if (rc)
+ dev_err(&led->spmi_dev->dev,
+ "RGB initialize failed(%d)\n", rc);
+ break;
default:
dev_err(&led->spmi_dev->dev, "Invalid LED(%d)\n", led->id);
- rc = -EINVAL;
+ return -EINVAL;
}
- return rc;
+ return 0;
}
static int __devinit qpnp_get_common_configs(struct qpnp_led_data *led,
@@ -965,6 +1144,120 @@
return 0;
}
+static int __devinit qpnp_get_config_rgb(struct qpnp_led_data *led,
+ struct device_node *node)
+{
+ struct property *prop;
+ int rc, i;
+ u32 val;
+ u8 *temp_cfg;
+
+ led->rgb_cfg = devm_kzalloc(&led->spmi_dev->dev,
+ sizeof(struct rgb_config_data), GFP_KERNEL);
+ if (!led->rgb_cfg) {
+ dev_err(&led->spmi_dev->dev, "Unable to allocate memory\n");
+ return -ENOMEM;
+ }
+
+ if (led->id == QPNP_ID_RGB_RED)
+ led->rgb_cfg->enable = RGB_LED_ENABLE_RED;
+ else if (led->id == QPNP_ID_RGB_GREEN)
+ led->rgb_cfg->enable = RGB_LED_ENABLE_GREEN;
+ else if (led->id == QPNP_ID_RGB_BLUE)
+ led->rgb_cfg->enable = RGB_LED_ENABLE_BLUE;
+ else
+ return -EINVAL;
+
+ rc = of_property_read_u32(node, "qcom,mode", &val);
+ if (!rc)
+ led->rgb_cfg->mode = (u8) val;
+ else
+ return rc;
+
+ rc = of_property_read_u32(node, "qcom,pwm-channel", &val);
+ if (!rc)
+ led->rgb_cfg->pwm_channel = (u8) val;
+ else
+ return rc;
+
+ rc = of_property_read_u32(node, "qcom,pwm-us", &val);
+ if (!rc)
+ led->rgb_cfg->pwm_period_us = val;
+ else
+ return rc;
+
+ if (led->rgb_cfg->mode == RGB_MODE_LPG) {
+ led->rgb_cfg->duty_cycles =
+ devm_kzalloc(&led->spmi_dev->dev,
+ sizeof(struct pwm_duty_cycles), GFP_KERNEL);
+ if (!led->rgb_cfg->duty_cycles) {
+ dev_err(&led->spmi_dev->dev,
+ "Unable to allocate memory\n");
+ return -ENOMEM;
+ }
+
+ rc = of_property_read_u32(node, "qcom,duty-ms", &val);
+ if (!rc)
+ led->rgb_cfg->duty_cycles->duty_ms = (u8) val;
+ else
+ return rc;
+
+ prop = of_find_property(node, "qcom,duty-pcts",
+ &led->rgb_cfg->duty_cycles->num_duty_pcts);
+ if (!prop) {
+ dev_err(&led->spmi_dev->dev, "Looking up property " \
+ "node qcom,duty-pcts failed\n");
+ return -ENODEV;
+ } else if (!led->rgb_cfg->duty_cycles->num_duty_pcts) {
+ dev_err(&led->spmi_dev->dev, "Invalid length of " \
+ "duty pcts\n");
+ return -EINVAL;
+ }
+
+ led->rgb_cfg->duty_cycles->duty_pcts =
+ devm_kzalloc(&led->spmi_dev->dev,
+ sizeof(int) * led->rgb_cfg->duty_cycles->num_duty_pcts,
+ GFP_KERNEL);
+ if (!led->rgb_cfg->duty_cycles->duty_pcts) {
+ dev_err(&led->spmi_dev->dev,
+ "Unable to allocate memory\n");
+ return -ENOMEM;
+ }
+
+ temp_cfg = devm_kzalloc(&led->spmi_dev->dev,
+ led->rgb_cfg->duty_cycles->num_duty_pcts *
+ sizeof(u8), GFP_KERNEL);
+ if (!temp_cfg) {
+ dev_err(&led->spmi_dev->dev, "Failed to allocate " \
+ "memory for duty pcts\n");
+ return -ENOMEM;
+ }
+
+ memcpy(temp_cfg, prop->value,
+ led->rgb_cfg->duty_cycles->num_duty_pcts);
+
+ for (i = 0; i < led->rgb_cfg->duty_cycles->num_duty_pcts; i++)
+ led->rgb_cfg->duty_cycles->duty_pcts[i] =
+ (int) temp_cfg[i];
+
+ rc = of_property_read_u32(node, "qcom,start-idx", &val);
+ if (!rc) {
+ led->rgb_cfg->lut_params.start_idx = (u8) val;
+ led->rgb_cfg->duty_cycles->start_idx = (u8) val;
+ } else
+ return rc;
+
+ led->rgb_cfg->lut_params.idx_len =
+ led->rgb_cfg->duty_cycles->num_duty_pcts;
+ led->rgb_cfg->lut_params.lut_pause_hi = 0;
+ led->rgb_cfg->lut_params.lut_pause_lo = 0;
+ led->rgb_cfg->lut_params.ramp_step_ms = 255;
+ led->rgb_cfg->lut_params.flags = QPNP_LED_PWM_FLAGS;
+ }
+
+ return 0;
+}
+
static int __devinit qpnp_leds_probe(struct spmi_device *spmi)
{
struct qpnp_led_data *led;
@@ -1060,6 +1353,13 @@
"Unable to read flash config data\n");
return rc;
}
+ } else if (strncmp(led_label, "rgb", sizeof("rgb")) == 0) {
+ rc = qpnp_get_config_rgb(led, temp);
+ if (rc < 0) {
+ dev_err(&led->spmi_dev->dev,
+ "Unable to read rgb config data\n");
+ return rc;
+ }
} else {
dev_err(&led->spmi_dev->dev, "No LED matching label\n");
return -EINVAL;
diff --git a/drivers/media/video/msm_wfd/enc-mfc-subdev.c b/drivers/media/video/msm_wfd/enc-mfc-subdev.c
index 6db2ad1..d839be3 100644
--- a/drivers/media/video/msm_wfd/enc-mfc-subdev.c
+++ b/drivers/media/video/msm_wfd/enc-mfc-subdev.c
@@ -194,6 +194,9 @@
break;
}
+ if (frame_data->flags & VCD_FRAME_FLAG_CODECCONFIG)
+ vbuf->v4l2_buf.flags |= V4L2_QCOM_BUF_FLAG_CODECCONFIG;
+
vbuf->v4l2_buf.timestamp =
ns_to_timeval(frame_data->time_stamp * NSEC_PER_USEC);
diff --git a/drivers/media/video/vcap_v4l2.c b/drivers/media/video/vcap_v4l2.c
index 2b73b11..9afc3df 100644
--- a/drivers/media/video/vcap_v4l2.c
+++ b/drivers/media/video/vcap_v4l2.c
@@ -569,6 +569,17 @@
}
/* VC Videobuf operations */
+static void wait_prepare(struct vb2_queue *q)
+{
+ struct vcap_client_data *c_data = vb2_get_drv_priv(q);
+ mutex_unlock(&c_data->mutex);
+}
+
+static void wait_finish(struct vb2_queue *q)
+{
+ struct vcap_client_data *c_data = vb2_get_drv_priv(q);
+ mutex_lock(&c_data->mutex);
+}
static int capture_queue_setup(struct vb2_queue *vq,
const struct v4l2_format *fmt,
@@ -651,6 +662,8 @@
static struct vb2_ops capture_video_qops = {
.queue_setup = capture_queue_setup,
+ .wait_finish = wait_finish,
+ .wait_prepare = wait_prepare,
.buf_init = capture_buffer_init,
.buf_prepare = capture_buffer_prepare,
.buf_queue = capture_buffer_queue,
@@ -749,6 +762,8 @@
static struct vb2_ops vp_in_video_qops = {
.queue_setup = vp_in_queue_setup,
+ .wait_finish = wait_finish,
+ .wait_prepare = wait_prepare,
.buf_init = vp_in_buffer_init,
.buf_prepare = vp_in_buffer_prepare,
.buf_queue = vp_in_buffer_queue,
@@ -847,6 +862,8 @@
static struct vb2_ops vp_out_video_qops = {
.queue_setup = vp_out_queue_setup,
+ .wait_finish = wait_finish,
+ .wait_prepare = wait_prepare,
.buf_init = vp_out_buffer_init,
.buf_prepare = vp_out_buffer_prepare,
.buf_queue = vp_out_buffer_queue,
@@ -1072,7 +1089,9 @@
rc = get_phys_addr(c_data->dev, &c_data->vc_vidq, p);
if (rc < 0)
return rc;
+ mutex_lock(&c_data->mutex);
rc = vb2_qbuf(&c_data->vc_vidq, p);
+ mutex_unlock(&c_data->mutex);
if (rc < 0)
free_ion_handle(c_data, &c_data->vc_vidq, p);
return rc;
@@ -1082,7 +1101,9 @@
rc = get_phys_addr(c_data->dev, &c_data->vp_in_vidq, p);
if (rc < 0)
return rc;
+ mutex_lock(&c_data->mutex);
rc = vb2_qbuf(&c_data->vp_in_vidq, p);
+ mutex_unlock(&c_data->mutex);
if (rc < 0)
free_ion_handle(c_data, &c_data->vp_in_vidq, p);
return rc;
@@ -1090,7 +1111,9 @@
rc = get_phys_addr(c_data->dev, &c_data->vp_out_vidq, p);
if (rc < 0)
return rc;
+ mutex_lock(&c_data->mutex);
rc = vb2_qbuf(&c_data->vp_out_vidq, p);
+ mutex_unlock(&c_data->mutex);
if (rc < 0)
free_ion_handle(c_data, &c_data->vp_out_vidq, p);
return rc;
@@ -1114,21 +1137,27 @@
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
if (c_data->op_mode == VC_AND_VP_VCAP_OP)
return -EINVAL;
+ mutex_lock(&c_data->mutex);
rc = vb2_dqbuf(&c_data->vc_vidq, p, file->f_flags & O_NONBLOCK);
+ mutex_unlock(&c_data->mutex);
if (rc < 0)
return rc;
return free_ion_handle(c_data, &c_data->vc_vidq, p);
case V4L2_BUF_TYPE_INTERLACED_IN_DECODER:
if (c_data->op_mode == VC_AND_VP_VCAP_OP)
return -EINVAL;
+ mutex_lock(&c_data->mutex);
rc = vb2_dqbuf(&c_data->vp_in_vidq, p, file->f_flags &
O_NONBLOCK);
+ mutex_unlock(&c_data->mutex);
if (rc < 0)
return rc;
return free_ion_handle(c_data, &c_data->vp_in_vidq, p);
case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+ mutex_lock(&c_data->mutex);
rc = vb2_dqbuf(&c_data->vp_out_vidq, p, file->f_flags &
O_NONBLOCK);
+ mutex_unlock(&c_data->mutex);
if (rc < 0)
return rc;
return free_ion_handle(c_data, &c_data->vp_out_vidq, p);
@@ -1488,8 +1517,10 @@
dev->vc_resource = 0;
mutex_unlock(&dev->dev_mutex);
c_data->streaming = 0;
+ mutex_lock(&c_data->mutex);
rc = vb2_streamoff(&c_data->vc_vidq,
V4L2_BUF_TYPE_VIDEO_CAPTURE);
+ mutex_unlock(&c_data->mutex);
if (rc >= 0)
atomic_set(&c_data->dev->vc_enabled, 0);
return rc;
@@ -1515,14 +1546,18 @@
return rc;
c_data->streaming = 0;
+ mutex_unlock(&dev->dev_mutex);
/* These stream on calls should not fail */
rc = vb2_streamoff(&c_data->vp_in_vidq,
V4L2_BUF_TYPE_INTERLACED_IN_DECODER);
- if (rc < 0)
+ if (rc < 0) {
+ mutex_unlock(&c_data->mutex);
return rc;
+ }
rc = vb2_streamoff(&c_data->vp_out_vidq,
V4L2_BUF_TYPE_VIDEO_OUTPUT);
+ mutex_unlock(&c_data->mutex);
if (rc < 0)
return rc;
@@ -1557,20 +1592,26 @@
if (rc < 0)
return rc;
- /* These stream on calls should not fail */
c_data->streaming = 0;
+ mutex_lock(&c_data->mutex);
+ /* These stream on calls should not fail */
rc = vb2_streamoff(&c_data->vc_vidq,
V4L2_BUF_TYPE_VIDEO_CAPTURE);
- if (rc < 0)
+ if (rc < 0) {
+ mutex_unlock(&c_data->mutex);
return rc;
+ }
rc = vb2_streamoff(&c_data->vp_in_vidq,
V4L2_BUF_TYPE_INTERLACED_IN_DECODER);
- if (rc < 0)
+ if (rc < 0) {
+ mutex_unlock(&c_data->mutex);
return rc;
+ }
rc = vb2_streamoff(&c_data->vp_out_vidq,
V4L2_BUF_TYPE_VIDEO_OUTPUT);
+ mutex_unlock(&c_data->mutex);
if (rc < 0)
return rc;
@@ -1716,6 +1757,7 @@
c_data->dev = dev;
spin_lock_init(&c_data->cap_slock);
+ mutex_init(&c_data->mutex);
/* initialize vc queue */
q = &c_data->vc_vidq;
@@ -1799,6 +1841,7 @@
vp_in_q_failed:
vb2_queue_release(&c_data->vc_vidq);
vc_q_failed:
+ mutex_destroy(&c_data->mutex);
kfree(c_data);
return ret;
}
@@ -1833,6 +1876,7 @@
c_data->dev->vc_client = NULL;
if (c_data->dev->vp_client == c_data)
c_data->dev->vp_client = NULL;
+ mutex_destroy(&c_data->mutex);
kfree(c_data);
return 0;
}
diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c
index e71c95d..27123bc 100644
--- a/drivers/misc/qseecom.c
+++ b/drivers/misc/qseecom.c
@@ -51,6 +51,9 @@
#define QSEOS_CHECK_VERSION_CMD 0x00001803
+#define QSEE_CE_CLK_100MHZ 100000000
+#define QSEE_CE_CLK_50MHZ 50000000
+
enum qseecom_command_scm_resp_type {
QSEOS_APP_ID = 0xEE01,
QSEOS_LISTENER_ID
@@ -247,8 +250,6 @@
/* Function proto types */
static int qsee_vote_for_clock(int32_t);
static void qsee_disable_clock_vote(int32_t);
-static int __qseecom_init_clk(void);
-static void __qseecom_disable_clk(void);
static int __qseecom_is_svc_unique(struct qseecom_dev_handle *data,
struct qseecom_register_listener_req *svc)
@@ -1718,9 +1719,13 @@
if (qsee_sfpb_bw_count > 0)
ret = msm_bus_scale_client_update_request(
qsee_perf_client, 3);
- else
+ else {
+ if (ce_core_src_clk != NULL)
+ clk_set_rate(ce_core_src_clk,
+ QSEE_CE_CLK_100MHZ);
ret = msm_bus_scale_client_update_request(
qsee_perf_client, 1);
+ }
if (ret)
pr_err("DFAB Bandwidth req failed (%d)\n",
ret);
@@ -1737,9 +1742,13 @@
if (qsee_bw_count > 0)
ret = msm_bus_scale_client_update_request(
qsee_perf_client, 3);
- else
+ else {
+ if (ce_core_src_clk != NULL)
+ clk_set_rate(ce_core_src_clk,
+ QSEE_CE_CLK_100MHZ);
ret = msm_bus_scale_client_update_request(
qsee_perf_client, 2);
+ }
if (ret)
pr_err("SFPB Bandwidth req failed (%d)\n",
@@ -1778,9 +1787,13 @@
if (qsee_sfpb_bw_count > 0)
ret = msm_bus_scale_client_update_request(
qsee_perf_client, 2);
- else
+ else {
ret = msm_bus_scale_client_update_request(
qsee_perf_client, 0);
+ if (ce_core_src_clk != NULL)
+ clk_set_rate(ce_core_src_clk,
+ QSEE_CE_CLK_50MHZ);
+ }
if (ret)
pr_err("SFPB Bandwidth req fail (%d)\n",
ret);
@@ -1798,9 +1811,13 @@
if (qsee_bw_count > 0)
ret = msm_bus_scale_client_update_request(
qsee_perf_client, 1);
- else
+ else {
ret = msm_bus_scale_client_update_request(
qsee_perf_client, 0);
+ if (ce_core_src_clk != NULL)
+ clk_set_rate(ce_core_src_clk,
+ QSEE_CE_CLK_50MHZ);
+ }
if (ret)
pr_err("SFPB Bandwidth req fail (%d)\n",
ret);
@@ -2261,7 +2278,47 @@
.release = qseecom_release
};
-static int __qseecom_init_clk()
+static int __qseecom_enable_clk(void)
+{
+ int rc = 0;
+
+ /* Enable CE core clk */
+ rc = clk_prepare_enable(ce_core_clk);
+ if (rc) {
+ pr_err("Unable to enable/prepare CE core clk\n");
+ return -EIO;
+ } else {
+ /* Enable CE clk */
+ rc = clk_prepare_enable(ce_clk);
+ if (rc) {
+ pr_err("Unable to enable/prepare CE iface clk\n");
+ clk_disable_unprepare(ce_core_clk);
+ return -EIO;
+ } else {
+ /* Enable AXI clk */
+ rc = clk_prepare_enable(ce_bus_clk);
+ if (rc) {
+ pr_err("Unable to enable/prepare CE iface clk\n");
+ clk_disable_unprepare(ce_core_clk);
+ clk_disable_unprepare(ce_clk);
+ return -EIO;
+ }
+ }
+ }
+ return rc;
+}
+
+static void __qseecom_disable_clk(void)
+{
+ if (ce_clk != NULL)
+ clk_disable_unprepare(ce_clk);
+ if (ce_core_clk != NULL)
+ clk_disable_unprepare(ce_core_clk);
+ if (ce_bus_clk != NULL)
+ clk_disable_unprepare(ce_bus_clk);
+}
+
+static int __qseecom_init_clk(void)
{
int rc = 0;
struct device *pdev;
@@ -2270,14 +2327,12 @@
/* Get CE3 src core clk. */
ce_core_src_clk = clk_get(pdev, "core_clk_src");
if (!IS_ERR(ce_core_src_clk)) {
- ce_core_src_clk = ce_core_src_clk;
-
- /* Set the core src clk @100Mhz */
- rc = clk_set_rate(ce_core_src_clk, 100000000);
+ /* Set the core src clk @50Mhz */
+ rc = clk_set_rate(ce_core_src_clk, QSEE_CE_CLK_50MHZ);
if (rc) {
clk_put(ce_core_src_clk);
pr_err("Unable to set the core src clk @100Mhz.\n");
- goto err_clk;
+ return -EIO;
}
} else {
pr_warn("Unable to get CE core src clk, set to NULL\n");
@@ -2291,7 +2346,7 @@
pr_err("Unable to get CE core clk\n");
if (ce_core_src_clk != NULL)
clk_put(ce_core_src_clk);
- goto err_clk;
+ return -EIO;
}
/* Get CE Interface clk */
@@ -2302,7 +2357,7 @@
if (ce_core_src_clk != NULL)
clk_put(ce_core_src_clk);
clk_put(ce_core_clk);
- goto err_clk;
+ return -EIO;
}
/* Get CE AXI clk */
@@ -2314,78 +2369,35 @@
clk_put(ce_core_src_clk);
clk_put(ce_core_clk);
clk_put(ce_clk);
- goto err_clk;
+ return -EIO;
}
-
- /* Enable CE core clk */
- rc = clk_prepare_enable(ce_core_clk);
- if (rc) {
- pr_err("Unable to enable/prepare CE core clk\n");
- if (ce_core_src_clk != NULL)
- clk_put(ce_core_src_clk);
- clk_put(ce_core_clk);
- clk_put(ce_clk);
- goto err_clk;
- } else {
- /* Enable CE clk */
- rc = clk_prepare_enable(ce_clk);
- if (rc) {
- pr_err("Unable to enable/prepare CE iface clk\n");
- clk_disable_unprepare(ce_core_clk);
- if (ce_core_src_clk != NULL)
- clk_put(ce_core_src_clk);
- clk_put(ce_core_clk);
- clk_put(ce_clk);
- goto err_clk;
- } else {
- /* Enable AXI clk */
- rc = clk_prepare_enable(ce_bus_clk);
- if (rc) {
- pr_err("Unable to enable/prepare CE iface clk\n");
- clk_disable_unprepare(ce_core_clk);
- clk_disable_unprepare(ce_clk);
- if (ce_core_src_clk != NULL)
- clk_put(ce_core_src_clk);
- clk_put(ce_core_clk);
- clk_put(ce_clk);
- goto err_clk;
- }
- }
- }
- return rc;
-
-err_clk:
- if (rc)
- pr_err("Unable to init CE clks, rc = %d\n", rc);
- clk_disable_unprepare(ce_clk);
- clk_disable_unprepare(ce_core_clk);
- clk_disable_unprepare(ce_bus_clk);
- if (ce_core_src_clk != NULL)
- clk_put(ce_core_src_clk);
- clk_put(ce_clk);
- clk_put(ce_core_clk);
- clk_put(ce_bus_clk);
return rc;
}
-
-
-static void __qseecom_disable_clk()
+static void __qseecom_deinit_clk(void)
{
- clk_disable_unprepare(ce_clk);
- clk_disable_unprepare(ce_core_clk);
- clk_disable_unprepare(ce_bus_clk);
- if (ce_core_src_clk != NULL)
+ if (ce_clk != NULL) {
+ clk_put(ce_clk);
+ ce_clk = NULL;
+ }
+ if (ce_core_clk != NULL) {
+ clk_put(ce_core_clk);
+ ce_clk = NULL;
+ }
+ if (ce_bus_clk != NULL) {
+ clk_put(ce_bus_clk);
+ ce_clk = NULL;
+ }
+ if (ce_core_src_clk != NULL) {
clk_put(ce_core_src_clk);
- clk_put(ce_clk);
- clk_put(ce_core_clk);
- clk_put(ce_bus_clk);
+ ce_core_src_clk = NULL;
+ }
}
static int __devinit qseecom_probe(struct platform_device *pdev)
{
int rc;
- int ret;
+ int ret = 0;
struct device *class_dev;
char qsee_not_legacy = 0;
struct msm_bus_scale_pdata *qseecom_platform_support = NULL;
@@ -2393,6 +2405,12 @@
qsee_bw_count = 0;
qsee_perf_client = 0;
+ qsee_sfpb_bw_count = 0;
+
+ ce_core_clk = NULL;
+ ce_clk = NULL;
+ ce_core_src_clk = NULL;
+ ce_bus_clk = NULL;
rc = alloc_chrdev_region(&qseecom_device_no, 0, 1, QSEECOM_DEV);
if (rc < 0) {
@@ -2471,6 +2489,11 @@
ret = __qseecom_init_clk();
if (ret)
goto err;
+ ret = __qseecom_enable_clk();
+ if (ret) {
+ __qseecom_deinit_clk();
+ goto err;
+ }
qseecom_platform_support = (struct msm_bus_scale_pdata *)
msm_bus_cl_get_pdata(pdev);
} else {
@@ -2550,6 +2573,14 @@
}
if (qseecom.qseos_version > QSEEE_VERSION_00)
qseecom_unload_commonlib_image();
+
+ if (qsee_perf_client)
+ msm_bus_scale_client_update_request(qsee_perf_client, 0);
+ /* register client for bus scaling */
+ if (pdev->dev.of_node) {
+ __qseecom_disable_clk();
+ __qseecom_deinit_clk();
+ }
return ret;
};
@@ -2577,9 +2608,6 @@
static void __devexit qseecom_exit(void)
{
-
- __qseecom_disable_clk();
-
device_destroy(driver_class, qseecom_device_no);
class_destroy(driver_class);
unregister_chrdev_region(qseecom_device_no, 1);
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 47fd9b9..5183f2a 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -479,11 +479,11 @@
else
card->ext_csd.bkops_en = 1;
}
- if (!card->ext_csd.bkops_en)
- pr_info("%s: BKOPS_EN bit is not set\n",
- mmc_hostname(card->host));
}
+ pr_info("%s: BKOPS_EN bit = %d\n",
+ mmc_hostname(card->host), card->ext_csd.bkops_en);
+
/* check whether the eMMC card supports HPI */
if (ext_csd[EXT_CSD_HPI_FEATURES] & 0x1) {
card->ext_csd.hpi = 1;
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c
index 6cb492d..a752357 100644
--- a/drivers/mmc/host/msm_sdcc.c
+++ b/drivers/mmc/host/msm_sdcc.c
@@ -5656,6 +5656,8 @@
pdata->nonremovable = true;
if (of_get_property(np, "qcom,sdcc-disable_cmd23", NULL))
pdata->disable_cmd23 = true;
+ of_property_read_u32(np, "qcom,dat1-mpm-int",
+ &pdata->mpm_sdiowakeup_int);
return pdata;
err:
@@ -5985,6 +5987,14 @@
disable_irq(core_irqres->start);
host->sdcc_irq_disabled = 1;
+ if (!plat->sdiowakeup_irq) {
+ /* Check if registered as IORESOURCE_IRQ */
+ plat->sdiowakeup_irq =
+ platform_get_irq_byname(pdev, "sdiowakeup_irq");
+ if (plat->sdiowakeup_irq < 0)
+ plat->sdiowakeup_irq = 0;
+ }
+
if (plat->sdiowakeup_irq) {
wake_lock_init(&host->sdio_wlock, WAKE_LOCK_SUSPEND,
mmc_hostname(mmc));
diff --git a/drivers/net/usb/rmnet_usb_ctrl.c b/drivers/net/usb/rmnet_usb_ctrl.c
index 7ed8ffa..f87b3b9 100644
--- a/drivers/net/usb/rmnet_usb_ctrl.c
+++ b/drivers/net/usb/rmnet_usb_ctrl.c
@@ -339,8 +339,10 @@
int rmnet_usb_ctrl_suspend(struct rmnet_ctrl_dev *dev)
{
- if (!flush_work_sync(&dev->get_encap_work))
- usb_kill_anchored_urbs(&dev->rx_submitted);
+ if (work_busy(&dev->get_encap_work))
+ return -EBUSY;
+
+ usb_kill_anchored_urbs(&dev->rx_submitted);
return 0;
}
diff --git a/drivers/net/wireless/wcnss/wcnss_wlan.c b/drivers/net/wireless/wcnss/wcnss_wlan.c
index b9459dd..3167b3a 100644
--- a/drivers/net/wireless/wcnss/wcnss_wlan.c
+++ b/drivers/net/wireless/wcnss/wcnss_wlan.c
@@ -25,6 +25,7 @@
#include <linux/delay.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
+#include <linux/clk.h>
#include <mach/msm_smd.h>
#include <mach/msm_iomap.h>
@@ -45,6 +46,14 @@
module_param(has_48mhz_xo, int, S_IWUSR | S_IRUGO);
MODULE_PARM_DESC(has_48mhz_xo, "Is an external 48 MHz XO present");
+static DEFINE_SPINLOCK(reg_spinlock);
+
+#define MSM_RIVA_PHYS 0x03204000
+#define MSM_PRONTO_PHYS 0xfb21b000
+
+#define RIVA_SPARE_OFFSET 0x0b4
+#define RIVA_SUSPEND_BIT BIT(24)
+
#define WCNSS_CTRL_CHANNEL "WCNSS_CTRL"
#define WCNSS_MAX_FRAME_SIZE 500
#define WCNSS_VERSION_LEN 30
@@ -91,6 +100,7 @@
struct work_struct wcnssctrl_version_work;
struct work_struct wcnssctrl_rx_work;
struct wake_lock wcnss_wake_lock;
+ void __iomem *msm_wcnss_base;
} *penv = NULL;
static ssize_t wcnss_serial_number_show(struct device *dev,
@@ -489,6 +499,87 @@
}
EXPORT_SYMBOL(wcnss_get_serial_number);
+static int enable_wcnss_suspend_notify;
+
+static int enable_wcnss_suspend_notify_set(const char *val,
+ struct kernel_param *kp)
+{
+ int ret;
+
+ ret = param_set_int(val, kp);
+ if (ret)
+ return ret;
+
+ if (enable_wcnss_suspend_notify)
+ pr_debug("Suspend notification activated for wcnss\n");
+
+ return 0;
+}
+module_param_call(enable_wcnss_suspend_notify, enable_wcnss_suspend_notify_set,
+ param_get_int, &enable_wcnss_suspend_notify, S_IRUGO | S_IWUSR);
+
+
+void wcnss_suspend_notify(void)
+{
+ void __iomem *pmu_spare_reg;
+ u32 reg = 0;
+ unsigned long flags;
+ struct clk *cxo = clk_get(&penv->pdev->dev, "cxo");
+ int rc = 0;
+
+ if (!enable_wcnss_suspend_notify)
+ return;
+
+ if (wcnss_hardware_type() == WCNSS_PRONTO_HW)
+ return;
+
+ /* For Riva */
+ rc = clk_prepare_enable(cxo);
+ if (rc) {
+ pr_err("cxo enable failed\n");
+ return;
+ }
+ pmu_spare_reg = penv->msm_wcnss_base + RIVA_SPARE_OFFSET;
+ spin_lock_irqsave(®_spinlock, flags);
+ reg = readl_relaxed(pmu_spare_reg);
+ reg |= RIVA_SUSPEND_BIT;
+ writel_relaxed(reg, pmu_spare_reg);
+ spin_unlock_irqrestore(®_spinlock, flags);
+ clk_disable_unprepare(cxo);
+}
+EXPORT_SYMBOL(wcnss_suspend_notify);
+
+void wcnss_resume_notify(void)
+{
+ void __iomem *pmu_spare_reg;
+ u32 reg = 0;
+ unsigned long flags;
+ struct clk *cxo = clk_get(&penv->pdev->dev, "cxo");
+ int rc = 0;
+
+ if (!enable_wcnss_suspend_notify)
+ return;
+
+ if (wcnss_hardware_type() == WCNSS_PRONTO_HW)
+ return;
+
+ /* For Riva */
+ pmu_spare_reg = penv->msm_wcnss_base + RIVA_SPARE_OFFSET;
+
+ rc = clk_prepare_enable(cxo);
+ if (rc) {
+ pr_err("cxo enable failed\n");
+ return;
+ }
+ spin_lock_irqsave(®_spinlock, flags);
+ reg = readl_relaxed(pmu_spare_reg);
+ reg &= ~RIVA_SUSPEND_BIT;
+ writel_relaxed(reg, pmu_spare_reg);
+ spin_unlock_irqrestore(®_spinlock, flags);
+ clk_disable_unprepare(cxo);
+}
+EXPORT_SYMBOL(wcnss_resume_notify);
+
static int wcnss_wlan_suspend(struct device *dev)
{
if (penv && dev && (dev == &penv->pdev->dev) &&
@@ -612,6 +703,8 @@
{
int ret;
struct qcom_wcnss_opts *pdata;
+ unsigned long wcnss_phys_addr;
+ int size = 0;
int has_pronto_hw = of_property_read_bool(pdev->dev.of_node,
"qcom,has_pronto_hw");
@@ -692,8 +785,25 @@
wake_lock_init(&penv->wcnss_wake_lock, WAKE_LOCK_SUSPEND, "wcnss");
+ if (wcnss_hardware_type() == WCNSS_PRONTO_HW) {
+ size = 0x3000;
+ wcnss_phys_addr = MSM_PRONTO_PHYS;
+ } else {
+ wcnss_phys_addr = MSM_RIVA_PHYS;
+ size = SZ_256;
+ }
+
+ penv->msm_wcnss_base = ioremap(wcnss_phys_addr, size);
+ if (!penv->msm_wcnss_base) {
+ ret = -ENOMEM;
+ pr_err("%s: ioremap wcnss physical failed\n", __func__);
+ goto fail_wake;
+ }
+
return 0;
+fail_wake:
+ wake_lock_destroy(&penv->wcnss_wake_lock);
fail_res:
if (penv->pil)
subsystem_put(penv->pil);
@@ -702,7 +812,7 @@
WCNSS_WLAN_SWITCH_OFF);
fail_power:
if (has_pronto_hw)
- ret = wcnss_pronto_gpios_config(&pdev->dev, false);
+ wcnss_pronto_gpios_config(&pdev->dev, false);
else
wcnss_gpios_config(penv->gpios_5wire, false);
fail_gpio_res:
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index 6b54b23..9a18a97 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -617,21 +617,6 @@
int error = 0;
/*
- * If a PCI device configured to wake up the system from sleep states
- * has been suspended at run time and there's a resume request pending
- * for it, this is equivalent to the device signaling wakeup, so the
- * system suspend operation should be aborted.
- */
- pm_runtime_get_noresume(dev);
- if (pm_runtime_barrier(dev) && device_may_wakeup(dev))
- pm_wakeup_event(dev, 0);
-
- if (pm_wakeup_pending()) {
- pm_runtime_put_sync(dev);
- return -EBUSY;
- }
-
- /*
* PCI devices suspended at run time need to be resumed at this
* point, because in general it is necessary to reconfigure them for
* system suspend. Namely, if the device is supposed to wake up the
@@ -654,8 +639,6 @@
if (drv && drv->pm && drv->pm->complete)
drv->pm->complete(dev);
-
- pm_runtime_put_sync(dev);
}
#else /* !CONFIG_PM_SLEEP */
diff --git a/drivers/power/pm8921-bms.c b/drivers/power/pm8921-bms.c
index 60eee64..81be519 100644
--- a/drivers/power/pm8921-bms.c
+++ b/drivers/power/pm8921-bms.c
@@ -1911,7 +1911,8 @@
}
/* last_soc < soc ... scale and catch up */
- if (last_soc != -EINVAL && last_soc < soc && soc != 100)
+ if (last_soc != -EINVAL && last_soc < soc && soc != 100
+ && chip->catch_up_time_us != 0)
soc = scale_soc_while_chg(chip, delta_time_us, soc, last_soc);
last_soc = soc;
diff --git a/drivers/power/pm8921-charger.c b/drivers/power/pm8921-charger.c
index 8a36d6c..cb6b23e 100644
--- a/drivers/power/pm8921-charger.c
+++ b/drivers/power/pm8921-charger.c
@@ -87,6 +87,7 @@
#define EOC_CHECK_PERIOD_MS 10000
/* check for USB unplug every 200 msecs */
#define UNPLUG_CHECK_WAIT_PERIOD_MS 200
+#define USB_TRIM_ENTRIES 16
enum chg_fsm_state {
FSM_STATE_OFF_0 = 0,
@@ -209,7 +210,6 @@
* @dc_present: present status of dc
* @usb_charger_current: usb current to charge the battery with used when
* the usb path is enabled or charging is resumed
- * @safety_time: max time for which charging will happen
* @update_time: how frequently the userland needs to be updated
* @max_voltage_mv: the max volts the batt should be charged up to
* @min_voltage_mv: the min battery voltage before turning the FETon
@@ -230,12 +230,12 @@
unsigned int usb_charger_current;
unsigned int max_bat_chg_current;
unsigned int pmic_chg_irq[PM_CHG_MAX_INTS];
- unsigned int safety_time;
unsigned int ttrkl_time;
unsigned int update_time;
unsigned int max_voltage_mv;
unsigned int min_voltage_mv;
unsigned int uvd_voltage_mv;
+ unsigned int safe_current_ma;
unsigned int alarm_low_mv;
unsigned int alarm_high_mv;
int cool_temp_dc;
@@ -259,6 +259,7 @@
struct power_supply batt_psy;
struct dentry *dent;
struct bms_notify bms_notify;
+ int *usb_trim_table;
bool keep_btm_on_suspend;
bool ext_charging;
bool ext_charge_done;
@@ -709,6 +710,46 @@
u8 value;
};
+/* USB Trim tables */
+static int usb_trim_8038_table[USB_TRIM_ENTRIES] = {
+ 0x0,
+ 0x0,
+ -0x9,
+ 0x0,
+ -0xD,
+ 0x0,
+ -0x10,
+ -0x11,
+ 0x0,
+ 0x0,
+ -0x25,
+ 0x0,
+ -0x28,
+ 0x0,
+ -0x32,
+ 0x0
+};
+
+static int usb_trim_8917_table[USB_TRIM_ENTRIES] = {
+ 0x0,
+ 0x0,
+ 0xA,
+ 0xC,
+ 0x10,
+ 0x10,
+ 0x13,
+ 0x14,
+ 0x13,
+ 0x16,
+ 0x1A,
+ 0x1D,
+ 0x1D,
+ 0x21,
+ 0x24,
+ 0x26
+};
+
+/* Maximum USB setting table */
static struct usb_ma_limit_entry usb_ma_table[] = {
{100, 0x0},
{200, 0x1},
@@ -728,18 +769,92 @@
{1600, 0xF},
};
+#define REG_SBI_CONFIG 0x04F
+#define PAGE3_ENABLE_MASK 0x6
+#define USB_OVP_TRIM_MASK 0x3F
+#define USB_OVP_TRIM_MIN 0x00
+#define REG_USB_OVP_TRIM_ORIG_LSB 0x10A
+#define REG_USB_OVP_TRIM_ORIG_MSB 0x09C
+static int pm_chg_usb_trim(struct pm8921_chg_chip *chip, int index)
+{
+ u8 temp, sbi_config, msb, lsb;
+ s8 trim;
+ int rc = 0;
+ static u8 usb_trim_reg_orig = 0xFF;
+
+ /* No trim data for PM8921 */
+ if (!chip->usb_trim_table)
+ return 0;
+
+ if (usb_trim_reg_orig == 0xFF) {
+ rc = pm8xxx_readb(chip->dev->parent,
+ REG_USB_OVP_TRIM_ORIG_MSB, &msb);
+ if (rc) {
+ pr_err("error = %d reading sbi config reg\n", rc);
+ return rc;
+ }
+
+ rc = pm8xxx_readb(chip->dev->parent,
+ REG_USB_OVP_TRIM_ORIG_LSB, &lsb);
+ if (rc) {
+ pr_err("error = %d reading sbi config reg\n", rc);
+ return rc;
+ }
+
+ msb = msb >> 5;
+ lsb = lsb >> 5;
+ usb_trim_reg_orig = msb << 3 | lsb;
+ }
+
+ /* use the original trim value */
+ trim = usb_trim_reg_orig;
+
+ trim += chip->usb_trim_table[index];
+ if (trim < 0)
+ trim = 0;
+
+ pr_err("trim_orig %d write 0x%x index=%d value 0x%x to USB_OVP_TRIM\n",
+ usb_trim_reg_orig, trim, index, chip->usb_trim_table[index]);
+
+ rc = pm8xxx_readb(chip->dev->parent, REG_SBI_CONFIG, &sbi_config);
+ if (rc) {
+ pr_err("error = %d reading sbi config reg\n", rc);
+ return rc;
+ }
+
+ temp = sbi_config | PAGE3_ENABLE_MASK;
+ rc = pm8xxx_writeb(chip->dev->parent, REG_SBI_CONFIG, temp);
+ if (rc) {
+ pr_err("error = %d writing sbi config reg\n", rc);
+ return rc;
+ }
+
+ rc = pm_chg_masked_write(chip, USB_OVP_TRIM, USB_OVP_TRIM_MASK, trim);
+ if (rc) {
+ pr_err("error = %d writing USB_OVP_TRIM\n", rc);
+ return rc;
+ }
+
+ rc = pm8xxx_writeb(chip->dev->parent, REG_SBI_CONFIG, sbi_config);
+ if (rc) {
+ pr_err("error = %d writing sbi config reg\n", rc);
+ return rc;
+ }
+ return rc;
+}
+
#define PM8921_CHG_IUSB_MASK 0x1C
#define PM8921_CHG_IUSB_SHIFT 2
#define PM8921_CHG_IUSB_MAX 7
#define PM8921_CHG_IUSB_MIN 0
#define PM8917_IUSB_FINE_RES BIT(0)
-static int pm_chg_iusbmax_set(struct pm8921_chg_chip *chip, int reg_val)
+static int pm_chg_iusbmax_set(struct pm8921_chg_chip *chip, int index)
{
- u8 temp, fineres;
+ u8 temp, fineres, reg_val;
int rc;
- fineres = PM8917_IUSB_FINE_RES & usb_ma_table[reg_val].value;
- reg_val = usb_ma_table[reg_val].value >> 1;
+ reg_val = usb_ma_table[index].value >> 1;
+ fineres = PM8917_IUSB_FINE_RES & usb_ma_table[index].value;
if (reg_val < PM8921_CHG_IUSB_MIN || reg_val > PM8921_CHG_IUSB_MAX) {
pr_err("bad mA=%d asked to set\n", reg_val);
@@ -764,17 +879,25 @@
if (fineres) {
rc = pm_chg_masked_write(chip, IUSB_FINE_RES,
PM8917_IUSB_FINE_RES, fineres);
- if (rc)
+ if (rc) {
pr_err("Failed to write ISUB_FINE_RES rc=%d\n",
rc);
+ return rc;
+ }
}
} else {
rc = pm_chg_masked_write(chip, PBL_ACCESS2,
PM8921_CHG_IUSB_MASK, temp);
- if (rc)
+ if (rc) {
pr_err("Failed to write PBL_ACCESS2 rc=%d\n", rc);
+ return rc;
+ }
}
+ rc = pm_chg_usb_trim(chip, index);
+ if (rc)
+ pr_err("unable to set usb trim rc = %d\n", rc);
+
return rc;
}
@@ -1717,9 +1840,8 @@
if (i < 0)
i = 0;
rc = pm_chg_iusbmax_set(the_chip, i);
- if (rc) {
+ if (rc)
pr_err("unable to set iusb to %d rc = %d\n", i, rc);
- }
}
}
@@ -2691,8 +2813,8 @@
goto check_again_later;
}
}
-
- if (active_path & USB_ACTIVE_BIT) {
+ /* AICL only for usb wall charger */
+ if ((active_path & USB_ACTIVE_BIT) && usb_target_ma > 0) {
reg_loop = pm_chg_get_regulation_loop(chip);
pr_debug("reg_loop=0x%x usb_ma = %d\n", reg_loop, usb_ma);
if ((reg_loop & VIN_ACTIVE_BIT) &&
@@ -2737,7 +2859,9 @@
unplug_ovp_fet_open(chip);
}
+ /* AICL only for usb wall charger */
if (!(reg_loop & VIN_ACTIVE_BIT) && (active_path & USB_ACTIVE_BIT)
+ && usb_target_ma > 0
&& !charging_disabled) {
/* only increase iusb_max if vin loop not active */
if (usb_ma < usb_target_ma) {
@@ -3551,6 +3675,12 @@
chip->dc_present,
get_prop_batt_present(chip),
fsm_state);
+
+ /* Determine which USB trim column to use */
+ if (pm8xxx_get_version(chip->dev->parent) == PM8XXX_VERSION_8917)
+ chip->usb_trim_table = usb_trim_8917_table;
+ else if (pm8xxx_get_version(chip->dev->parent) == PM8XXX_VERSION_8038)
+ chip->usb_trim_table = usb_trim_8038_table;
}
struct pm_chg_irq_init_data {
@@ -3757,11 +3887,15 @@
#define CHG_BAT_TEMP_DIS_BIT BIT(2)
#define SAFE_CURRENT_MA 1500
#define PM_SUB_REV 0x001
+#define MIN_CHARGE_CURRENT_MA 350
+#define DEFAULT_SAFETY_MINUTES 500
static int __devinit pm8921_chg_hw_init(struct pm8921_chg_chip *chip)
{
int rc;
int vdd_safe;
u8 subrev;
+ int fcc_uah;
+ int safety_time = DEFAULT_SAFETY_MINUTES;
/* forcing 19p2mhz before accessing any charger registers */
pm8921_chg_force_19p2mhz_clk(chip);
@@ -3802,7 +3936,11 @@
chip->max_voltage_mv, rc);
return rc;
}
- rc = pm_chg_ibatsafe_set(chip, SAFE_CURRENT_MA);
+
+ if (chip->safe_current_ma == 0)
+ chip->safe_current_ma = SAFE_CURRENT_MA;
+
+ rc = pm_chg_ibatsafe_set(chip, chip->safe_current_ma);
if (rc) {
pr_err("Failed to set max voltage to %d rc=%d\n",
SAFE_CURRENT_MA, rc);
@@ -3830,20 +3968,26 @@
return rc;
}
- if (chip->safety_time != 0) {
- rc = pm_chg_tchg_max_set(chip, chip->safety_time);
- if (rc) {
- pr_err("Failed to set max time to %d minutes rc=%d\n",
- chip->safety_time, rc);
- return rc;
- }
+ fcc_uah = pm8921_bms_get_fcc();
+ if (fcc_uah > 0) {
+ safety_time = div_s64((s64)fcc_uah * 60,
+ 1000 * MIN_CHARGE_CURRENT_MA);
+ /* add 20 minutes of buffer time */
+ safety_time += 20;
+ }
+
+ rc = pm_chg_tchg_max_set(chip, safety_time);
+ if (rc) {
+ pr_err("Failed to set max time to %d minutes rc=%d\n",
+ safety_time, rc);
+ return rc;
}
if (chip->ttrkl_time != 0) {
rc = pm_chg_ttrkl_max_set(chip, chip->ttrkl_time);
if (rc) {
pr_err("Failed to set trkl time to %d minutes rc=%d\n",
- chip->safety_time, rc);
+ chip->ttrkl_time, rc);
return rc;
}
}
@@ -4249,13 +4393,13 @@
}
chip->dev = &pdev->dev;
- chip->safety_time = pdata->safety_time;
chip->ttrkl_time = pdata->ttrkl_time;
chip->update_time = pdata->update_time;
chip->max_voltage_mv = pdata->max_voltage;
chip->alarm_low_mv = pdata->alarm_low_mv;
chip->alarm_high_mv = pdata->alarm_high_mv;
chip->min_voltage_mv = pdata->min_voltage;
+ chip->safe_current_ma = pdata->safe_current_ma;
chip->uvd_voltage_mv = pdata->uvd_thresh_voltage;
chip->resume_voltage_delta = pdata->resume_voltage_delta;
chip->resume_charge_percent = pdata->resume_charge_percent;
diff --git a/drivers/slimbus/slim-msm-ctrl.c b/drivers/slimbus/slim-msm-ctrl.c
index 7efe40d..9c69f47 100644
--- a/drivers/slimbus/slim-msm-ctrl.c
+++ b/drivers/slimbus/slim-msm-ctrl.c
@@ -619,6 +619,7 @@
u16 chh[40];
struct slim_ch prop;
u32 exp;
+ u16 *grph = NULL;
u8 coeff, cc;
u8 prrate = buf[6];
if (len <= 8)
@@ -639,6 +640,9 @@
return ret;
if (mc == SLIM_USR_MC_DEF_ACT_CHAN)
sat->satch[j].req_def++;
+ /* First channel in group from satellite */
+ if (i == 8)
+ grph = &sat->satch[j].chanh;
continue;
}
if (sat->nsatch >= MSM_MAX_SATCH)
@@ -650,6 +654,8 @@
sat->satch[j].chanh = chh[i - 8];
if (mc == SLIM_USR_MC_DEF_ACT_CHAN)
sat->satch[j].req_def++;
+ if (i == 8)
+ grph = &sat->satch[j].chanh;
sat->nsatch++;
}
prop.dataf = (enum slim_ch_dataf)((buf[3] & 0xE0) >> 5);
@@ -670,10 +676,12 @@
true, &chh[0]);
else
ret = slim_define_ch(&sat->satcl, &prop,
- &chh[0], 1, false, NULL);
+ chh, 1, true, &chh[0]);
dev_dbg(dev->dev, "define sat grp returned:%d", ret);
if (ret)
return ret;
+ else if (grph)
+ *grph = chh[0];
/* part of group so activating 1 will take care of rest */
if (mc == SLIM_USR_MC_DEF_ACT_CHAN)
@@ -806,6 +814,8 @@
slim_control_ch(&sat->satcl,
sat->satch[i].chanh,
SLIM_CH_REMOVE, true);
+ slim_dealloc_ch(&sat->satcl,
+ sat->satch[i].chanh);
sat->satch[i].reconf = false;
}
}
diff --git a/drivers/slimbus/slimbus.c b/drivers/slimbus/slimbus.c
index 1e79dce..d5d6e0c 100644
--- a/drivers/slimbus/slimbus.c
+++ b/drivers/slimbus/slimbus.c
@@ -26,6 +26,7 @@
#define SLIM_HDL_TO_PORT(hdl) ((u32)(hdl) & 0xFF)
#define SLIM_HDL_TO_CHIDX(hdl) ((u16)(hdl) & 0xFF)
+#define SLIM_GRP_TO_NCHAN(hdl) ((u16)(hdl >> 8) & 0xFF)
#define SLIM_SLAVE_PORT(p, la) (((la)<<16) | (p))
#define SLIM_MGR_PORT(p) ((0xFF << 16) | (p))
@@ -767,6 +768,7 @@
list_for_each_entry(sbdev, &ctrl->devs, dev_list) {
if (memcmp(sbdev->e_addr, e_addr, 6) == 0) {
struct slim_driver *sbdrv;
+ sbdev->laddr = *laddr;
if (sbdev->dev.driver) {
sbdrv = to_slim_driver(sbdev->dev.driver);
if (sbdrv->device_up)
@@ -1845,7 +1847,7 @@
}
if (grp)
- *grph = chanh[0];
+ *grph = ((nchan << 8) | SLIM_HDL_TO_CHIDX(chanh[0]));
for (i = 0; i < nchan; i++) {
u8 chan = SLIM_HDL_TO_CHIDX(chanh[i]);
struct slim_ich *slc = &ctrl->chans[chan];
@@ -2868,6 +2870,7 @@
int ret = 0;
/* Get rid of the group flag in MSB if any */
u8 chan = SLIM_HDL_TO_CHIDX(chanh);
+ u8 nchan = 0;
struct slim_ich *slc = &ctrl->chans[chan];
if (!(slc->nextgrp & SLIM_START_GRP))
return -EINVAL;
@@ -2928,9 +2931,10 @@
}
}
- if (!(slc->nextgrp & SLIM_END_GRP))
+ nchan++;
+ if (nchan < SLIM_GRP_TO_NCHAN(chanh))
chan = SLIM_HDL_TO_CHIDX(slc->nextgrp);
- } while (!(slc->nextgrp & SLIM_END_GRP));
+ } while (nchan < SLIM_GRP_TO_NCHAN(chanh));
mutex_unlock(&ctrl->m_ctrl);
if (!ret && commit == true)
ret = slim_reconfigure_now(sb);
diff --git a/drivers/thermal/msm8974-tsens.c b/drivers/thermal/msm8974-tsens.c
index 8e13fbf..4cb93b8 100644
--- a/drivers/thermal/msm8974-tsens.c
+++ b/drivers/thermal/msm8974-tsens.c
@@ -558,6 +558,7 @@
int tsens9_point2 = 0, tsens10_point2 = 0;
int tsens_base2_data = 0, tsens_calibration_mode = 0, temp = 0;
uint32_t calib_data[6], calib_redun_sel, calib_data_backup[4];
+ uint32_t calib_tsens_point1_data[11], calib_tsens_point2_data[11];
if (tmdev->calibration_less_mode)
goto calibration_less_mode;
@@ -619,45 +620,46 @@
tsens10_point1 = (calib_data_backup[2] &
TSENS10_POINT1_MASK_BACKUP) >>
TSENS10_POINT1_BACKUP_SHIFT;
- } else if (tsens_calibration_mode == TSENS_TWO_POINT_CALIB) {
- pr_debug("backup two point calibrationless mode\n");
- tsens_base2_data = (calib_data_backup[2] &
+ } else
+ goto calibration_less_mode;
+
+ if (tsens_calibration_mode == TSENS_TWO_POINT_CALIB) {
+ pr_debug("backup two point calibrationless mode\n");
+ tsens_base2_data = (calib_data_backup[2] &
TSENS_BASE2_BACKUP_MASK) >>
TSENS_POINT2_BASE_BACKUP_SHIFT;
- tsens0_point2 = (calib_data_backup[2] &
+ tsens0_point2 = (calib_data_backup[2] &
TSENS0_POINT2_BACKUP_MASK) >>
TSENS0_POINT2_BACKUP_SHIFT;
- tsens1_point2 = (calib_data_backup[3] &
+ tsens1_point2 = (calib_data_backup[3] &
TSENS1_POINT2_BACKUP_MASK);
- tsens2_point2 = (calib_data_backup[3] &
+ tsens2_point2 = (calib_data_backup[3] &
TSENS2_POINT2_BACKUP_MASK) >>
TSENS2_POINT2_BACKUP_SHIFT;
- tsens3_point2 = (calib_data_backup[3] &
+ tsens3_point2 = (calib_data_backup[3] &
TSENS3_POINT2_BACKUP_MASK) >>
TSENS3_POINT2_BACKUP_SHIFT;
- tsens4_point2 = (calib_data_backup[3] &
+ tsens4_point2 = (calib_data_backup[3] &
TSENS4_POINT2_BACKUP_MASK) >>
TSENS4_POINT2_BACKUP_SHIFT;
- tsens5_point2 = (calib_data[4] & TSENS5_POINT2_BACKUP_MASK) >>
- TSENS5_POINT2_BACKUP_SHIFT;
- tsens6_point2 = (calib_data[5] & TSENS6_POINT2_BACKUP_MASK);
- tsens7_point2 = (calib_data[5] & TSENS7_POINT2_BACKUP_MASK) >>
- TSENS7_POINT2_BACKUP_SHIFT;
- tsens8_point2 = (calib_data[5] & TSENS8_POINT2_BACKUP_MASK) >>
- TSENS8_POINT2_BACKUP_SHIFT;
- tsens9_point2 = (calib_data[5] & TSENS9_POINT2_BACKUP_MASK) >>
- TSENS9_POINT2_BACKUP_SHIFT;
- tsens10_point2 = (calib_data[5] & TSENS10_POINT2_BACKUP_MASK)
- >> TSENS10_POINT2_BACKUP_SHIFT;
- } else {
- pr_debug("TSENS:backup is calibrationless mode\n");
- for (i = 0; i < tmdev->tsens_num_sensor; i++) {
- tmdev->sensor[i].calib_data_point2 = 780;
- tmdev->sensor[i].calib_data_point1 = 492;
+ tsens5_point2 = (calib_data[4] &
+ TSENS5_POINT2_BACKUP_MASK) >>
+ TSENS5_POINT2_BACKUP_SHIFT;
+ tsens6_point2 = (calib_data[5] &
+ TSENS6_POINT2_BACKUP_MASK);
+ tsens7_point2 = (calib_data[5] &
+ TSENS7_POINT2_BACKUP_MASK) >>
+ TSENS7_POINT2_BACKUP_SHIFT;
+ tsens8_point2 = (calib_data[5] &
+ TSENS8_POINT2_BACKUP_MASK) >>
+ TSENS8_POINT2_BACKUP_SHIFT;
+ tsens9_point2 = (calib_data[5] &
+ TSENS9_POINT2_BACKUP_MASK) >>
+ TSENS9_POINT2_BACKUP_SHIFT;
+ tsens10_point2 = (calib_data[5] &
+ TSENS10_POINT2_BACKUP_MASK)
+ >> TSENS10_POINT2_BACKUP_SHIFT;
}
- tsens_calibration_mode = 0;
- goto compute_intercept_slope;
- }
} else {
tsens_calibration_mode = (calib_data[1] & TSENS_CAL_SEL_0_1)
>> TSENS_CAL_SEL_SHIFT;
@@ -690,7 +692,10 @@
tsens9_point1 = (calib_data[2] & TSENS9_POINT1_MASK);
tsens10_point1 = (calib_data[2] & TSENS10_POINT1_MASK)
>> TSENS10_POINT1_SHIFT;
- } else if (tsens_calibration_mode == TSENS_TWO_POINT_CALIB) {
+ } else
+ goto calibration_less_mode;
+
+ if (tsens_calibration_mode == TSENS_TWO_POINT_CALIB) {
pr_debug("TSENS is two point calibrationless mode\n");
tsens_base2_data = (calib_data[2] & TSENS_BASE2_MASK) >>
TSENS_POINT2_BASE_SHIFT;
@@ -714,120 +719,145 @@
TSENS9_POINT2_SHIFT;
tsens10_point2 = (calib_data[4] & TSENS10_POINT2_MASK)
>> TSENS10_POINT2_SHIFT;
- } else {
+ }
+
+ if (tsens_calibration_mode == 0) {
calibration_less_mode:
pr_debug("TSENS is calibrationless mode\n");
for (i = 0; i < tmdev->tsens_num_sensor; i++)
- tmdev->sensor[i].calib_data_point2 = 780;
- tmdev->sensor[0].calib_data_point1 = 502;
- tmdev->sensor[1].calib_data_point1 = 509;
- tmdev->sensor[2].calib_data_point1 = 503;
- tmdev->sensor[3].calib_data_point1 = 509;
- tmdev->sensor[4].calib_data_point1 = 505;
- tmdev->sensor[5].calib_data_point1 = 509;
- tmdev->sensor[6].calib_data_point1 = 507;
- tmdev->sensor[7].calib_data_point1 = 510;
- tmdev->sensor[8].calib_data_point1 = 508;
- tmdev->sensor[9].calib_data_point1 = 509;
- tmdev->sensor[10].calib_data_point1 = 508;
+ calib_tsens_point2_data[i] = 780;
+ calib_tsens_point1_data[0] = 502;
+ calib_tsens_point1_data[1] = 509;
+ calib_tsens_point1_data[2] = 503;
+ calib_tsens_point1_data[3] = 509;
+ calib_tsens_point1_data[4] = 505;
+ calib_tsens_point1_data[5] = 509;
+ calib_tsens_point1_data[6] = 507;
+ calib_tsens_point1_data[7] = 510;
+ calib_tsens_point1_data[8] = 508;
+ calib_tsens_point1_data[9] = 509;
+ calib_tsens_point1_data[10] = 508;
goto compute_intercept_slope;
}
}
if (tsens_calibration_mode == TSENS_ONE_POINT_CALIB) {
pr_debug("old one point calibration calculation\n");
- tmdev->sensor[0].calib_data_point1 =
- (((tsens_base1_data) << 2) | TSENS_BIT_APPEND) + tsens0_point1;
- tmdev->sensor[1].calib_data_point1 =
- (((tsens_base1_data) << 2) | TSENS_BIT_APPEND) + tsens1_point1;
- tmdev->sensor[2].calib_data_point1 =
- (((tsens_base1_data) << 2) | TSENS_BIT_APPEND) + tsens2_point1;
- tmdev->sensor[3].calib_data_point1 =
- (((tsens_base1_data) << 2) | TSENS_BIT_APPEND) + tsens3_point1;
- tmdev->sensor[4].calib_data_point1 =
- (((tsens_base1_data) << 2) | TSENS_BIT_APPEND) + tsens4_point1;
- tmdev->sensor[5].calib_data_point1 =
- (((tsens_base1_data) << 2) | TSENS_BIT_APPEND) + tsens5_point1;
- tmdev->sensor[6].calib_data_point1 =
- (((tsens_base1_data) << 2) | TSENS_BIT_APPEND) + tsens6_point1;
- tmdev->sensor[7].calib_data_point1 =
- (((tsens_base1_data) << 2) | TSENS_BIT_APPEND) + tsens7_point1;
- tmdev->sensor[8].calib_data_point1 =
- (((tsens_base1_data) << 2) | TSENS_BIT_APPEND) + tsens8_point1;
- tmdev->sensor[9].calib_data_point1 =
- (((tsens_base1_data) << 2) | TSENS_BIT_APPEND) + tsens9_point1;
- tmdev->sensor[10].calib_data_point1 =
- (((tsens_base1_data) << 2) | TSENS_BIT_APPEND) + tsens10_point1;
+ calib_tsens_point1_data[0] =
+ (((tsens_base1_data) << 2) | TSENS_BIT_APPEND)
+ + tsens0_point1;
+ calib_tsens_point1_data[1] =
+ (((tsens_base1_data) << 2) | TSENS_BIT_APPEND)
+ + tsens1_point1;
+ calib_tsens_point1_data[2] =
+ (((tsens_base1_data) << 2) | TSENS_BIT_APPEND)
+ + tsens2_point1;
+ calib_tsens_point1_data[3] =
+ (((tsens_base1_data) << 2) | TSENS_BIT_APPEND)
+ + tsens3_point1;
+ calib_tsens_point1_data[4] =
+ (((tsens_base1_data) << 2) | TSENS_BIT_APPEND)
+ + tsens4_point1;
+ calib_tsens_point1_data[5] =
+ (((tsens_base1_data) << 2) | TSENS_BIT_APPEND)
+ + tsens5_point1;
+ calib_tsens_point1_data[6] =
+ (((tsens_base1_data) << 2) | TSENS_BIT_APPEND)
+ + tsens6_point1;
+ calib_tsens_point1_data[7] =
+ (((tsens_base1_data) << 2) | TSENS_BIT_APPEND)
+ + tsens7_point1;
+ calib_tsens_point1_data[8] =
+ (((tsens_base1_data) << 2) | TSENS_BIT_APPEND)
+ + tsens8_point1;
+ calib_tsens_point1_data[9] =
+ (((tsens_base1_data) << 2) | TSENS_BIT_APPEND)
+ + tsens9_point1;
+ calib_tsens_point1_data[10] =
+ (((tsens_base1_data) << 2) | TSENS_BIT_APPEND)
+ + tsens10_point1;
}
if ((tsens_calibration_mode == TSENS_ONE_POINT_CALIB_OPTION_2) ||
(tsens_calibration_mode == TSENS_TWO_POINT_CALIB)) {
pr_debug("one and two point calibration calculation\n");
-
- tmdev->sensor[0].calib_data_point1 =
- ((((tsens_base1_data) + tsens0_point1) << 2) |
+ calib_tsens_point1_data[0] =
+ ((((tsens_base1_data) + tsens0_point1) << 2) |
TSENS_BIT_APPEND);
- tmdev->sensor[1].calib_data_point1 =
- ((((tsens_base1_data) + tsens1_point1) << 2) |
+ calib_tsens_point1_data[1] =
+ ((((tsens_base1_data) + tsens1_point1) << 2) |
TSENS_BIT_APPEND);
- tmdev->sensor[2].calib_data_point1 =
- ((((tsens_base1_data) + tsens2_point1) << 2) |
+ calib_tsens_point1_data[2] =
+ ((((tsens_base1_data) + tsens2_point1) << 2) |
TSENS_BIT_APPEND);
- tmdev->sensor[3].calib_data_point1 =
- ((((tsens_base1_data) + tsens3_point1) << 2) |
+ calib_tsens_point1_data[3] =
+ ((((tsens_base1_data) + tsens3_point1) << 2) |
TSENS_BIT_APPEND);
- tmdev->sensor[4].calib_data_point1 =
- ((((tsens_base1_data) + tsens4_point1) << 2) |
+ calib_tsens_point1_data[4] =
+ ((((tsens_base1_data) + tsens4_point1) << 2) |
TSENS_BIT_APPEND);
- tmdev->sensor[5].calib_data_point1 =
- ((((tsens_base1_data) + tsens5_point1) << 2) |
+ calib_tsens_point1_data[5] =
+ ((((tsens_base1_data) + tsens5_point1) << 2) |
TSENS_BIT_APPEND);
- tmdev->sensor[6].calib_data_point1 =
- ((((tsens_base1_data) + tsens6_point1) << 2) |
+ calib_tsens_point1_data[6] =
+ ((((tsens_base1_data) + tsens6_point1) << 2) |
TSENS_BIT_APPEND);
- tmdev->sensor[7].calib_data_point1 =
- ((((tsens_base1_data) + tsens7_point1) << 2) |
+ calib_tsens_point1_data[7] =
+ ((((tsens_base1_data) + tsens7_point1) << 2) |
TSENS_BIT_APPEND);
- tmdev->sensor[8].calib_data_point1 =
- ((((tsens_base1_data) + tsens8_point1) << 2) |
+ calib_tsens_point1_data[8] =
+ ((((tsens_base1_data) + tsens8_point1) << 2) |
TSENS_BIT_APPEND);
- tmdev->sensor[9].calib_data_point1 =
- ((((tsens_base1_data) + tsens9_point1) << 2) |
+ calib_tsens_point1_data[9] =
+ ((((tsens_base1_data) + tsens9_point1) << 2) |
TSENS_BIT_APPEND);
- tmdev->sensor[10].calib_data_point1 =
- ((((tsens_base1_data) + tsens10_point1) << 2) |
+ calib_tsens_point1_data[10] =
+ ((((tsens_base1_data) + tsens10_point1) << 2) |
TSENS_BIT_APPEND);
}
if (tsens_calibration_mode == TSENS_TWO_POINT_CALIB) {
pr_debug("two point calibration calculation\n");
- tmdev->sensor[0].calib_data_point2 =
- (((tsens_base2_data + tsens0_point2) << 2) | TSENS_BIT_APPEND);
- tmdev->sensor[1].calib_data_point2 =
- (((tsens_base2_data + tsens1_point2) << 2) | TSENS_BIT_APPEND);
- tmdev->sensor[2].calib_data_point2 =
- (((tsens_base2_data + tsens2_point2) << 2) | TSENS_BIT_APPEND);
- tmdev->sensor[3].calib_data_point2 =
- (((tsens_base2_data + tsens3_point2) << 2) | TSENS_BIT_APPEND);
- tmdev->sensor[4].calib_data_point2 =
- (((tsens_base2_data + tsens4_point2) << 2) | TSENS_BIT_APPEND);
- tmdev->sensor[5].calib_data_point2 =
- (((tsens_base2_data + tsens5_point2) << 2) | TSENS_BIT_APPEND);
- tmdev->sensor[6].calib_data_point2 =
- (((tsens_base2_data + tsens6_point2) << 2) | TSENS_BIT_APPEND);
- tmdev->sensor[7].calib_data_point2 =
- (((tsens_base2_data + tsens7_point2) << 2) | TSENS_BIT_APPEND);
- tmdev->sensor[8].calib_data_point2 =
- (((tsens_base2_data + tsens8_point2) << 2) | TSENS_BIT_APPEND);
- tmdev->sensor[9].calib_data_point2 =
- (((tsens_base2_data + tsens9_point2) << 2) | TSENS_BIT_APPEND);
- tmdev->sensor[10].calib_data_point2 =
- (((tsens_base2_data + tsens10_point2) << 2) | TSENS_BIT_APPEND);
+ calib_tsens_point2_data[0] =
+ (((tsens_base2_data + tsens0_point2) << 2) |
+ TSENS_BIT_APPEND);
+ calib_tsens_point2_data[1] =
+ (((tsens_base2_data + tsens1_point2) << 2) |
+ TSENS_BIT_APPEND);
+ calib_tsens_point2_data[2] =
+ (((tsens_base2_data + tsens2_point2) << 2) |
+ TSENS_BIT_APPEND);
+ calib_tsens_point2_data[3] =
+ (((tsens_base2_data + tsens3_point2) << 2) |
+ TSENS_BIT_APPEND);
+ calib_tsens_point2_data[4] =
+ (((tsens_base2_data + tsens4_point2) << 2) |
+ TSENS_BIT_APPEND);
+ calib_tsens_point2_data[5] =
+ (((tsens_base2_data + tsens5_point2) << 2) |
+ TSENS_BIT_APPEND);
+ calib_tsens_point2_data[6] =
+ (((tsens_base2_data + tsens6_point2) << 2) |
+ TSENS_BIT_APPEND);
+ calib_tsens_point2_data[7] =
+ (((tsens_base2_data + tsens7_point2) << 2) |
+ TSENS_BIT_APPEND);
+ calib_tsens_point2_data[8] =
+ (((tsens_base2_data + tsens8_point2) << 2) |
+ TSENS_BIT_APPEND);
+ calib_tsens_point2_data[9] =
+ (((tsens_base2_data + tsens9_point2) << 2) |
+ TSENS_BIT_APPEND);
+ calib_tsens_point2_data[10] =
+ (((tsens_base2_data + tsens10_point2) << 2) |
+ TSENS_BIT_APPEND);
}
compute_intercept_slope:
for (i = 0; i < tmdev->tsens_num_sensor; i++) {
int32_t num = 0, den = 0;
+ tmdev->sensor[i].calib_data_point2 = calib_tsens_point2_data[i];
+ tmdev->sensor[i].calib_data_point1 = calib_tsens_point1_data[i];
if (tsens_calibration_mode == TSENS_TWO_POINT_CALIB) {
num = TSENS_CAL_DEGC_POINT2 - TSENS_CAL_DEGC_POINT2;
den = tmdev->sensor[i].calib_data_point2 -
diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c
index 98eb0a0..4073fc8 100644
--- a/drivers/usb/dwc3/dwc3-msm.c
+++ b/drivers/usb/dwc3/dwc3-msm.c
@@ -1262,6 +1262,17 @@
dwc3_msm_write_readback(mdwc->base, HS_PHY_CTRL_REG,
0xC00000, 0x800000);
+ /* Sequence to put SSPHY in low power state:
+ * 1. Clear REF_SS_PHY_EN in SS_PHY_CTRL_REG
+ * 2. Clear REF_USE_PAD in SS_PHY_CTRL_REG
+ * 3. Set TEST_POWERED_DOWN in SS_PHY_CTRL_REG to enable PHY retention
+ * 4. Disable SSPHY ref clk
+ */
+ dwc3_msm_write_readback(mdwc->base, SS_PHY_CTRL_REG, (1 << 8), 0x0);
+ dwc3_msm_write_readback(mdwc->base, SS_PHY_CTRL_REG, (1 << 28), 0x0);
+ dwc3_msm_write_readback(mdwc->base, SS_PHY_CTRL_REG, (1 << 26),
+ (1 << 26));
+
usleep_range(1000, 1200);
clk_disable_unprepare(mdwc->ref_clk);
@@ -1346,14 +1357,26 @@
dwc3_msm_write_reg(mdwc->base, DWC3_GUSB2PHYCFG(0),
dwc3_msm_read_reg(mdwc->base, DWC3_GUSB2PHYCFG(0)) | 0xF0000000);
- /* 20usec delay required before de-asserting PHY RESET */
- udelay(20);
+ /* 10usec delay required before de-asserting PHY RESET */
+ udelay(10);
dwc3_msm_write_reg(mdwc->base, DWC3_GUSB2PHYCFG(0),
dwc3_msm_read_reg(mdwc->base, DWC3_GUSB2PHYCFG(0)) & 0x7FFFFFFF);
/* Bring PHY out of suspend */
dwc3_msm_write_readback(mdwc->base, HS_PHY_CTRL_REG, 0xC00000, 0x0);
+ /* Assert SS PHY RESET */
+ dwc3_msm_write_readback(mdwc->base, SS_PHY_CTRL_REG, (1 << 7),
+ (1 << 7));
+ dwc3_msm_write_readback(mdwc->base, SS_PHY_CTRL_REG, (1 << 28),
+ (1 << 28));
+ dwc3_msm_write_readback(mdwc->base, SS_PHY_CTRL_REG, (1 << 8),
+ (1 << 8));
+ dwc3_msm_write_readback(mdwc->base, SS_PHY_CTRL_REG, (1 << 26), 0x0);
+ /* 10usec delay required before de-asserting SS PHY RESET */
+ udelay(10);
+ dwc3_msm_write_readback(mdwc->base, SS_PHY_CTRL_REG, (1 << 7), 0x0);
+
atomic_set(&mdwc->in_lpm, 0);
/* match disable_irq call from isr */
@@ -1745,7 +1768,9 @@
}
msm->ext_xceiv.otg_capability = of_property_read_bool(node,
- "qcom,dwc-usb3-msm-otg-capability");
+ "qcom,otg-capability");
+ msm->charger.charging_disabled = of_property_read_bool(node,
+ "qcom,charging-disabled");
if (!msm->ext_xceiv.otg_capability) {
/* DWC3 has separate IRQ line for OTG events (ID/BSV etc.) */
diff --git a/drivers/usb/dwc3/dwc3_otg.c b/drivers/usb/dwc3/dwc3_otg.c
index 41dd144..7b672c4 100644
--- a/drivers/usb/dwc3/dwc3_otg.c
+++ b/drivers/usb/dwc3/dwc3_otg.c
@@ -393,11 +393,14 @@
struct dwc3_otg *dotg = container_of(phy->otg, struct dwc3_otg, otg);
- if (!dotg->psy) {
- dev_err(phy->dev, "no usb power supply registered\n");
+ if (!dotg->psy || !dotg->charger) {
+ dev_err(phy->dev, "no usb power supply/charger registered\n");
return 0;
}
+ if (dotg->charger->charging_disabled)
+ return 0;
+
if (dotg->charger->chg_type == DWC3_SDP_CHARGER)
power_supply_type = POWER_SUPPLY_TYPE_USB;
else if (dotg->charger->chg_type == DWC3_CDP_CHARGER)
diff --git a/drivers/usb/dwc3/dwc3_otg.h b/drivers/usb/dwc3/dwc3_otg.h
index 4384888..c93ce5f 100644
--- a/drivers/usb/dwc3/dwc3_otg.h
+++ b/drivers/usb/dwc3/dwc3_otg.h
@@ -70,6 +70,7 @@
struct dwc3_charger {
enum dwc3_chg_type chg_type;
unsigned max_power;
+ bool charging_disabled;
/* start/stop charger detection, provided by external charger module */
void (*start_detection)(struct dwc3_charger *charger, bool start);
diff --git a/drivers/usb/gadget/android.c b/drivers/usb/gadget/android.c
index 5fb2370..b773d1a 100644
--- a/drivers/usb/gadget/android.c
+++ b/drivers/usb/gadget/android.c
@@ -24,6 +24,7 @@
#include <linux/utsname.h>
#include <linux/platform_device.h>
#include <linux/pm_qos.h>
+#include <linux/of.h>
#include <linux/usb/ch9.h>
#include <linux/usb/composite.h>
@@ -2409,11 +2410,26 @@
static int __devinit android_probe(struct platform_device *pdev)
{
- struct android_usb_platform_data *pdata = pdev->dev.platform_data;
+ struct android_usb_platform_data *pdata;
struct android_dev *android_dev;
struct resource *res;
int ret = 0;
+ if (pdev->dev.of_node) {
+ dev_dbg(&pdev->dev, "device tree enabled\n");
+ pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+ if (!pdata) {
+ pr_err("unable to allocate platform data\n");
+ return -ENOMEM;
+ }
+
+ of_property_read_u32(pdev->dev.of_node,
+ "qcom,android-usb-swfi-latency",
+ &pdata->swfi_latency);
+ } else {
+ pdata = pdev->dev.platform_data;
+ }
+
if (!android_class) {
android_class = class_create(THIS_MODULE, "android_usb");
if (IS_ERR(android_class))
diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c
index 92cbe6f..d10c692 100644
--- a/drivers/usb/otg/msm_otg.c
+++ b/drivers/usb/otg/msm_otg.c
@@ -3068,10 +3068,9 @@
{
static bool init;
struct msm_otg *motg = the_msm_otg;
- struct usb_otg *otg = motg->phy.otg;
- /* In A Host Mode, ignore received BSV interrupts */
- if (otg->phy->state >= OTG_STATE_A_IDLE)
+ /* Ignore received BSV interrupts, if ID pin is GND */
+ if (!test_bit(ID, &motg->inputs))
return;
if (online) {
diff --git a/drivers/video/msm/mdp.c b/drivers/video/msm/mdp.c
index 25da094..985d0b0 100644
--- a/drivers/video/msm/mdp.c
+++ b/drivers/video/msm/mdp.c
@@ -2528,8 +2528,6 @@
#if defined(CONFIG_FB_MSM_MIPI_DSI) && defined(CONFIG_FB_MSM_MDP40)
struct mipi_panel_info *mipi;
#endif
- static int contSplash_update_done;
- char *cp;
unsigned int mdp_r = 0;
if ((pdev->id == 0) && (pdev->num_resources > 0)) {
@@ -2613,57 +2611,6 @@
mfd->pdev = msm_fb_dev;
mfd->mdp_rev = mdp_rev;
- if (mdp_pdata) {
- if (mdp_pdata->cont_splash_enabled) {
- mfd->cont_splash_done = 0;
-
- if (!contSplash_update_done) {
- uint32 bpp = 3;
- /*read panel wxh and calculate splash screen
- size*/
- mdp_pdata->splash_screen_size =
- inpdw(MDP_BASE + 0x90004);
- mdp_pdata->splash_screen_size =
- (((mdp_pdata->splash_screen_size >> 16) &
- 0x00000FFF) * (
- mdp_pdata->splash_screen_size &
- 0x00000FFF)) * bpp;
-
- mdp_pdata->splash_screen_addr =
- inpdw(MDP_BASE + 0x90008);
-
- mfd->copy_splash_buf = dma_alloc_coherent(NULL,
- mdp_pdata->splash_screen_size,
- (dma_addr_t *) &(mfd->copy_splash_phys),
- GFP_KERNEL);
-
- if (!mfd->copy_splash_buf) {
- pr_err("DMA ALLOC FAILED for SPLASH\n");
- return -ENOMEM;
- }
- cp = (char *)ioremap(
- mdp_pdata->splash_screen_addr,
- mdp_pdata->splash_screen_size);
- if (!cp) {
- pr_err("IOREMAP FAILED for SPLASH\n");
- return -ENOMEM;
- }
- memcpy(mfd->copy_splash_buf, cp,
- mdp_pdata->splash_screen_size);
-
- MDP_OUTP(MDP_BASE + 0x90008,
- mfd->copy_splash_phys);
-
- if (mfd->panel.type == MIPI_VIDEO_PANEL ||
- mfd->panel.type == LCDC_PANEL)
- mdp_pipe_ctrl(MDP_CMD_BLOCK,
- MDP_BLOCK_POWER_ON, FALSE);
- contSplash_update_done = 1;
- }
- } else
- mfd->cont_splash_done = 1;
- }
-
mfd->ov0_wb_buf = MDP_ALLOC(sizeof(struct mdp_buf_type));
mfd->ov1_wb_buf = MDP_ALLOC(sizeof(struct mdp_buf_type));
memset((void *)mfd->ov0_wb_buf, 0, sizeof(struct mdp_buf_type));
@@ -2694,6 +2641,53 @@
rc = -ENOMEM;
goto mdp_probe_err;
}
+
+ if (mdp_pdata) {
+ if (mdp_pdata->cont_splash_enabled &&
+ mfd->panel_info.pdest == DISPLAY_1) {
+ char *cp;
+ uint32 bpp = 3;
+ /*read panel wxh and calculate splash screen
+ size*/
+ mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+
+ mdp_pdata->splash_screen_size =
+ inpdw(MDP_BASE + 0x90004);
+ mdp_pdata->splash_screen_size =
+ (((mdp_pdata->splash_screen_size >> 16) &
+ 0x00000FFF) * (
+ mdp_pdata->splash_screen_size &
+ 0x00000FFF)) * bpp;
+
+ mdp_pdata->splash_screen_addr =
+ inpdw(MDP_BASE + 0x90008);
+
+ mfd->copy_splash_buf = dma_alloc_coherent(NULL,
+ mdp_pdata->splash_screen_size,
+ (dma_addr_t *) &(mfd->copy_splash_phys),
+ GFP_KERNEL);
+
+ if (!mfd->copy_splash_buf) {
+ pr_err("DMA ALLOC FAILED for SPLASH\n");
+ return -ENOMEM;
+ }
+ cp = (char *)ioremap(
+ mdp_pdata->splash_screen_addr,
+ mdp_pdata->splash_screen_size);
+ if (!cp) {
+ pr_err("IOREMAP FAILED for SPLASH\n");
+ return -ENOMEM;
+ }
+ memcpy(mfd->copy_splash_buf, cp,
+ mdp_pdata->splash_screen_size);
+
+ MDP_OUTP(MDP_BASE + 0x90008,
+ mfd->copy_splash_phys);
+ }
+
+ mfd->cont_splash_done = (1 - mdp_pdata->cont_splash_enabled);
+ }
+
/* data chain */
pdata = msm_fb_dev->dev.platform_data;
pdata->on = mdp_on;
@@ -2993,7 +2987,7 @@
}
/* req bus bandwidth immediately */
- if (!(mfd->cont_splash_done))
+ if (!(mfd->cont_splash_done) && (mfd->panel_info.pdest == DISPLAY_1))
mdp_bus_scale_update_request(5);
#endif
diff --git a/drivers/video/msm/mdss/mdss_hdmi_tx.c b/drivers/video/msm/mdss/mdss_hdmi_tx.c
index d53240f..a8f853d 100644
--- a/drivers/video/msm/mdss/mdss_hdmi_tx.c
+++ b/drivers/video/msm/mdss/mdss_hdmi_tx.c
@@ -15,6 +15,7 @@
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/mutex.h>
+#include <linux/iopoll.h>
#include <linux/of_address.h>
#include <linux/of_gpio.h>
#include <linux/types.h>
@@ -37,6 +38,9 @@
#define SW_RESET BIT(2)
#define SW_RESET_PLL BIT(0)
+#define HPD_DISCONNECT_POLARITY 0
+#define HPD_CONNECT_POLARITY 1
+
#define IFRAME_CHECKSUM_32(d) \
((d & 0xff) + ((d >> 8) & 0xff) + \
((d >> 16) & 0xff) + ((d >> 24) & 0xff))
@@ -457,86 +461,8 @@
return status;
} /* hdmi_tx_read_sink_info */
-static void hdmi_tx_hpd_state_work(struct work_struct *work)
-{
- u32 hpd_state = false;
- struct hdmi_tx_ctrl *hdmi_ctrl = NULL;
- struct dss_io_data *io = NULL;
-
- hdmi_ctrl = container_of(work, struct hdmi_tx_ctrl, hpd_state_work);
- if (!hdmi_ctrl || !hdmi_ctrl->hpd_initialized) {
- DEV_DBG("%s: invalid input\n", __func__);
- return;
- }
-
- io = &hdmi_ctrl->pdata.io[HDMI_TX_CORE_IO];
- if (!io->base) {
- DEV_ERR("%s: Core io is not initialized\n", __func__);
- return;
- }
-
- DEV_DBG("%s: Got HPD interrupt\n", __func__);
-
- hpd_state = (DSS_REG_R(io, HDMI_HPD_INT_STATUS) & BIT(1)) >> 1;
- mutex_lock(&hdmi_ctrl->mutex);
- if ((hdmi_ctrl->hpd_prev_state != hdmi_ctrl->hpd_state) ||
- (hdmi_ctrl->hpd_state != hpd_state)) {
-
- hdmi_ctrl->hpd_state = hpd_state;
- hdmi_ctrl->hpd_prev_state = hdmi_ctrl->hpd_state;
- hdmi_ctrl->hpd_stable = 0;
-
- DEV_DBG("%s: state not stable yet, wait again (%d|%d|%d)\n",
- __func__, hdmi_ctrl->hpd_prev_state,
- hdmi_ctrl->hpd_state, hpd_state);
-
- mutex_unlock(&hdmi_ctrl->mutex);
-
- mod_timer(&hdmi_ctrl->hpd_state_timer, jiffies + HZ/2);
-
- return;
- }
-
- if (hdmi_ctrl->hpd_stable) {
- mutex_unlock(&hdmi_ctrl->mutex);
- DEV_DBG("%s: no more timer, depending on IRQ now\n",
- __func__);
- return;
- }
-
- hdmi_ctrl->hpd_stable = 1;
-
- /*
- *todo: Revisit cable chg detected condition when HPD support is ready
- */
- hdmi_ctrl->hpd_cable_chg_detected = false;
- mutex_unlock(&hdmi_ctrl->mutex);
-
- if (hpd_state) {
- /* todo: what if EDID read fails? */
- hdmi_tx_read_sink_info(hdmi_ctrl);
- DEV_INFO("HDMI HPD: sense CONNECTED: send ONLINE\n");
- kobject_uevent(hdmi_ctrl->kobj, KOBJ_ONLINE);
- switch_set_state(&hdmi_ctrl->sdev, 1);
- DEV_INFO("%s: Hdmi state switch to %d\n", __func__,
- hdmi_ctrl->sdev.state);
- } else {
- DEV_INFO("HDMI HPD: sense DISCONNECTED: send OFFLINE\n");
- kobject_uevent(hdmi_ctrl->kobj, KOBJ_OFFLINE);
- switch_set_state(&hdmi_ctrl->sdev, 0);
- DEV_INFO("%s: Hdmi state switch to %d\n", __func__,
- hdmi_ctrl->sdev.state);
- }
-
- /* Set IRQ for HPD */
- DSS_REG_W(io, HDMI_HPD_INT_CTRL, 4 | (hpd_state ? 0 : 2));
-} /* hdmi_tx_hpd_state_work */
-
static void hdmi_tx_hpd_int_work(struct work_struct *work)
{
- u32 hpd_int_status;
- u32 hpd_int_ctrl;
- u32 cable_detected;
struct hdmi_tx_ctrl *hdmi_ctrl = NULL;
struct dss_io_data *io = NULL;
@@ -552,23 +478,24 @@
return;
}
- /* Process HPD Interrupt */
- hpd_int_status = DSS_REG_R(io, HDMI_HPD_INT_STATUS);
- hpd_int_ctrl = DSS_REG_R(io, HDMI_HPD_INT_CTRL);
+ DEV_DBG("%s: Got HPD interrupt\n", __func__);
- DSS_REG_W(io, HDMI_HPD_INT_CTRL, BIT(2));
-
- cable_detected = hpd_int_status & BIT(1);
- mutex_lock(&hdmi_ctrl->mutex);
- hdmi_ctrl->hpd_cable_chg_detected = true;
- hdmi_ctrl->hpd_prev_state = cable_detected ? 0 : 1;
- hdmi_ctrl->hpd_stable = 0;
- mutex_unlock(&hdmi_ctrl->mutex);
-
- mod_timer(&hdmi_ctrl->hpd_state_timer, jiffies + HZ/2);
-
- DEV_DBG("%s: HPD<Ctrl=%04x, State=%04x>\n", __func__, hpd_int_ctrl,
- hpd_int_status);
+ hdmi_ctrl->hpd_state =
+ (DSS_REG_R(io, HDMI_HPD_INT_STATUS) & BIT(1)) >> 1;
+ if (hdmi_ctrl->hpd_state) {
+ hdmi_tx_read_sink_info(hdmi_ctrl);
+ DEV_INFO("HDMI HPD: sense CONNECTED: send ONLINE\n");
+ kobject_uevent(hdmi_ctrl->kobj, KOBJ_ONLINE);
+ switch_set_state(&hdmi_ctrl->sdev, 1);
+ DEV_INFO("%s: Hdmi state switch to %d\n", __func__,
+ hdmi_ctrl->sdev.state);
+ } else {
+ DEV_INFO("HDMI HPD: sense DISCONNECTED: send OFFLINE\n");
+ kobject_uevent(hdmi_ctrl->kobj, KOBJ_OFFLINE);
+ switch_set_state(&hdmi_ctrl->sdev, 0);
+ DEV_INFO("%s: Hdmi state switch to %d\n", __func__,
+ hdmi_ctrl->sdev.state);
+ }
} /* hdmi_tx_hpd_int_work */
static int hdmi_tx_check_capability(struct dss_io_data *io)
@@ -1009,17 +936,6 @@
DSS_REG_W(io, HDMI_GEN_PKT_CTRL, packet_control);
} /* hdmi_tx_set_spd_infoframe */
-/* todo: revisit when new HPD debouncing logic is avialble */
-static void hdmi_tx_hpd_state_timer(unsigned long data)
-{
- struct hdmi_tx_ctrl *hdmi_ctrl = (struct hdmi_tx_ctrl *)data;
-
- if (hdmi_ctrl)
- queue_work(hdmi_ctrl->workq, &hdmi_ctrl->hpd_state_work);
- else
- DEV_ERR("%s: invalid input\n", __func__);
-} /* hdmi_tx_hpd_state_timer */
-
static void hdmi_tx_set_mode(struct hdmi_tx_ctrl *hdmi_ctrl, u32 power_on)
{
u32 reg_val = 0;
@@ -1560,7 +1476,8 @@
}
DSS_REG_W(io, HDMI_INFOFRAME_CTRL0, audio_info_ctrl_reg);
- dss_reg_dump(io->base, io->len, "HDMI-AUDIO-ON: ", REG_DUMP);
+ dss_reg_dump(io->base, io->len,
+ enabled ? "HDMI-AUDIO-ON: " : "HDMI-AUDIO-OFF: ", REG_DUMP);
return 0;
} /* hdmi_tx_audio_info_setup */
@@ -1603,8 +1520,7 @@
static void hdmi_tx_audio_off(struct hdmi_tx_ctrl *hdmi_ctrl)
{
- int i;
- u32 audio_pkt_ctrl, audio_cfg;
+ u32 i, status, max_reads, timeout_us, timeout_sec = 15;
struct dss_io_data *io = NULL;
if (!hdmi_ctrl) {
@@ -1618,15 +1534,26 @@
return;
}
- /* Number of wait iterations */
- i = 10;
- do {
- audio_pkt_ctrl = DSS_REG_R_ND(io, HDMI_AUDIO_PKT_CTRL);
- audio_cfg = DSS_REG_R_ND(io, HDMI_AUDIO_CFG);
- DEV_DBG("%s: i=%d, AUDIO PACKET=%08x, AUDIO CFG=%08x",
- __func__, i, audio_pkt_ctrl, audio_cfg);
- msleep(20);
- } while (((audio_pkt_ctrl & BIT(0)) || (audio_cfg & BIT(0))) && i--);
+ /* Check if audio engine is turned off by QDSP or not */
+ /* send off notification after every 1 sec for 15 seconds */
+ for (i = 0; i < timeout_sec; i++) {
+ max_reads = 500;
+ timeout_us = 1000 * 2;
+
+ if (readl_poll_timeout_noirq((io->base + HDMI_AUDIO_CFG),
+ status, ((status & BIT(0)) == 0),
+ max_reads, timeout_us)) {
+
+ DEV_ERR("%s: audio still on after %d sec. try again\n",
+ __func__, i+1);
+
+ switch_set_state(&hdmi_ctrl->audio_sdev, 0);
+ continue;
+ }
+ break;
+ }
+ if (i == timeout_sec)
+ DEV_ERR("%s: Error: cannot turn off audio engine\n", __func__);
if (hdmi_tx_audio_info_setup(hdmi_ctrl, false, 0, 0, 0, false))
DEV_ERR("%s: hdmi_tx_audio_info_setup failed.\n", __func__);
@@ -1678,9 +1605,6 @@
/* todo: CONFIG_FB_MSM_HDMI_3D */
hdmi_tx_set_spd_infoframe(hdmi_ctrl);
- /* Set IRQ for HPD */
- DSS_REG_W(io, HDMI_HPD_INT_CTRL, 4 | (hdmi_ctrl->hpd_state ? 0 : 2));
-
/* todo: HDCP/CEC */
DEV_INFO("%s: HDMI Core: Initialized\n", __func__);
@@ -1688,17 +1612,51 @@
return rc;
} /* hdmi_tx_start */
-static int hdmi_tx_power_off(struct mdss_panel_data *panel_data)
+static void hdmi_tx_hpd_polarity_setup(struct hdmi_tx_ctrl *hdmi_ctrl,
+ bool polarity)
{
- struct hdmi_tx_ctrl *hdmi_ctrl =
- hdmi_tx_get_drvdata_from_panel_data(panel_data);
+ struct dss_io_data *io = NULL;
if (!hdmi_ctrl) {
DEV_ERR("%s: invalid input\n", __func__);
- return -EINVAL;
+ return;
+ }
+ io = &hdmi_ctrl->pdata.io[HDMI_TX_CORE_IO];
+ if (!io->base) {
+ DEV_ERR("%s: core io is not initialized\n", __func__);
+ return;
}
- DEV_INFO("%s: HDMI Core: OFF\n", __func__);
+ if (polarity)
+ DSS_REG_W(io, HDMI_HPD_INT_CTRL, BIT(2) | BIT(1));
+ else
+ DSS_REG_W(io, HDMI_HPD_INT_CTRL, BIT(2));
+
+ if ((DSS_REG_R(io, HDMI_HPD_INT_STATUS) & BIT(1)) == polarity) {
+ u32 reg_val = DSS_REG_R(io, HDMI_HPD_CTRL);
+
+ /* Toggle HPD circuit to trigger HPD sense */
+ DSS_REG_W(io, HDMI_HPD_CTRL, reg_val & ~BIT(28));
+ DSS_REG_W(io, HDMI_HPD_CTRL, reg_val | BIT(28));
+ }
+} /* hdmi_tx_hpd_polarity_setup */
+
+static void hdmi_tx_power_off_work(struct work_struct *work)
+{
+ struct hdmi_tx_ctrl *hdmi_ctrl = NULL;
+ struct dss_io_data *io = NULL;
+
+ hdmi_ctrl = container_of(work, struct hdmi_tx_ctrl, power_off_work);
+ if (!hdmi_ctrl) {
+ DEV_DBG("%s: invalid input\n", __func__);
+ return;
+ }
+
+ io = &hdmi_ctrl->pdata.io[HDMI_TX_CORE_IO];
+ if (!io->base) {
+ DEV_ERR("%s: Core io is not initialized\n", __func__);
+ return;
+ }
if (!hdmi_tx_is_dvi_mode(hdmi_ctrl)) {
switch_set_state(&hdmi_ctrl->audio_sdev, 0);
@@ -1709,9 +1667,35 @@
}
hdmi_tx_powerdown_phy(hdmi_ctrl);
- hdmi_ctrl->panel_power_on = false;
hdmi_tx_core_off(hdmi_ctrl);
+ mutex_lock(&hdmi_ctrl->mutex);
+ hdmi_ctrl->panel_power_on = false;
+ mutex_unlock(&hdmi_ctrl->mutex);
+
+ hdmi_tx_hpd_polarity_setup(hdmi_ctrl, HPD_CONNECT_POLARITY);
+
+ DEV_INFO("%s: HDMI Core: OFF\n", __func__);
+} /* hdmi_tx_power_off_work */
+
+static int hdmi_tx_power_off(struct mdss_panel_data *panel_data)
+{
+ struct hdmi_tx_ctrl *hdmi_ctrl =
+ hdmi_tx_get_drvdata_from_panel_data(panel_data);
+
+ if (!hdmi_ctrl || !hdmi_ctrl->panel_power_on) {
+ DEV_ERR("%s: invalid input\n", __func__);
+ return -EINVAL;
+ }
+
+ /*
+ * Queue work item to handle power down sequence.
+ * This is needed since we need to wait for the audio engine
+ * to shutdown first before we shutdown the HDMI core.
+ */
+ DEV_DBG("%s: Queuing work to power off HDMI core\n", __func__);
+ queue_work(hdmi_ctrl->workq, &hdmi_ctrl->power_off_work);
+
return 0;
} /* hdmi_tx_power_off */
@@ -1732,6 +1716,15 @@
return -EINVAL;
}
+ if (!hdmi_ctrl->hpd_initialized) {
+ DEV_ERR("%s: HDMI on is not possible w/o cable detection.\n",
+ __func__);
+ return -EPERM;
+ }
+
+ /* If a power down is already underway, wait for it to finish */
+ flush_work_sync(&hdmi_ctrl->power_off_work);
+
DEV_INFO("power: ON (%dx%d %ld)\n", hdmi_ctrl->xres, hdmi_ctrl->yres,
hdmi_ctrl->pixel_clk);
@@ -1772,6 +1765,8 @@
hdmi_tx_is_controller_on(hdmi_ctrl) ? "ON" : "OFF" ,
hdmi_tx_is_dvi_mode(hdmi_ctrl) ? "ON" : "OFF");
+ hdmi_tx_hpd_polarity_setup(hdmi_ctrl, HPD_DISCONNECT_POLARITY);
+
return 0;
} /* hdmi_tx_power_on */
@@ -1789,8 +1784,6 @@
return;
}
- DEV_DBG("%s: (timer, 5V, IRQ off)\n", __func__);
- del_timer_sync(&hdmi_ctrl->hpd_state_timer);
mdss_disable_irq(&hdmi_tx_hw);
hdmi_tx_set_mode(hdmi_ctrl, false);
@@ -1838,28 +1831,18 @@
DSS_REG_W(io, HDMI_USEC_REFTIMER, 0x0001001B);
- /* set timeout to 4.1ms (max) for hardware debounce */
- reg_val = DSS_REG_R(io, HDMI_HPD_CTRL) | 0x1FFF;
-
- /* Toggle HPD circuit to trigger HPD sense */
- DSS_REG_W(io, HDMI_HPD_CTRL,
- ~(1 << 28) & reg_val);
- DSS_REG_W(io, HDMI_HPD_CTRL, (1 << 28) | reg_val);
+ mdss_enable_irq(&hdmi_tx_hw);
hdmi_ctrl->hpd_initialized = true;
- /* Check HPD State */
- mdss_enable_irq(&hdmi_tx_hw);
- }
+ /* set timeout to 4.1ms (max) for hardware debounce */
+ reg_val = DSS_REG_R(io, HDMI_HPD_CTRL) | 0x1FFF;
- /* Set HPD state machine: ensure at least 2 readouts */
- mutex_lock(&hdmi_ctrl->mutex);
- hdmi_ctrl->hpd_stable = 0;
- hdmi_ctrl->hpd_prev_state = true;
- hdmi_ctrl->hpd_state = false;
- hdmi_ctrl->hpd_cable_chg_detected = true;
- mutex_unlock(&hdmi_ctrl->mutex);
- mod_timer(&hdmi_ctrl->hpd_state_timer, jiffies + HZ/2);
+ /* Turn on HPD HW circuit */
+ DSS_REG_W(io, HDMI_HPD_CTRL, reg_val | BIT(28));
+
+ hdmi_tx_hpd_polarity_setup(hdmi_ctrl, HPD_CONNECT_POLARITY);
+ }
return rc;
} /* hdmi_tx_hpd_on */
@@ -1905,10 +1888,10 @@
if (DSS_REG_R(io, HDMI_HPD_INT_STATUS) & BIT(0)) {
/*
- * Turn off HPD irq and clear all interrupts,
- * worker will turn IRQ back on
+ * Ack the current hpd interrupt and stop listening to
+ * new hpd interrupt.
*/
- DSS_REG_W(io, HDMI_HPD_INT_CTRL, ~BIT(2) | BIT(0));
+ DSS_REG_W(io, HDMI_HPD_INT_CTRL, BIT(0));
queue_work(hdmi_ctrl->workq, &hdmi_ctrl->hpd_int_work);
}
@@ -1930,7 +1913,6 @@
switch_dev_unregister(&hdmi_ctrl->audio_sdev);
switch_dev_unregister(&hdmi_ctrl->sdev);
- del_timer_sync(&hdmi_ctrl->hpd_state_timer);
if (hdmi_ctrl->workq)
destroy_workqueue(hdmi_ctrl->workq);
mutex_destroy(&hdmi_ctrl->mutex);
@@ -1971,12 +1953,10 @@
hdmi_ctrl->ddc_ctrl.io = &pdata->io[HDMI_TX_CORE_IO];
init_completion(&hdmi_ctrl->ddc_ctrl.ddc_sw_done);
- INIT_WORK(&hdmi_ctrl->hpd_state_work, hdmi_tx_hpd_state_work);
+ hdmi_ctrl->hpd_state = false;
INIT_WORK(&hdmi_ctrl->hpd_int_work, hdmi_tx_hpd_int_work);
- init_timer(&hdmi_ctrl->hpd_state_timer);
- hdmi_ctrl->hpd_state_timer.function = hdmi_tx_hpd_state_timer;
- hdmi_ctrl->hpd_state_timer.data = (u32)hdmi_ctrl;
- hdmi_ctrl->hpd_state_timer.expires = 0xffffffffL;
+
+ INIT_WORK(&hdmi_ctrl->power_off_work, hdmi_tx_power_off_work);
hdmi_ctrl->audio_sample_rate = HDMI_SAMPLE_RATE_48KHZ;
@@ -1984,7 +1964,7 @@
if (switch_dev_register(&hdmi_ctrl->sdev) < 0) {
DEV_ERR("%s: Hdmi switch registration failed\n", __func__);
rc = -ENODEV;
- goto fail_switch_dev;
+ goto fail_create_workq;
}
hdmi_ctrl->audio_sdev.name = "hdmi_audio";
@@ -1999,8 +1979,6 @@
fail_audio_switch_dev:
switch_dev_unregister(&hdmi_ctrl->sdev);
-fail_switch_dev:
- del_timer_sync(&hdmi_ctrl->hpd_state_timer);
fail_create_workq:
if (hdmi_ctrl->workq)
destroy_workqueue(hdmi_ctrl->workq);
diff --git a/drivers/video/msm/mdss/mdss_hdmi_tx.h b/drivers/video/msm/mdss/mdss_hdmi_tx.h
index 437f681..3e9fd3c 100644
--- a/drivers/video/msm/mdss/mdss_hdmi_tx.h
+++ b/drivers/video/msm/mdss/mdss_hdmi_tx.h
@@ -53,14 +53,11 @@
u32 panel_power_on;
u32 hpd_initialized;
- int hpd_stable;
- u32 hpd_prev_state;
- u32 hpd_cable_chg_detected;
u32 hpd_state;
u32 hpd_feature_on;
- struct work_struct hpd_state_work;
struct work_struct hpd_int_work;
- struct timer_list hpd_state_timer;
+
+ struct work_struct power_off_work;
unsigned long pixel_clk;
u32 xres;
diff --git a/drivers/video/msm/mdss/mdss_io_util.c b/drivers/video/msm/mdss/mdss_io_util.c
index 5778525..0a14056 100644
--- a/drivers/video/msm/mdss/mdss_io_util.c
+++ b/drivers/video/msm/mdss/mdss_io_util.c
@@ -136,7 +136,7 @@
curr_vreg = &in_vreg[i];
curr_vreg->vreg = regulator_get(dev,
curr_vreg->vreg_name);
- rc = IS_ERR(curr_vreg->vreg);
+ rc = PTR_RET(curr_vreg->vreg);
if (rc) {
DEV_ERR("%pS->%s: %s get failed. rc=%d\n",
__builtin_return_address(0), __func__,
@@ -215,7 +215,7 @@
int i = 0, rc = 0;
if (enable) {
for (i = 0; i < num_vreg; i++) {
- rc = IS_ERR(in_vreg[i].vreg);
+ rc = PTR_RET(in_vreg[i].vreg);
if (rc) {
DEV_ERR("%pS->%s: %s regulator error. rc=%d\n",
__builtin_return_address(0), __func__,
@@ -286,7 +286,7 @@
for (i = 0; i < num_clk; i++) {
clk_arry[i].clk = clk_get(dev, clk_arry[i].clk_name);
- rc = IS_ERR(clk_arry[i].clk);
+ rc = PTR_RET(clk_arry[i].clk);
if (rc) {
DEV_ERR("%pS->%s: '%s' get failed. rc=%d\n",
__builtin_return_address(0), __func__,
diff --git a/drivers/video/msm/mdss/mdss_mdp.c b/drivers/video/msm/mdss/mdss_mdp.c
index c2d107a..11b0831 100644
--- a/drivers/video/msm/mdss/mdss_mdp.c
+++ b/drivers/video/msm/mdss/mdss_mdp.c
@@ -226,7 +226,7 @@
mdss_res->irq_mask &= ~ndx_bit;
if (mdss_res->irq_mask == 0) {
mdss_res->irq_ena = false;
- disable_irq(mdss_res->irq);
+ disable_irq_nosync(mdss_res->irq);
}
}
spin_unlock_irqrestore(&mdss_lock, irq_flags);
@@ -292,7 +292,7 @@
msm_bus_scale_unregister_client(mdata->bus_hdl);
}
-int mdss_mdp_bus_scale_set_quota(u32 ab_quota, u32 ib_quota)
+int mdss_mdp_bus_scale_set_quota(u64 ab_quota, u64 ib_quota)
{
static int current_bus_idx;
int bus_idx;
@@ -310,6 +310,10 @@
bus_idx = (current_bus_idx % (num_cases - 1)) + 1;
+ /* aligning to avoid performing updates for small changes */
+ ab_quota = ALIGN(ab_quota, SZ_64M);
+ ib_quota = ALIGN(ib_quota, SZ_64M);
+
vect = mdp_bus_scale_table.usecase[current_bus_idx].vectors;
if ((ab_quota == vect->ab) && (ib_quota == vect->ib)) {
pr_debug("skip bus scaling, no change in vectors\n");
diff --git a/drivers/video/msm/mdss/mdss_mdp.h b/drivers/video/msm/mdss/mdss_mdp.h
index 33028cb..808babb 100644
--- a/drivers/video/msm/mdss/mdss_mdp.h
+++ b/drivers/video/msm/mdss/mdss_mdp.h
@@ -276,7 +276,7 @@
int mdss_mdp_set_intr_callback(u32 intr_type, u32 intf_num,
void (*fnc_ptr)(void *), void *arg);
-int mdss_mdp_bus_scale_set_quota(u32 ab_quota, u32 ib_quota);
+int mdss_mdp_bus_scale_set_quota(u64 ab_quota, u64 ib_quota);
void mdss_mdp_set_clk_rate(unsigned long min_clk_rate);
unsigned long mdss_mdp_get_clk_rate(u32 clk_idx);
int mdss_mdp_vsync_clk_enable(int enable);
diff --git a/drivers/video/msm/mdss/mdss_mdp_ctl.c b/drivers/video/msm/mdss/mdss_mdp_ctl.c
index 73b8c60..3db13f5 100644
--- a/drivers/video/msm/mdss/mdss_mdp_ctl.c
+++ b/drivers/video/msm/mdss/mdss_mdp_ctl.c
@@ -20,8 +20,10 @@
#include "mdss_fb.h"
#include "mdss_mdp.h"
+/* truncate at 1k */
+#define MDSS_MDP_BUS_FACTOR_SHIFT 10
/* 1.5 bus fudge factor */
-#define MDSS_MDP_BUS_FUDGE_FACTOR(val) ALIGN((((val) * 3) / 2), SZ_16M)
+#define MDSS_MDP_BUS_FUDGE_FACTOR(val) (((val) / 2) * 3)
/* 1.25 clock fudge factor */
#define MDSS_MDP_CLK_FUDGE_FACTOR(val) (((val) * 5) / 4)
@@ -44,7 +46,7 @@
struct mdss_mdp_ctl *ctl;
int cnum;
unsigned long clk_rate = 0;
- u32 bus_ab_quota = 0, bus_ib_quota = 0;
+ u64 bus_ab_quota = 0, bus_ib_quota = 0;
if (!flags) {
pr_err("nothing to update\n");
@@ -63,7 +65,9 @@
}
}
if (flags & MDSS_MDP_PERF_UPDATE_BUS) {
+ bus_ab_quota = bus_ab_quota << MDSS_MDP_BUS_FACTOR_SHIFT;
bus_ib_quota = MDSS_MDP_BUS_FUDGE_FACTOR(bus_ib_quota);
+ bus_ib_quota <<= MDSS_MDP_BUS_FACTOR_SHIFT;
mdss_mdp_bus_scale_set_quota(bus_ab_quota, bus_ib_quota);
}
if (flags & MDSS_MDP_PERF_UPDATE_CLK) {
@@ -116,6 +120,7 @@
if (is_writeback) {
/* perf for bus writeback */
*bus_ab_quota = fps * mixer->width * mixer->height * 3;
+ *bus_ab_quota >>= MDSS_MDP_BUS_FACTOR_SHIFT;
*bus_ib_quota = *bus_ab_quota;
}
}
@@ -148,13 +153,13 @@
if (mixer->rotator_mode)
rate /= 4; /* block mode fetch at 4 pix/clk */
- *bus_ab_quota += quota;
- *bus_ib_quota += ib_quota;
- if (rate > *clk_rate)
- *clk_rate = rate;
-
pr_debug("mixer=%d pnum=%d clk_rate=%u bus ab=%u ib=%u\n",
mixer->num, pipe->num, rate, quota, ib_quota);
+
+ *bus_ab_quota += quota >> MDSS_MDP_BUS_FACTOR_SHIFT;
+ *bus_ib_quota += ib_quota >> MDSS_MDP_BUS_FACTOR_SHIFT;
+ if (rate > *clk_rate)
+ *clk_rate = rate;
}
pr_debug("final mixer=%d clk_rate=%u bus ab=%u ib=%u\n", mixer->num,
@@ -564,6 +569,17 @@
goto start_fail;
}
+ /* request bus bandwidth for panel commands */
+ ctl->clk_rate = MDP_CLK_DEFAULT_RATE;
+ ctl->bus_ib_quota = SZ_1M;
+ mdss_mdp_ctl_perf_commit(MDSS_MDP_PERF_UPDATE_ALL);
+
+ ret = pdata->on(pdata);
+ if (ret) {
+ pr_err("panel power on failed ctl=%d\n", ctl->num);
+ goto panel_fail;
+ }
+
pr_debug("ctl_num=%d\n", ctl->num);
mixer = ctl->mixer_left;
@@ -591,17 +607,16 @@
MDSS_MDP_REG_WRITE(off + MDSS_MDP_REG_LM_OUT_SIZE, outsize);
mdss_mdp_ctl_write(ctl, MDSS_MDP_REG_CTL_PACK_3D, 0);
}
-
- /* request bus bandwidth for panel commands */
- ctl->clk_rate = MDP_CLK_DEFAULT_RATE;
- ctl->bus_ib_quota = SZ_1M;
- mdss_mdp_ctl_perf_commit(MDSS_MDP_PERF_UPDATE_ALL);
-
- ret = pdata->on(pdata);
-
+panel_fail:
+ if (ret && ctl->stop_fnc)
+ ctl->stop_fnc(ctl);
start_fail:
mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF, false);
mutex_unlock(&ctl->lock);
+ if (ret) {
+ mdss_mdp_ctl_destroy(mfd);
+ mdss_mdp_ctl_perf_commit(MDSS_MDP_PERF_UPDATE_ALL);
+ }
return ret;
}
diff --git a/drivers/video/msm/mipi_dsi.c b/drivers/video/msm/mipi_dsi.c
index a58010e..cc19555 100644
--- a/drivers/video/msm/mipi_dsi.c
+++ b/drivers/video/msm/mipi_dsi.c
@@ -446,9 +446,6 @@
if (pdev_list_cnt >= MSM_FB_MAX_DEV_LIST)
return -ENOMEM;
- if (!mfd->cont_splash_done)
- cont_splash_clk_ctrl(1);
-
mdp_dev = platform_device_alloc("mdp", pdev->id);
if (!mdp_dev)
return -ENOMEM;
@@ -584,6 +581,9 @@
pdev_list[pdev_list_cnt++] = pdev;
+ if (!mfd->cont_splash_done)
+ cont_splash_clk_ctrl(1);
+
return 0;
mipi_dsi_probe_err:
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index f581c8f..37b1fdc 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -486,7 +486,7 @@
__attribute__((section("__trace_printk_fmt"))) = \
__builtin_constant_p(fmt) ? fmt : NULL; \
\
- __trace_bprintk(_THIS_IP_, trace_printk_fmt, ##args); \
+ __trace_printk(_THIS_IP_, trace_printk_fmt, ##args); \
} else \
__trace_printk(_THIS_IP_, fmt, ##args); \
} while (0)
diff --git a/include/linux/mfd/pm8xxx/pm8921-charger.h b/include/linux/mfd/pm8xxx/pm8921-charger.h
index 130fb54..4ad55f4 100644
--- a/include/linux/mfd/pm8xxx/pm8921-charger.h
+++ b/include/linux/mfd/pm8xxx/pm8921-charger.h
@@ -58,7 +58,6 @@
/**
* struct pm8921_charger_platform_data -
- * @safety_time: max charging time in minutes incl. fast and trkl
* valid range 4 to 512 min. PON default 120 min
* @ttrkl_time: max trckl charging time in minutes
* valid range 1 to 64 mins. PON default 15 min
@@ -70,6 +69,9 @@
* trickle to fast. This is also the minimum voltage the
* system operates at
* @uvd_thresh_voltage: the USB falling UVD threshold (mV) (PM8917 only)
+ * @safe_current_ma: The upper limit of current allowed to be pushed in
+ * battery. This ends up writing in a one time
+ * programmable register.
* @resume_voltage_delta: the (mV) drop to wait for before resume charging
* after the battery has been fully charged
* @resume_charge_percent: the % SOC the charger will drop to after the
@@ -127,12 +129,12 @@
*/
struct pm8921_charger_platform_data {
struct pm8xxx_charger_core_data charger_cdata;
- unsigned int safety_time;
unsigned int ttrkl_time;
unsigned int update_time;
unsigned int max_voltage;
unsigned int min_voltage;
unsigned int uvd_thresh_voltage;
+ unsigned int safe_current_ma;
unsigned int alarm_low_mv;
unsigned int alarm_high_mv;
unsigned int resume_voltage_delta;
diff --git a/include/linux/wcnss_wlan.h b/include/linux/wcnss_wlan.h
index 7a194ca..6d2eee4 100644
--- a/include/linux/wcnss_wlan.h
+++ b/include/linux/wcnss_wlan.h
@@ -31,6 +31,8 @@
};
#define WCNSS_WLAN_IRQ_INVALID -1
+#define HAVE_WCNSS_SUSPEND_RESUME_NOTIFY 1
+#define HAVE_WCNSS_RESET_INTR 1
struct device *wcnss_wlan_get_device(void);
struct resource *wcnss_wlan_get_memory_map(struct device *dev);
@@ -59,6 +61,8 @@
void *wcnss_prealloc_get(unsigned int size);
int wcnss_prealloc_put(void *ptr);
void wcnss_reset_intr(void);
+void wcnss_suspend_notify(void);
+void wcnss_resume_notify(void);
#define wcnss_wlan_get_drvdata(dev) dev_get_drvdata(dev)
#define wcnss_wlan_set_drvdata(dev, data) dev_set_drvdata((dev), (data))
diff --git a/include/media/vcap_v4l2.h b/include/media/vcap_v4l2.h
index 55d67bf..2d3b5c5 100644
--- a/include/media/vcap_v4l2.h
+++ b/include/media/vcap_v4l2.h
@@ -254,6 +254,8 @@
uint32_t hold_vc;
uint32_t hold_vp;
+ /* Mutex ensures only one thread is dq buffer or turning streamoff */
+ struct mutex mutex;
spinlock_t cap_slock;
bool streaming;
diff --git a/include/sound/cs8427.h b/include/sound/cs8427.h
index 2004ec3..a1e988d 100644
--- a/include/sound/cs8427.h
+++ b/include/sound/cs8427.h
@@ -209,7 +209,8 @@
int irq_base;
int num_irqs;
int reset_gpio;
- int (*enable) (int enable);
+ int (*enable) (int enable, int gpio);
+ int ls_gpio;
};
struct snd_pcm_substream;
diff --git a/sound/soc/codecs/cs8427.c b/sound/soc/codecs/cs8427.c
index 23870a4..6e08742 100644
--- a/sound/soc/codecs/cs8427.c
+++ b/sound/soc/codecs/cs8427.c
@@ -110,7 +110,7 @@
* with CS8427 chip
*/
if (pdata->enable) {
- err = pdata->enable(1);
+ err = pdata->enable(1, pdata->ls_gpio);
if (err < 0) {
dev_err(&chip->client->dev,
"failed to enable the level shifter\n");
@@ -124,7 +124,7 @@
* with CS8427 chip
*/
if (pdata->enable) {
- err = pdata->enable(0);
+ err = pdata->enable(0, pdata->ls_gpio);
if (err < 0) {
dev_err(&chip->client->dev,
"failed to disable the level shifter\n");
@@ -192,7 +192,7 @@
* with CS8427 chip
*/
if (pdata->enable) {
- err = pdata->enable(1);
+ err = pdata->enable(1, pdata->ls_gpio);
if (err < 0) {
dev_err(&chip->client->dev,
"failed to enable the level shifter\n");
@@ -207,7 +207,7 @@
* with CS8427 chip
*/
if (pdata->enable) {
- err = pdata->enable(0);
+ err = pdata->enable(0, pdata->ls_gpio);
if (err < 0) {
dev_err(&chip->client->dev,
"failed to disable the level shifter\n");
@@ -239,7 +239,7 @@
* with CS8427 chip
*/
if (pdata->enable) {
- err = pdata->enable(1);
+ err = pdata->enable(1, pdata->ls_gpio);
if (err < 0) {
dev_err(&chip->client->dev,
"failed to enable the level shifter\n");
@@ -262,7 +262,7 @@
* with CS8427 chip
*/
if (pdata->enable) {
- err = pdata->enable(0);
+ err = pdata->enable(0, pdata->ls_gpio);
if (err < 0) {
dev_err(&chip->client->dev,
"failed to disable the level shifter\n");
@@ -734,6 +734,16 @@
struct cs8427_platform_data *pdata = chip->client->dev.platform_data;
int ret = 0;
+ if (pdata->enable) {
+ ret = gpio_request(pdata->ls_gpio, "cs8427 ls");
+ if (ret < 0) {
+ dev_err(&chip->client->dev,
+ "failed to request the gpio %d\n",
+ pdata->reset_gpio);
+ return ret;
+ }
+ }
+
ret = gpio_request(pdata->reset_gpio, "cs8427 reset");
if (ret < 0) {
dev_err(&chip->client->dev,
@@ -928,8 +938,10 @@
}
pdata = chip->client->dev.platform_data;
gpio_free(pdata->reset_gpio);
- if (pdata->enable)
- pdata->enable(0);
+ if (pdata->enable) {
+ pdata->enable(0, pdata->ls_gpio);
+ gpio_free(pdata->ls_gpio);
+ }
kfree(chip);
return 0;
}
diff --git a/sound/soc/msm/msm-compr-q6.c b/sound/soc/msm/msm-compr-q6.c
index 127a2c3..6ac4562 100644
--- a/sound/soc/msm/msm-compr-q6.c
+++ b/sound/soc/msm/msm-compr-q6.c
@@ -875,6 +875,7 @@
pr_debug("%s\n", __func__);
atomic_set(&prtd->pending_buffer, 0);
q6asm_cmd(prtd->audio_client, CMD_CLOSE);
+ compressed_audio.prtd = NULL;
q6asm_audio_client_buf_free_contiguous(dir,
prtd->audio_client);
if (compr->info.codec_param.codec.id ==
diff --git a/sound/soc/msm/qdsp6/q6asm.c b/sound/soc/msm/qdsp6/q6asm.c
index 7b52956..cde5b02 100644
--- a/sound/soc/msm/qdsp6/q6asm.c
+++ b/sound/soc/msm/qdsp6/q6asm.c
@@ -486,6 +486,7 @@
struct audio_buffer *buf;
#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
int len;
+ unsigned int bufsz_4k_aligned;
#endif
if (!(ac) || ((dir != IN) && (dir != OUT)))
@@ -526,8 +527,15 @@
mutex_unlock(&ac->cmd_lock);
goto fail;
}
+ bufsz_4k_aligned = (bufsz + 4095) &
+ (~4095);
+ pr_debug("%s: bufsz_4k_aligned %d"\
+ "bufsz = %d\n",
+ __func__, bufsz_4k_aligned,
+ bufsz);
buf[cnt].handle = ion_alloc
- (buf[cnt].client, bufsz, SZ_4K,
+ (buf[cnt].client,
+ bufsz_4k_aligned, SZ_4K,
(0x1 << ION_AUDIO_HEAP_ID), 0);
if (IS_ERR_OR_NULL((void *)
buf[cnt].handle)) {
@@ -757,6 +765,7 @@
{
uint32_t token;
uint32_t *payload = data->payload;
+ struct audio_client *ac;
if (data->opcode == RESET_EVENTS) {
pr_debug("%s: Reset event is received: %d %d apr[%p]\n",
@@ -776,6 +785,8 @@
if (data->opcode == APR_BASIC_RSP_RESULT) {
token = data->token;
+ ac = (struct audio_client *)data->token;
+ pr_debug("%s: audio_client addr %x\n", __func__, (uint32_t)ac);
switch (payload[0]) {
case ASM_SESSION_CMD_MEMORY_MAP:
case ASM_SESSION_CMD_MEMORY_UNMAP:
@@ -783,9 +794,15 @@
case ASM_SESSION_CMD_MEMORY_UNMAP_REGIONS:
pr_debug("%s:command[0x%x]success [0x%x]\n",
__func__, payload[0], payload[1]);
- if (atomic_read(&this_mmap.cmd_state)) {
- atomic_set(&this_mmap.cmd_state, 0);
- wake_up(&this_mmap.cmd_wait);
+ if (atomic_read(&ac->cmd_state)) {
+ atomic_set(&ac->cmd_state, 0);
+ if (payload[1] != ADSP_EOK) {
+ pr_err("payload[1]:%d error case\n",
+ payload[1]);
+ atomic_set(&ac->cmd_response, 1);
+ } else
+ atomic_set(&ac->cmd_response, 0);
+ wake_up(&ac->cmd_wait);
}
break;
default:
@@ -1327,14 +1344,16 @@
static void q6asm_add_mmaphdr(struct apr_hdr *hdr, uint32_t pkt_size,
uint32_t cmd_flg)
{
+ struct audio_client *ac;
pr_debug("%s:pkt size=%d cmd_flg=%d\n", __func__, pkt_size, cmd_flg);
+ ac = (struct audio_client *)hdr->token;
+ pr_debug("%s: audio_client = %x\n", __func__, (uint32_t)ac);
hdr->hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, \
APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
hdr->src_port = 0;
hdr->dest_port = 0;
if (cmd_flg) {
- hdr->token = 0;
- atomic_set(&this_mmap.cmd_state, 1);
+ atomic_set(&ac->cmd_state, 1);
}
hdr->pkt_size = pkt_size;
return;
@@ -2813,6 +2832,8 @@
mem_map.mempool_id = 0; /* EBI */
mem_map.reserved = 0;
+ pr_debug("%s: audio_client addr %x\n", __func__, (uint32_t)ac);
+ mem_map.hdr.token = (uint32_t)ac;
q6asm_add_mmaphdr(&mem_map.hdr,
sizeof(struct asm_stream_cmd_memory_map), TRUE);
@@ -2827,14 +2848,20 @@
goto fail_cmd;
}
- rc = wait_event_timeout(this_mmap.cmd_wait,
- (atomic_read(&this_mmap.cmd_state) == 0), 5 * HZ);
+ rc = wait_event_timeout(ac->cmd_wait,
+ (atomic_read(&ac->cmd_state) == 0), 5*HZ);
if (!rc) {
pr_err("timeout. waited for memory_map\n");
rc = -EINVAL;
goto fail_cmd;
}
+ if (atomic_read(&ac->cmd_response)) {
+ pr_err("%s: ASM_SESSION_CMD_MEMORY_MAP cmd failed\n", __func__);
+ rc = -EINVAL;
+ goto fail_cmd;
+ }
rc = 0;
+
fail_cmd:
return rc;
}
@@ -2850,6 +2877,8 @@
}
pr_debug("%s: Session[%d]\n", __func__, ac->session);
+ pr_debug("%s: audio_client addr %x\n", __func__, (uint32_t)ac);
+ mem_unmap.hdr.token = (uint32_t)ac;
q6asm_add_mmaphdr(&mem_unmap.hdr,
sizeof(struct asm_stream_cmd_memory_unmap), TRUE);
mem_unmap.hdr.opcode = ASM_SESSION_CMD_MEMORY_UNMAP;
@@ -2863,14 +2892,21 @@
goto fail_cmd;
}
- rc = wait_event_timeout(this_mmap.cmd_wait,
- (atomic_read(&this_mmap.cmd_state) == 0), 5 * HZ);
+ rc = wait_event_timeout(ac->cmd_wait,
+ (atomic_read(&ac->cmd_state) == 0), 5*HZ);
if (!rc) {
- pr_err("timeout. waited for memory_map\n");
+ pr_err("timeout. waited for memory_unmap\n");
+ rc = -EINVAL;
+ goto fail_cmd;
+ }
+ if (atomic_read(&ac->cmd_response)) {
+ pr_err("%s: ASM_SESSION_CMD_MEMORY_UNMAP cmd failed\n",
+ __func__);
rc = -EINVAL;
goto fail_cmd;
}
rc = 0;
+
fail_cmd:
return rc;
}
@@ -2959,6 +2995,8 @@
}
mmap_regions = (struct asm_stream_cmd_memory_map_regions *)
mmap_region_cmd;
+ mmap_regions->hdr.token = (uint32_t)ac;
+ pr_debug("%s: audio_client addr %x\n", __func__, (uint32_t)ac);
q6asm_add_mmaphdr(&mmap_regions->hdr, cmd_size, TRUE);
mmap_regions->hdr.opcode = ASM_SESSION_CMD_MEMORY_MAP_REGIONS;
mmap_regions->mempool_id = 0;
@@ -2984,14 +3022,21 @@
goto fail_cmd;
}
- rc = wait_event_timeout(this_mmap.cmd_wait,
- (atomic_read(&this_mmap.cmd_state) == 0), 5*HZ);
+ rc = wait_event_timeout(ac->cmd_wait,
+ (atomic_read(&ac->cmd_state) == 0), 5*HZ);
if (!rc) {
- pr_err("timeout. waited for memory_map\n");
+ pr_err("timeout. waited for map_regions\n");
+ rc = -EINVAL;
+ goto fail_cmd;
+ }
+ if (atomic_read(&ac->cmd_response)) {
+ pr_err("%s: ASM_SESSION_CMD_MEMORY_MAP_REGIONS cmd failed\n",
+ __func__);
rc = -EINVAL;
goto fail_cmd;
}
rc = 0;
+
fail_cmd:
kfree(mmap_region_cmd);
return rc;
@@ -3027,6 +3072,8 @@
}
unmap_regions = (struct asm_stream_cmd_memory_unmap_regions *)
unmap_region_cmd;
+ unmap_regions->hdr.token = (uint32_t)ac;
+ pr_debug("%s: audio_client addr %x\n", __func__, (uint32_t)ac);
q6asm_add_mmaphdr(&unmap_regions->hdr, cmd_size, TRUE);
unmap_regions->hdr.opcode = ASM_SESSION_CMD_MEMORY_UNMAP_REGIONS;
unmap_regions->nregions = bufcnt & 0x00ff;
@@ -3048,10 +3095,17 @@
goto fail_cmd;
}
- rc = wait_event_timeout(this_mmap.cmd_wait,
- (atomic_read(&this_mmap.cmd_state) == 0), 5*HZ);
+ rc = wait_event_timeout(ac->cmd_wait,
+ (atomic_read(&ac->cmd_state) == 0), 5*HZ);
if (!rc) {
- pr_err("timeout. waited for memory_unmap\n");
+ pr_err("timeout. waited for unmap_regions\n");
+ rc = -EINVAL;
+ goto fail_cmd;
+ }
+ if (atomic_read(&ac->cmd_response)) {
+ pr_err("%s: ASM_SESSION_CMD_MEMORY_UNMAP_REGIONS cmd failed\n",
+ __func__);
+ rc = -EINVAL;
goto fail_cmd;
}
rc = 0;
diff --git a/sound/soc/msm/qdsp6v2/audio_ocmem.c b/sound/soc/msm/qdsp6v2/audio_ocmem.c
index d38bcbb..9e08be3 100644
--- a/sound/soc/msm/qdsp6v2/audio_ocmem.c
+++ b/sound/soc/msm/qdsp6v2/audio_ocmem.c
@@ -30,6 +30,11 @@
#define AUDIO_OCMEM_BUF_SIZE (512 * SZ_1K)
+static int enable_ocmem_audio_voice;
+module_param(enable_ocmem_audio_voice, int,
+ S_IRUGO | S_IWUSR | S_IWGRP);
+MODULE_PARM_DESC(enable_ocmem_audio_voice, "control OCMEM usage for audio/voice");
+
enum {
OCMEM_STATE_DEFAULT = 0,
OCMEM_STATE_ALLOC = 1,
@@ -71,6 +76,7 @@
spinlock_t audio_lock;
struct workqueue_struct *audio_ocmem_workqueue;
struct workqueue_struct *voice_ocmem_workqueue;
+ bool ocmem_en;
};
static struct audio_ocmem_prv audio_ocmem_lcl;
@@ -416,21 +422,31 @@
struct voice_ocmem_workdata *workdata = NULL;
- if (audio_ocmem_lcl.voice_ocmem_workqueue == NULL) {
- pr_err("%s: voice ocmem workqueue is NULL\n", __func__);
- return -EINVAL;
+ if (enable) {
+ if (enable_ocmem_audio_voice)
+ audio_ocmem_lcl.ocmem_en = true;
+ else
+ audio_ocmem_lcl.ocmem_en = false;
}
- workdata = kzalloc(sizeof(struct voice_ocmem_workdata),
- GFP_ATOMIC);
- if (workdata == NULL) {
- pr_err("%s: mem failure\n", __func__);
- return -ENOMEM;
- }
- workdata->id = cid;
- workdata->en = enable;
+ if (audio_ocmem_lcl.ocmem_en) {
+ if (audio_ocmem_lcl.voice_ocmem_workqueue == NULL) {
+ pr_err("%s: voice ocmem workqueue is NULL\n",
+ __func__);
+ return -EINVAL;
+ }
+ workdata = kzalloc(sizeof(struct voice_ocmem_workdata),
+ GFP_ATOMIC);
+ if (workdata == NULL) {
+ pr_err("%s: mem failure\n", __func__);
+ return -ENOMEM;
+ }
+ workdata->id = cid;
+ workdata->en = enable;
- INIT_WORK(&workdata->work, voice_ocmem_process_workdata);
- queue_work(audio_ocmem_lcl.voice_ocmem_workqueue, &workdata->work);
+ INIT_WORK(&workdata->work, voice_ocmem_process_workdata);
+ queue_work(audio_ocmem_lcl.voice_ocmem_workqueue,
+ &workdata->work);
+ }
return 0;
}
@@ -510,24 +526,35 @@
{
struct audio_ocmem_workdata *workdata = NULL;
- if (audio_ocmem_lcl.audio_ocmem_workqueue == NULL) {
- pr_err("%s: audio ocmem workqueue is NULL\n", __func__);
- return -EINVAL;
+ if (enable) {
+ if (enable_ocmem_audio_voice)
+ audio_ocmem_lcl.ocmem_en = true;
+ else
+ audio_ocmem_lcl.ocmem_en = false;
}
- workdata = kzalloc(sizeof(struct audio_ocmem_workdata),
+
+ if (audio_ocmem_lcl.ocmem_en) {
+ if (audio_ocmem_lcl.audio_ocmem_workqueue == NULL) {
+ pr_err("%s: audio ocmem workqueue is NULL\n",
+ __func__);
+ return -EINVAL;
+ }
+ workdata = kzalloc(sizeof(struct audio_ocmem_workdata),
GFP_ATOMIC);
- if (workdata == NULL) {
- pr_err("%s: mem failure\n", __func__);
- return -ENOMEM;
+ if (workdata == NULL) {
+ pr_err("%s: mem failure\n", __func__);
+ return -ENOMEM;
+ }
+ workdata->id = id;
+ workdata->en = enable;
+
+ /* if previous work waiting for ocmem - signal it to exit */
+ atomic_set(&audio_ocmem_lcl.audio_exit, 1);
+
+ INIT_WORK(&workdata->work, audio_ocmem_process_workdata);
+ queue_work(audio_ocmem_lcl.audio_ocmem_workqueue,
+ &workdata->work);
}
- workdata->id = id;
- workdata->en = enable;
-
- /* if previous work waiting for ocmem - signal it to exit */
- atomic_set(&audio_ocmem_lcl.audio_exit, 1);
-
- INIT_WORK(&workdata->work, audio_ocmem_process_workdata);
- queue_work(audio_ocmem_lcl.audio_ocmem_workqueue, &workdata->work);
return 0;
}
@@ -584,6 +611,7 @@
atomic_set(&audio_ocmem_lcl.audio_state, OCMEM_STATE_DEFAULT);
atomic_set(&audio_ocmem_lcl.audio_exit, 0);
spin_lock_init(&audio_ocmem_lcl.audio_lock);
+ audio_ocmem_lcl.ocmem_en = false;
/* populate platform data */
ret = audio_ocmem_platform_data_populate(pdev);