Merge "msm: scm-pas: Fix the bus-master port id for the MSM8610"
diff --git a/arch/arm/boot/dts/msm-pm8226.dtsi b/arch/arm/boot/dts/msm-pm8226.dtsi
index 4e70dce..f702abb 100644
--- a/arch/arm/boot/dts/msm-pm8226.dtsi
+++ b/arch/arm/boot/dts/msm-pm8226.dtsi
@@ -175,6 +175,7 @@
qcom,low-ocv-correction-limit-uv = <100>;
qcom,high-ocv-correction-limit-uv = <50>;
qcom,hold-soc-est = <3>;
+ qcom,low-voltage-threshold = <3420000>;
qcom,bms-iadc@3800 {
reg = <0x3800 0x100>;
diff --git a/arch/arm/boot/dts/msm8226-camera-sensor-cdp-qrd.dtsi b/arch/arm/boot/dts/msm8226-camera-sensor-cdp.dtsi
similarity index 97%
copy from arch/arm/boot/dts/msm8226-camera-sensor-cdp-qrd.dtsi
copy to arch/arm/boot/dts/msm8226-camera-sensor-cdp.dtsi
index b7f837f..c47d48d 100644
--- a/arch/arm/boot/dts/msm8226-camera-sensor-cdp-qrd.dtsi
+++ b/arch/arm/boot/dts/msm8226-camera-sensor-cdp.dtsi
@@ -25,7 +25,7 @@
actuator0: qcom,actuator@6e {
cell-index = <3>;
- reg = <0x6c 0x0>;
+ reg = <0x6c>;
compatible = "qcom,actuator";
qcom,cci-master = <0>;
};
@@ -38,7 +38,7 @@
qcom,csid-sd-index = <0>;
qcom,actuator-src = <&actuator0>;
qcom,led-flash-src = <&led_flash0>;
- qcom,mount-angle = <90>;
+ qcom,mount-angle = <0>;
qcom,sensor-name = "ov8825";
cam_vdig-supply = <&pm8226_l5>;
cam_vana-supply = <&pm8226_l19>;
@@ -74,7 +74,7 @@
qcom,slave-id = <0x20 0x0 0x9724>;
qcom,csiphy-sd-index = <1>;
qcom,csid-sd-index = <0>;
- qcom,mount-angle = <90>;
+ qcom,mount-angle = <0>;
qcom,sensor-name = "ov9724";
cam_vdig-supply = <&pm8226_l5>;
cam_vana-supply = <&pm8226_l19>;
diff --git a/arch/arm/boot/dts/msm8226-camera-sensor-mtp.dtsi b/arch/arm/boot/dts/msm8226-camera-sensor-mtp.dtsi
index 02089be..1f7ba89 100644
--- a/arch/arm/boot/dts/msm8226-camera-sensor-mtp.dtsi
+++ b/arch/arm/boot/dts/msm8226-camera-sensor-mtp.dtsi
@@ -25,7 +25,7 @@
actuator0: qcom,actuator@6e {
cell-index = <3>;
- reg = <0x6c 0x0>;
+ reg = <0x6c>;
compatible = "qcom,actuator";
qcom,cci-master = <0>;
};
@@ -38,7 +38,7 @@
qcom,csid-sd-index = <0>;
qcom,actuator-src = <&actuator0>;
qcom,led-flash-src = <&led_flash0>;
- qcom,mount-angle = <90>;
+ qcom,mount-angle = <0>;
qcom,sensor-name = "ov8825";
cam_vdig-supply = <&pm8226_l5>;
cam_vana-supply = <&pm8226_l19>;
diff --git a/arch/arm/boot/dts/msm8226-camera-sensor-cdp-qrd.dtsi b/arch/arm/boot/dts/msm8226-camera-sensor-qrd.dtsi
similarity index 98%
rename from arch/arm/boot/dts/msm8226-camera-sensor-cdp-qrd.dtsi
rename to arch/arm/boot/dts/msm8226-camera-sensor-qrd.dtsi
index b7f837f..5ea02b4 100644
--- a/arch/arm/boot/dts/msm8226-camera-sensor-cdp-qrd.dtsi
+++ b/arch/arm/boot/dts/msm8226-camera-sensor-qrd.dtsi
@@ -25,7 +25,7 @@
actuator0: qcom,actuator@6e {
cell-index = <3>;
- reg = <0x6c 0x0>;
+ reg = <0x6c>;
compatible = "qcom,actuator";
qcom,cci-master = <0>;
};
@@ -38,7 +38,7 @@
qcom,csid-sd-index = <0>;
qcom,actuator-src = <&actuator0>;
qcom,led-flash-src = <&led_flash0>;
- qcom,mount-angle = <90>;
+ qcom,mount-angle = <270>;
qcom,sensor-name = "ov8825";
cam_vdig-supply = <&pm8226_l5>;
cam_vana-supply = <&pm8226_l19>;
diff --git a/arch/arm/boot/dts/msm8226-cdp.dts b/arch/arm/boot/dts/msm8226-cdp.dts
index 7b8dd59..0186e54 100644
--- a/arch/arm/boot/dts/msm8226-cdp.dts
+++ b/arch/arm/boot/dts/msm8226-cdp.dts
@@ -13,7 +13,7 @@
/dts-v1/;
/include/ "msm8226.dtsi"
/include/ "dsi-panel-nt35590-720p-video.dtsi"
-/include/ "msm8226-camera-sensor-cdp-qrd.dtsi"
+/include/ "msm8226-camera-sensor-cdp.dtsi"
/ {
model = "Qualcomm MSM 8226 CDP";
diff --git a/arch/arm/boot/dts/msm8226-fluid.dts b/arch/arm/boot/dts/msm8226-fluid.dts
index 02a0b0b..d70ef6e 100644
--- a/arch/arm/boot/dts/msm8226-fluid.dts
+++ b/arch/arm/boot/dts/msm8226-fluid.dts
@@ -21,4 +21,8 @@
serial@f991f000 {
status = "disabled";
};
-};
\ No newline at end of file
+};
+
+&pm8226_bms {
+ status = "ok";
+};
diff --git a/arch/arm/boot/dts/msm8226-mtp.dts b/arch/arm/boot/dts/msm8226-mtp.dts
index dab15ae..b0a4a3d 100644
--- a/arch/arm/boot/dts/msm8226-mtp.dts
+++ b/arch/arm/boot/dts/msm8226-mtp.dts
@@ -299,3 +299,7 @@
qcom,fast-avg-setup = <0>;
};
};
+
+&pm8226_bms {
+ status = "ok";
+};
diff --git a/arch/arm/boot/dts/msm8226-qrd.dts b/arch/arm/boot/dts/msm8226-qrd.dts
index 4879691..7d4f0d5 100644
--- a/arch/arm/boot/dts/msm8226-qrd.dts
+++ b/arch/arm/boot/dts/msm8226-qrd.dts
@@ -13,7 +13,7 @@
/dts-v1/;
/include/ "msm8226.dtsi"
/include/ "dsi-panel-nt35590-720p-video.dtsi"
-/include/ "msm8226-camera-sensor-cdp-qrd.dtsi"
+/include/ "msm8226-camera-sensor-qrd.dtsi"
/ {
model = "Qualcomm MSM 8226 QRD";
diff --git a/arch/arm/boot/dts/msm8610-cdp.dts b/arch/arm/boot/dts/msm8610-cdp.dts
index c762405..5b0eb33 100644
--- a/arch/arm/boot/dts/msm8610-cdp.dts
+++ b/arch/arm/boot/dts/msm8610-cdp.dts
@@ -19,7 +19,7 @@
compatible = "qcom,msm8610-cdp", "qcom,msm8610", "qcom,cdp";
qcom,msm-id = <147 1 0>, <165 1 0>;
- serial@f991f000 {
+ serial@f991e000 {
status = "ok";
};
};
diff --git a/arch/arm/boot/dts/msm8610-coresight.dtsi b/arch/arm/boot/dts/msm8610-coresight.dtsi
index 89a00f1..a0a2c14 100644
--- a/arch/arm/boot/dts/msm8610-coresight.dtsi
+++ b/arch/arm/boot/dts/msm8610-coresight.dtsi
@@ -113,7 +113,7 @@
coresight-nr-inports = <4>;
coresight-outports = <0>;
coresight-child-list = <&funnel_in1>;
- coresight-child-ports = <5>;
+ coresight-child-ports = <6>;
};
stm: stm@fc302000 {
@@ -126,7 +126,7 @@
coresight-name = "coresight-stm";
coresight-nr-inports = <0>;
coresight-outports = <0>;
- coresight-child-list = <&funnel_in1>;
+ coresight-child-list = <&funnel_in0>;
coresight-child-ports = <7>;
};
diff --git a/arch/arm/boot/dts/msm8610-smp2p.dtsi b/arch/arm/boot/dts/msm8610-smp2p.dtsi
index 9690d12..91029e2 100644
--- a/arch/arm/boot/dts/msm8610-smp2p.dtsi
+++ b/arch/arm/boot/dts/msm8610-smp2p.dtsi
@@ -12,8 +12,7 @@
/ {
qcom,smp2p-modem {
compatible = "qcom,smp2p";
- reg = <0xfa006000 0x1000>, <0x8 0x0>;
- reg-names = "irq-reg-base", "irq-reg-offset";
+ reg = <0xf9011008 0x4>;
qcom,remote-pid = <1>;
qcom,irq-bitmask = <0x4000>;
interrupts = <0 27 1>;
@@ -21,8 +20,7 @@
qcom,smp2p-adsp {
compatible = "qcom,smp2p";
- reg = <0xfa006000 0x1000>, <0x8 0x0>;
- reg-names = "irq-reg-base", "irq-reg-offset";
+ reg = <0xf9011008 0x4>;
qcom,remote-pid = <2>;
qcom,irq-bitmask = <0x400>;
interrupts = <0 158 1>;
@@ -30,8 +28,7 @@
qcom,smp2p-wcnss {
compatible = "qcom,smp2p";
- reg = <0xfa006000 0x1000>, <0x8 0x0>;
- reg-names = "irq-reg-base", "irq-reg-offset";
+ reg = <0xf9011008 0x4>;
qcom,remote-pid = <4>;
qcom,irq-bitmask = <0x40000>;
interrupts = <0 143 1>;
diff --git a/arch/arm/boot/dts/msm8610.dtsi b/arch/arm/boot/dts/msm8610.dtsi
index 28a3c35..6052131 100644
--- a/arch/arm/boot/dts/msm8610.dtsi
+++ b/arch/arm/boot/dts/msm8610.dtsi
@@ -74,6 +74,13 @@
status = "disabled";
};
+ serial@f991e000 {
+ compatible = "qcom,msm-lsuart-v14";
+ reg = <0xf991e000 0x1000>;
+ interrupts = <0 108 0>;
+ status = "disabled";
+ };
+
qcom,vidc@fdc00000 {
compatible = "qcom,msm-vidc";
qcom,vidc-ns-map = <0x40000000 0x40000000>;
@@ -212,9 +219,9 @@
qcom,device-type = <3>;
};
- qcom,smem@d600000 {
+ qcom,smem@d900000 {
compatible = "qcom,smem";
- reg = <0xd600000 0x200000>,
+ reg = <0xd900000 0x200000>,
<0xf9011000 0x1000>,
<0xfc428000 0x4000>;
reg-names = "smem", "irq-reg-base", "aux-mem1";
diff --git a/arch/arm/boot/dts/msm8974-camera.dtsi b/arch/arm/boot/dts/msm8974-camera.dtsi
index 0bd303f..3a78a15 100644
--- a/arch/arm/boot/dts/msm8974-camera.dtsi
+++ b/arch/arm/boot/dts/msm8974-camera.dtsi
@@ -104,7 +104,7 @@
cell-index = <0>;
compatible = "qcom,vfe40";
reg = <0xfda10000 0x1000>,
- <0xfda40000 0x200>;
+ <0xfda40000 0x200>;
reg-names = "vfe", "vfe_vbif";
interrupts = <0 57 0>;
interrupt-names = "vfe";
@@ -115,7 +115,7 @@
cell-index = <1>;
compatible = "qcom,vfe40";
reg = <0xfda14000 0x1000>,
- <0xfda40000 0x200>;
+ <0xfda40000 0x200>;
reg-names = "vfe", "vfe_vbif";
interrupts = <0 58 0>;
interrupt-names = "vfe";
@@ -129,7 +129,7 @@
reg-names = "jpeg";
interrupts = <0 59 0>;
interrupt-names = "jpeg";
- vdd-supply = <&gdsc_jpeg>;
+ vdd-supply = <&gdsc_jpeg>;
};
qcom,jpeg@fda20000 {
@@ -163,8 +163,8 @@
cell-index = <0>;
compatible = "qcom,cpp";
reg = <0xfda04000 0x100>,
- <0xfda40000 0x200>,
- <0xfda18000 0x008>;
+ <0xfda40000 0x200>,
+ <0xfda18000 0x008>;
reg-names = "cpp", "cpp_vbif", "cpp_hw";
interrupts = <0 49 0>;
interrupt-names = "cpp";
@@ -182,7 +182,7 @@
cell-index = <0>;
compatible = "qcom,cci";
reg = <0xfda0C000 0x1000>;
- #address-cells = <1>;
+ #address-cells = <1>;
#size-cells = <0>;
reg-names = "cci";
interrupts = <0 50 0>;
@@ -194,9 +194,9 @@
qcom,gpio-tbl-num = <0 1 2 3>;
qcom,gpio-tbl-flags = <1 1 1 1>;
qcom,gpio-tbl-label = "CCI_I2C_DATA0",
- "CCI_I2C_CLK0",
- "CCI_I2C_DATA1",
- "CCI_I2C_CLK1";
+ "CCI_I2C_CLK0",
+ "CCI_I2C_DATA1",
+ "CCI_I2C_CLK1";
qcom,hw-thigh = <78>;
qcom,hw-tlow = <114>;
qcom,hw-tsu-sto = <28>;
diff --git a/arch/arm/boot/dts/msmkrypton-sim.dts b/arch/arm/boot/dts/msmkrypton-sim.dts
new file mode 100644
index 0000000..1872a36
--- /dev/null
+++ b/arch/arm/boot/dts/msmkrypton-sim.dts
@@ -0,0 +1,25 @@
+/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/dts-v1/;
+
+/include/ "msmkrypton.dtsi"
+
+/ {
+ model = "Qualcomm MSM KRYPTON SIM";
+ compatible = "qcom,msmkrypton-sim", "qcom,msmkrypton", "qcom,sim";
+ qcom,msm-id = <187 16 0>;
+};
+
+&uartdm3{
+ status = "ok";
+};
diff --git a/arch/arm/boot/dts/msmkrypton.dtsi b/arch/arm/boot/dts/msmkrypton.dtsi
new file mode 100644
index 0000000..db61dab
--- /dev/null
+++ b/arch/arm/boot/dts/msmkrypton.dtsi
@@ -0,0 +1,54 @@
+/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/include/ "skeleton.dtsi"
+
+/ {
+ model = "Qualcomm MSM KRYPTON";
+ compatible = "qcom,msmkrypton";
+ interrupt-parent = <&intc>;
+
+ intc: interrupt-controller@f9000000 {
+ compatible = "qcom,msm-qgic2";
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ reg = <0xf9000000 0x1000>,
+ <0xf9002000 0x1000>;
+ };
+
+ msmgpio: gpio@fd510000 {
+ compatible = "qcom,msm-gpio";
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0xfd510000 0x4000>;
+ ngpio = <89>;
+ interrupts = <0 208 0>;
+ qcom,direct-connect-irqs = <8>;
+ };
+
+ timer: msm-qtimer@f9021000 {
+ compatible = "arm,armv7-timer";
+ reg = <0xf9021000 0x1000>;
+ interrupts = <0 7 0>;
+ irq-is-not-percpu;
+ clock-frequency = <19200000>;
+ };
+
+ uartdm3: serial@f991f000 {
+ compatible = "qcom,msm-lsuart-v14";
+ reg = <0xf991f000 0x1000>;
+ interrupts = <0 109 0>;
+ status = "disabled";
+ };
+};
diff --git a/arch/arm/configs/msm8610_defconfig b/arch/arm/configs/msm8610_defconfig
index 5fdd1bc..45f0868 100644
--- a/arch/arm/configs/msm8610_defconfig
+++ b/arch/arm/configs/msm8610_defconfig
@@ -241,6 +241,7 @@
CONFIG_GPIO_QPNP_PIN=y
CONFIG_POWER_SUPPLY=y
CONFIG_QPNP_CHARGER=y
+CONFIG_QPNP_BMS=y
CONFIG_SENSORS_QPNP_ADC_VOLTAGE=y
CONFIG_SENSORS_QPNP_ADC_CURRENT=y
CONFIG_THERMAL=y
diff --git a/arch/arm/configs/msm8960-perf_defconfig b/arch/arm/configs/msm8960-perf_defconfig
index 4e6cb05..f90e5f3 100644
--- a/arch/arm/configs/msm8960-perf_defconfig
+++ b/arch/arm/configs/msm8960-perf_defconfig
@@ -483,6 +483,7 @@
CONFIG_SPS_SUPPORT_BAMDMA=y
CONFIG_MSM_AVTIMER=y
CONFIG_MSM_IOMMU=y
+CONFIG_IOMMU_PGTABLES_L2=y
CONFIG_MOBICORE_SUPPORT=m
CONFIG_MOBICORE_API=m
CONFIG_CORESIGHT=y
diff --git a/arch/arm/configs/msm8960_defconfig b/arch/arm/configs/msm8960_defconfig
index c4fffb9..f699dee 100644
--- a/arch/arm/configs/msm8960_defconfig
+++ b/arch/arm/configs/msm8960_defconfig
@@ -485,6 +485,7 @@
CONFIG_SPS=y
CONFIG_SPS_SUPPORT_BAMDMA=y
CONFIG_MSM_IOMMU=y
+CONFIG_IOMMU_PGTABLES_L2=y
CONFIG_MOBICORE_SUPPORT=m
CONFIG_MOBICORE_API=m
CONFIG_CORESIGHT=y
diff --git a/arch/arm/configs/msm8974-perf_defconfig b/arch/arm/configs/msm8974-perf_defconfig
index f76f810..f67cb0d 100644
--- a/arch/arm/configs/msm8974-perf_defconfig
+++ b/arch/arm/configs/msm8974-perf_defconfig
@@ -431,6 +431,7 @@
CONFIG_QPNP_REVID=y
CONFIG_QPNP_COINCELL=y
CONFIG_MSM_IOMMU=y
+CONFIG_IOMMU_PGTABLES_L2=y
CONFIG_MOBICORE_SUPPORT=m
CONFIG_MOBICORE_API=m
CONFIG_CORESIGHT=y
diff --git a/arch/arm/configs/msm8974_defconfig b/arch/arm/configs/msm8974_defconfig
index 6112134..b5e67fd 100644
--- a/arch/arm/configs/msm8974_defconfig
+++ b/arch/arm/configs/msm8974_defconfig
@@ -440,6 +440,7 @@
CONFIG_QPNP_REVID=y
CONFIG_QPNP_COINCELL=y
CONFIG_MSM_IOMMU=y
+CONFIG_IOMMU_PGTABLES_L2=y
CONFIG_MSM_IOMMU_PMON=y
CONFIG_MOBICORE_SUPPORT=m
CONFIG_MOBICORE_API=m
diff --git a/arch/arm/configs/msmzinc_defconfig b/arch/arm/configs/msmzinc_defconfig
index 678b086..d0ea87a 100644
--- a/arch/arm/configs/msmzinc_defconfig
+++ b/arch/arm/configs/msmzinc_defconfig
@@ -335,6 +335,7 @@
CONFIG_QPNP_POWER_ON=y
CONFIG_QPNP_CLKDIV=y
CONFIG_MSM_IOMMU=y
+CONFIG_IOMMU_PGTABLES_L2=y
CONFIG_EXT2_FS=y
CONFIG_EXT2_FS_XATTR=y
CONFIG_EXT3_FS=y
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index 601fcfa..c510889 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -391,6 +391,21 @@
select MEMORY_HOLE_CARVEOUT
select MSM_RPM_LOG
+config ARCH_MSMKRYPTON
+ bool "MSMKRYPTON"
+ select ARM_GIC
+ select CPU_V7
+ select MSM_GPIOMUX
+ select MSM_RPM_SMD
+ select MSM_NATIVE_RESTART
+ select MSM_RESTART_V2
+ select MSM_SPM_V2
+ select MSM_PM8X60 if PM
+ select MULTI_IRQ_HANDLER
+ select GPIO_MSM_V3
+ select MAY_HAVE_SPARSE_IRQ
+ select SPARSE_IRQ
+
config ARCH_MSM8610
bool "MSM8610"
select ARM_GIC
@@ -1074,6 +1089,7 @@
default "0x00000000" if ARCH_MSM8610
default "0x10000000" if ARCH_FSM9XXX
default "0x00200000" if ARCH_MSM9625
+ default "0x00200000" if ARCH_MSMKRYPTON
default "0x00200000" if !MSM_STACKED_MEMORY
default "0x00000000" if ARCH_QSD8X50 && MSM_SOC_REV_A
default "0x20000000" if ARCH_QSD8X50
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index 1c14ac6..7c78395 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -121,6 +121,7 @@
ifndef CONFIG_ARCH_MPQ8092
ifndef CONFIG_ARCH_MSM8610
ifndef CONFIG_ARCH_MSMZINC
+ifndef CONFIG_ARCH_MSMKRYPTON
obj-y += nand_partitions.o
endif
endif
@@ -131,6 +132,7 @@
endif
endif
endif
+endif
obj-$(CONFIG_MSM_SDIO_TTY) += sdio_tty.o
obj-$(CONFIG_MSM_SMD_TTY) += smd_tty.o
obj-$(CONFIG_MSM_SMD_QMI) += smd_qmi.o
@@ -304,6 +306,7 @@
obj-$(CONFIG_ARCH_MSM8226) += gdsc.o
obj-$(CONFIG_ARCH_MSM8610) += gdsc.o
obj-$(CONFIG_ARCH_MSM8974) += krait-regulator.o
+obj-$(CONFIG_ARCH_MSMKRYPTON) += board-krypton.o board-krypton-gpiomux.o
obj-$(CONFIG_ARCH_MSM9625) += board-9625.o board-9625-gpiomux.o
obj-$(CONFIG_ARCH_MSM9625) += clock-local2.o clock-pll.o clock-9625.o clock-rpm.o clock-voter.o acpuclock-9625.o acpuclock-cortex.o
obj-$(CONFIG_ARCH_MSM8930) += acpuclock-8930.o acpuclock-8627.o acpuclock-8930aa.o acpuclock-8930ab.o
@@ -368,6 +371,7 @@
obj-$(CONFIG_ARCH_MSM9615) += gpiomux-v2.o gpiomux.o
obj-$(CONFIG_ARCH_MSM8974) += gpiomux-v2.o gpiomux.o
obj-$(CONFIG_ARCH_MSM9625) += gpiomux-v2.o gpiomux.o
+obj-$(CONFIG_ARCH_MSMKRYPTON) += gpiomux-v2.o gpiomux.o
obj-$(CONFIG_ARCH_MPQ8092) += gpiomux-v2.o gpiomux.o
obj-$(CONFIG_ARCH_MSM8226) += gpiomux-v2.o gpiomux.o
obj-$(CONFIG_ARCH_MSM8610) += gpiomux-v2.o gpiomux.o
diff --git a/arch/arm/mach-msm/Makefile.boot b/arch/arm/mach-msm/Makefile.boot
index e3b8d73..f20f6ae 100644
--- a/arch/arm/mach-msm/Makefile.boot
+++ b/arch/arm/mach-msm/Makefile.boot
@@ -62,6 +62,9 @@
zreladdr-$(CONFIG_ARCH_MSMZINC) := 0x00008000
dtb-$(CONFIG_ARCH_MSMZINC) += msmzinc-sim.dtb
+# MSMKRYPTON
+ zreladdr-$(CONFIG_ARCH_MSMKRYPTON) := 0x00208000
+ dtb-$(CONFIG_ARCH_MSMKRYPTON) += msmkrypton-sim.dtb
# MSM9615
zreladdr-$(CONFIG_ARCH_MSM9615) := 0x40808000
diff --git a/arch/arm/mach-msm/acpuclock-8974.c b/arch/arm/mach-msm/acpuclock-8974.c
index 0533d06..c60e89a 100644
--- a/arch/arm/mach-msm/acpuclock-8974.c
+++ b/arch/arm/mach-msm/acpuclock-8974.c
@@ -653,32 +653,32 @@
};
static struct acpu_level acpu_freq_tbl_2p2g_pvs6[] __initdata = {
- { 1, { 300000, PLL_0, 0, 0 }, L2(0), 75000, 400000 },
- { 0, { 345600, HFPLL, 2, 36 }, L2(1), 75000, 3200000 },
- { 1, { 422400, HFPLL, 2, 44 }, L2(2), 75000, 3200000 },
- { 0, { 499200, HFPLL, 2, 52 }, L2(2), 75000, 3200000 },
- { 0, { 576000, HFPLL, 1, 30 }, L2(3), 75000, 3200000 },
- { 1, { 652800, HFPLL, 1, 34 }, L2(3), 76000, 3200000 },
- { 1, { 729600, HFPLL, 1, 38 }, L2(4), 77000, 3200000 },
- { 0, { 806400, HFPLL, 1, 42 }, L2(4), 78000, 3200000 },
- { 1, { 883200, HFPLL, 1, 46 }, L2(4), 79000, 3200000 },
- { 1, { 960000, HFPLL, 1, 50 }, L2(9), 80000, 3200000 },
- { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 81000, 3200000 },
- { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 82000, 3200000 },
- { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 83000, 3200000 },
- { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 84000, 3200000 },
- { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 85000, 3200000 },
- { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 86000, 3200000 },
- { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 87000, 3200000 },
- { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 87500, 3200000 },
- { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 88500, 3200000 },
- { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 89500, 3200000 },
- { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 90500, 3200000 },
- { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 91500, 3200000 },
- { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 92000, 3200000 },
- { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 93000, 3200000 },
- { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 94000, 3200000 },
- { 1, { 2150400, HFPLL, 1, 112 }, L2(19), 95000, 3200000 },
+ { 1, { 300000, PLL_0, 0, 0 }, L2(0), 750000, 400000 },
+ { 0, { 345600, HFPLL, 2, 36 }, L2(1), 750000, 3200000 },
+ { 1, { 422400, HFPLL, 2, 44 }, L2(2), 750000, 3200000 },
+ { 0, { 499200, HFPLL, 2, 52 }, L2(2), 750000, 3200000 },
+ { 0, { 576000, HFPLL, 1, 30 }, L2(3), 750000, 3200000 },
+ { 1, { 652800, HFPLL, 1, 34 }, L2(3), 760000, 3200000 },
+ { 1, { 729600, HFPLL, 1, 38 }, L2(4), 770000, 3200000 },
+ { 0, { 806400, HFPLL, 1, 42 }, L2(4), 780000, 3200000 },
+ { 1, { 883200, HFPLL, 1, 46 }, L2(4), 790000, 3200000 },
+ { 1, { 960000, HFPLL, 1, 50 }, L2(9), 800000, 3200000 },
+ { 1, { 1036800, HFPLL, 1, 54 }, L2(10), 810000, 3200000 },
+ { 0, { 1113600, HFPLL, 1, 58 }, L2(10), 820000, 3200000 },
+ { 1, { 1190400, HFPLL, 1, 62 }, L2(10), 830000, 3200000 },
+ { 1, { 1267200, HFPLL, 1, 66 }, L2(13), 840000, 3200000 },
+ { 0, { 1344000, HFPLL, 1, 70 }, L2(14), 850000, 3200000 },
+ { 0, { 1420800, HFPLL, 1, 74 }, L2(15), 860000, 3200000 },
+ { 1, { 1497600, HFPLL, 1, 78 }, L2(16), 870000, 3200000 },
+ { 1, { 1574400, HFPLL, 1, 82 }, L2(17), 875000, 3200000 },
+ { 0, { 1651200, HFPLL, 1, 86 }, L2(17), 885000, 3200000 },
+ { 1, { 1728000, HFPLL, 1, 90 }, L2(18), 895000, 3200000 },
+ { 0, { 1804800, HFPLL, 1, 94 }, L2(18), 905000, 3200000 },
+ { 0, { 1881600, HFPLL, 1, 98 }, L2(18), 915000, 3200000 },
+ { 1, { 1958400, HFPLL, 1, 102 }, L2(19), 920000, 3200000 },
+ { 0, { 2035200, HFPLL, 1, 106 }, L2(19), 930000, 3200000 },
+ { 0, { 2112000, HFPLL, 1, 110 }, L2(19), 940000, 3200000 },
+ { 1, { 2150400, HFPLL, 1, 112 }, L2(19), 950000, 3200000 },
{ 0, { 0 } }
};
diff --git a/arch/arm/mach-msm/board-8226.c b/arch/arm/mach-msm/board-8226.c
index 6371b9d..3582914 100644
--- a/arch/arm/mach-msm/board-8226.c
+++ b/arch/arm/mach-msm/board-8226.c
@@ -25,6 +25,7 @@
#include <linux/of_irq.h>
#include <linux/memory.h>
#include <linux/regulator/qpnp-regulator.h>
+#include <linux/msm_tsens.h>
#include <asm/mach/map.h>
#include <asm/hardware/gic.h>
#include <asm/mach/arch.h>
@@ -112,7 +113,7 @@
msm_clock_init(&msm8226_rumi_clock_init_data);
else
msm_clock_init(&msm8226_clock_init_data);
-
+ tsens_tm_init_driver();
msm_thermal_device_init();
}
diff --git a/arch/arm/mach-msm/board-8610.c b/arch/arm/mach-msm/board-8610.c
index 99db345..67334d5 100644
--- a/arch/arm/mach-msm/board-8610.c
+++ b/arch/arm/mach-msm/board-8610.c
@@ -24,6 +24,7 @@
#include <linux/of_fdt.h>
#include <linux/of_irq.h>
#include <linux/memory.h>
+#include <linux/msm_tsens.h>
#include <asm/mach/map.h>
#include <asm/arch_timer.h>
#include <asm/hardware/gic.h>
@@ -105,6 +106,7 @@
msm_lpmrs_module_init();
msm_spm_device_init();
qpnp_regulator_init();
+ tsens_tm_init_driver();
msm_thermal_device_init();
if (of_board_is_rumi())
diff --git a/arch/arm/mach-msm/board-8974.c b/arch/arm/mach-msm/board-8974.c
index 9b69c8f..0ca55d1 100644
--- a/arch/arm/mach-msm/board-8974.c
+++ b/arch/arm/mach-msm/board-8974.c
@@ -22,6 +22,7 @@
#include <linux/memory.h>
#include <linux/regulator/machine.h>
#include <linux/regulator/krait-regulator.h>
+#include <linux/msm_tsens.h>
#include <linux/msm_thermal.h>
#include <asm/mach/map.h>
#include <asm/hardware/gic.h>
@@ -101,6 +102,7 @@
msm_clock_init(&msm8974_rumi_clock_init_data);
else
msm_clock_init(&msm8974_clock_init_data);
+ tsens_tm_init_driver();
msm_thermal_device_init();
}
diff --git a/arch/arm/mach-msm/board-9625.c b/arch/arm/mach-msm/board-9625.c
index 923dc2a..3bb00bb 100644
--- a/arch/arm/mach-msm/board-9625.c
+++ b/arch/arm/mach-msm/board-9625.c
@@ -21,6 +21,7 @@
#include <linux/of_platform.h>
#include <linux/of_irq.h>
#include <linux/memory.h>
+#include <linux/msm_tsens.h>
#include <asm/mach/map.h>
#include <asm/hardware/gic.h>
#include <asm/mach/arch.h>
@@ -237,6 +238,7 @@
msm_spm_device_init();
msm_clock_init(&msm9625_clock_init_data);
msm9625_init_buses();
+ tsens_tm_init_driver();
}
void __init msm9625_init(void)
diff --git a/arch/arm/mach-msm/board-krypton-gpiomux.c b/arch/arm/mach-msm/board-krypton-gpiomux.c
new file mode 100644
index 0000000..3d86ba7
--- /dev/null
+++ b/arch/arm/mach-msm/board-krypton-gpiomux.c
@@ -0,0 +1,52 @@
+/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <mach/board.h>
+#include <mach/gpio.h>
+#include <mach/gpiomux.h>
+
+static struct gpiomux_setting gpio_uart_config = {
+ .func = GPIOMUX_FUNC_1,
+ .drv = GPIOMUX_DRV_8MA,
+ .pull = GPIOMUX_PULL_NONE,
+};
+
+static struct msm_gpiomux_config msm_blsp_configs[] __initdata = {
+ {
+ .gpio = 8, /* BLSP1 UART TX */
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &gpio_uart_config,
+ },
+ },
+ {
+ .gpio = 9, /* BLSP1 UART RX */
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &gpio_uart_config,
+ },
+ },
+};
+
+void __init msmkrypton_init_gpiomux(void)
+{
+ int rc;
+
+ rc = msm_gpiomux_init_dt();
+ if (rc) {
+ pr_err("%s failed %d\n", __func__, rc);
+ return;
+ }
+
+ msm_gpiomux_install(msm_blsp_configs, ARRAY_SIZE(msm_blsp_configs));
+}
diff --git a/arch/arm/mach-msm/board-krypton.c b/arch/arm/mach-msm/board-krypton.c
new file mode 100644
index 0000000..aada3b0
--- /dev/null
+++ b/arch/arm/mach-msm/board-krypton.c
@@ -0,0 +1,84 @@
+/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/memory.h>
+#include <asm/hardware/gic.h>
+#include <asm/mach/map.h>
+#include <asm/mach/arch.h>
+#include <mach/board.h>
+#include <mach/gpiomux.h>
+#include <mach/msm_iomap.h>
+#include <mach/msm_memtypes.h>
+#include <mach/msm_smd.h>
+#include <mach/restart.h>
+#include <mach/socinfo.h>
+#include <mach/clk-provider.h>
+#include "board-dt.h"
+#include "clock.h"
+#include "devices.h"
+
+static struct clk_lookup msm_clocks_dummy[] = {
+ CLK_DUMMY("core_clk", BLSP1_UART_CLK, "f991f000.serial", OFF),
+ CLK_DUMMY("iface_clk", BLSP1_UART_CLK, "f991f000.serial", OFF),
+};
+
+static struct clock_init_data msm_dummy_clock_init_data __initdata = {
+ .table = msm_clocks_dummy,
+ .size = ARRAY_SIZE(msm_clocks_dummy),
+};
+
+/*
+ * Used to satisfy dependencies for devices that need to be
+ * run early or in a particular order. Most likely your device doesn't fall
+ * into this category, and thus the driver should not be added here. The
+ * EPROBE_DEFER can satisfy most dependency problems.
+ */
+void __init msmkrypton_add_drivers(void)
+{
+ msm_smd_init();
+ msm_clock_init(&msm_dummy_clock_init_data);
+}
+
+static void __init msmkrypton_map_io(void)
+{
+ msm_map_msmkrypton_io();
+}
+
+void __init msmkrypton_init(void)
+{
+ if (socinfo_init() < 0)
+ pr_err("%s: socinfo_init() failed\n", __func__);
+
+ msmkrypton_init_gpiomux();
+ of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+ msmkrypton_add_drivers();
+}
+
+static const char *msmkrypton_dt_match[] __initconst = {
+ "qcom,msmkrypton",
+ NULL
+};
+
+DT_MACHINE_START(MSMKRYPTON_DT, "Qualcomm MSM Krypton (Flattened Device Tree)")
+ .map_io = msmkrypton_map_io,
+ .init_irq = msm_dt_init_irq,
+ .init_machine = msmkrypton_init,
+ .handle_irq = gic_handle_irq,
+ .timer = &msm_dt_timer,
+ .dt_compat = msmkrypton_dt_match,
+ .restart = msm_restart,
+MACHINE_END
diff --git a/arch/arm/mach-msm/clock-8226.c b/arch/arm/mach-msm/clock-8226.c
index 4079b5a..80907c8 100644
--- a/arch/arm/mach-msm/clock-8226.c
+++ b/arch/arm/mach-msm/clock-8226.c
@@ -2810,6 +2810,9 @@
static DEFINE_CLK_VOTER(pnoc_sps_clk, &pnoc_clk.c, LONG_MAX);
+static DEFINE_CLK_VOTER(qseecom_ce1_clk_src, &ce1_clk_src.c, LONG_MAX);
+static DEFINE_CLK_VOTER(scm_ce1_clk_src, &ce1_clk_src.c, LONG_MAX);
+
static DEFINE_CLK_BRANCH_VOTER(cxo_otg_clk, &xo.c);
static DEFINE_CLK_BRANCH_VOTER(cxo_pil_lpass_clk, &xo.c);
static DEFINE_CLK_BRANCH_VOTER(cxo_pil_mss_clk, &xo.c);
@@ -3171,12 +3174,14 @@
CLK_LOOKUP("core_clk", gcc_ce1_clk.c, "qseecom"),
CLK_LOOKUP("iface_clk", gcc_ce1_ahb_clk.c, "qseecom"),
CLK_LOOKUP("bus_clk", gcc_ce1_axi_clk.c, "qseecom"),
- CLK_LOOKUP("core_clk_src", ce1_clk_src.c, "qseecom"),
+ CLK_LOOKUP("core_clk_src", qseecom_ce1_clk_src.c, "qseecom"),
CLK_LOOKUP("core_clk", gcc_ce1_clk.c, "scm"),
CLK_LOOKUP("iface_clk", gcc_ce1_ahb_clk.c, "scm"),
CLK_LOOKUP("bus_clk", gcc_ce1_axi_clk.c, "scm"),
- CLK_LOOKUP("core_clk_src", ce1_clk_src.c, "scm"),
+ CLK_LOOKUP("core_clk_src", scm_ce1_clk_src.c, "scm"),
+
+ CLK_LOOKUP("core_clk_src", ce1_clk_src.c, ""),
/* SDCC */
CLK_LOOKUP("iface_clk", gcc_sdcc1_ahb_clk.c, "f9824000.qcom,sdcc"),
diff --git a/arch/arm/mach-msm/ebi_erp.c b/arch/arm/mach-msm/ebi_erp.c
index eb38101..6b300d8 100644
--- a/arch/arm/mach-msm/ebi_erp.c
+++ b/arch/arm/mach-msm/ebi_erp.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -18,6 +18,9 @@
#include <linux/errno.h>
#include <linux/proc_fs.h>
#include <linux/cpu.h>
+#include <mach/usb_trace.h>
+
+DEFINE_TRACE(usb_daytona_invalid_access);
#define MODULE_NAME "msm_ebi_erp"
@@ -113,6 +116,11 @@
err_cntl |= CNTL_CLEAR_ERR;
writel_relaxed(err_cntl, base + SLV_ERR_CNTL);
mb(); /* Ensure interrupt is cleared before returning */
+
+ if ((err_apacket0 & AMID_MASK) == 0x00000102)
+ trace_usb_daytona_invalid_access(err_addr, err_apacket0,
+ err_apacket1);
+
return IRQ_HANDLED;
}
diff --git a/arch/arm/mach-msm/include/mach/board.h b/arch/arm/mach-msm/include/mach/board.h
index 35257b2..72f5051 100644
--- a/arch/arm/mach-msm/include/mach/board.h
+++ b/arch/arm/mach-msm/include/mach/board.h
@@ -601,6 +601,7 @@
void msm_map_fsm9xxx_io(void);
void msm_map_8974_io(void);
void msm_map_zinc_io(void);
+void msm_map_msmkrypton_io(void);
void msm_map_msm8625_io(void);
void msm_map_msm9625_io(void);
void msm_init_irq(void);
@@ -611,6 +612,7 @@
void msm_8974_init_gpiomux(void);
void msmzinc_init_gpiomux(void);
void msm9625_init_gpiomux(void);
+void msmkrypton_init_gpiomux(void);
void msm_map_mpq8092_io(void);
void mpq8092_init_gpiomux(void);
void msm_map_msm8226_io(void);
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-8610.h b/arch/arm/mach-msm/include/mach/msm_iomap-8610.h
index b07ddba..2a62460 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-8610.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-8610.h
@@ -22,7 +22,7 @@
*
*/
-#define MSM8610_MSM_SHARED_RAM_PHYS 0x0D600000
+#define MSM8610_MSM_SHARED_RAM_PHYS 0x0D900000
#define MSM8610_APCS_GCC_PHYS 0xF9011000
#define MSM8610_APCS_GCC_SIZE SZ_4K
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-krypton.h b/arch/arm/mach-msm/include/mach/msm_iomap-krypton.h
new file mode 100644
index 0000000..a8b9da5
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-krypton.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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 __ASM_ARCH_MSM_IOMAP_MSMKRYPTON_H
+#define __ASM_ARCH_MSM_IOMAP_MSMKRYPTON_H
+
+/* Physical base address and size of peripherals.
+ * Ordered by the virtual base addresses they will be mapped at.
+ *
+ * If you add or remove entries here, you'll want to edit the
+ * io desc array in arch/arm/mach-msm/io.c to reflect your
+ * changes.
+ *
+ */
+
+#define MSMKRYPTON_SHARED_RAM_PHYS 0x00000000
+
+#define MSMKRYPTON_TLMM_PHYS 0xFD510000
+#define MSMKRYPTON_TLMM_SIZE SZ_16K
+
+#define MSMKRYPTON_MPM2_PSHOLD_PHYS 0xFC4AB000
+#define MSMKRYPTON_MPM2_PSHOLD_SIZE SZ_4K
+
+#endif
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap.h b/arch/arm/mach-msm/include/mach/msm_iomap.h
index d3706cd..f27eb36 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap.h
@@ -134,6 +134,7 @@
#include "msm_iomap-8092.h"
#include "msm_iomap-8226.h"
#include "msm_iomap-8610.h"
+#include "msm_iomap-krypton.h"
#endif
diff --git a/arch/arm/mach-msm/include/mach/usb_trace.h b/arch/arm/mach-msm/include/mach/usb_trace.h
new file mode 100644
index 0000000..02ca8ca
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/usb_trace.h
@@ -0,0 +1,27 @@
+/* include/asm-arm/arch-msm/usbtrace.h
+ *
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _USB_TRACE_H_
+#define _USB_TRACE_H_
+
+#include <linux/tracepoint.h>
+
+DECLARE_TRACE(usb_daytona_invalid_access,
+ TP_PROTO(unsigned int ebi_addr,
+ unsigned int ebi_apacket0, unsigned int ebi_apacket1),
+ TP_ARGS(ebi_addr, ebi_apacket0, ebi_apacket1));
+
+#endif
+
diff --git a/arch/arm/mach-msm/io.c b/arch/arm/mach-msm/io.c
index 19c7acd..ecac4a5 100644
--- a/arch/arm/mach-msm/io.c
+++ b/arch/arm/mach-msm/io.c
@@ -507,6 +507,25 @@
}
#endif /* CONFIG_ARCH_MSM9625 */
+#ifdef CONFIG_ARCH_MSMKRYPTON
+static struct map_desc msmkrypton_io_desc[] __initdata = {
+ MSM_CHIP_DEVICE(TLMM, MSMKRYPTON),
+ MSM_CHIP_DEVICE(MPM2_PSHOLD, MSMKRYPTON),
+ {
+ .virtual = (unsigned long) MSM_SHARED_RAM_BASE,
+ .length = MSM_SHARED_RAM_SIZE,
+ .type = MT_DEVICE,
+ },
+};
+
+void __init msm_map_msmkrypton_io(void)
+{
+ msm_shared_ram_phys = MSMKRYPTON_SHARED_RAM_PHYS;
+ msm_map_io(msmkrypton_io_desc, ARRAY_SIZE(msmkrypton_io_desc));
+ of_scan_flat_dt(msm_scan_dt_map_imem, NULL);
+}
+#endif /* CONFIG_ARCH_MSMKRYPTON */
+
#ifdef CONFIG_ARCH_MPQ8092
static struct map_desc mpq8092_io_desc[] __initdata = {
MSM_CHIP_DEVICE(QGIC_DIST, MPQ8092),
diff --git a/arch/arm/mach-msm/memory.c b/arch/arm/mach-msm/memory.c
index edfb45b..d71787c 100644
--- a/arch/arm/mach-msm/memory.c
+++ b/arch/arm/mach-msm/memory.c
@@ -20,6 +20,7 @@
#include <linux/module.h>
#include <linux/memory_alloc.h>
#include <linux/memblock.h>
+#include <asm/memblock.h>
#include <asm/pgtable.h>
#include <asm/io.h>
#include <asm/mach/map.h>
@@ -160,42 +161,18 @@
static void __init reserve_memory_for_mempools(void)
{
- int memtype, memreg_type;
+ int memtype;
struct memtype_reserve *mt;
- struct memblock_region *mr, *mr_candidate = NULL;
- int ret;
+ phys_addr_t alignment;
mt = &reserve_info->memtype_reserve_table[0];
for (memtype = 0; memtype < MEMTYPE_MAX; memtype++, mt++) {
if (mt->flags & MEMTYPE_FLAGS_FIXED || !mt->size)
continue;
-
- /* Choose the memory block with the highest physical
- * address which is large enough, so that we will not
- * take memory from the lowest memory bank which the kernel
- * is in (and cause boot problems) and so that we might
- * be able to steal memory that would otherwise become
- * highmem.
- */
- for_each_memblock(memory, mr) {
- memreg_type =
- reserve_info->paddr_to_memtype(mr->base);
- if (memtype != memreg_type)
- continue;
- if (mr->size >= mt->size
- && (mr_candidate == NULL
- || mr->base > mr_candidate->base))
- mr_candidate = mr;
- }
- BUG_ON(mr_candidate == NULL);
- /* bump mt up against the top of the region */
- mt->start = mr_candidate->base + mr_candidate->size - mt->size;
- ret = memblock_reserve(mt->start, mt->size);
- BUG_ON(ret);
- ret = memblock_free(mt->start, mt->size);
- BUG_ON(ret);
- ret = memblock_remove(mt->start, mt->size);
- BUG_ON(ret);
+ alignment = (mt->flags & MEMTYPE_FLAGS_1M_ALIGN) ?
+ SZ_1M : PAGE_SIZE;
+ mt->start = arm_memblock_steal(mt->size, alignment);
+ BUG_ON(!mt->start);
}
}
diff --git a/arch/arm/mach-msm/socinfo.c b/arch/arm/mach-msm/socinfo.c
index ee6dfbf..5158f8e 100644
--- a/arch/arm/mach-msm/socinfo.c
+++ b/arch/arm/mach-msm/socinfo.c
@@ -328,6 +328,7 @@
/* 8610 IDs */
[147] = MSM_CPU_8610,
+ [165] = MSM_CPU_8610,
/* 8064AB IDs */
[153] = MSM_CPU_8064AB,
@@ -849,10 +850,6 @@
dummy_socinfo.id = 146;
strlcpy(dummy_socinfo.build_id, "mpq8092 - ",
sizeof(dummy_socinfo.build_id));
- } else if (early_machine_is_msm8610()) {
- dummy_socinfo.id = 147;
- strlcpy(dummy_socinfo.build_id, "msm8610 - ",
- sizeof(dummy_socinfo.build_id));
} else if (early_machine_is_msmzinc()) {
dummy_socinfo.id = 178;
strlcpy(dummy_socinfo.build_id, "msmzinc - ",
diff --git a/block/blk-core.c b/block/blk-core.c
index bd50c8e..69764df 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -1080,6 +1080,16 @@
BUG_ON(blk_queued_rq(rq));
+ if (rq->cmd_flags & REQ_URGENT) {
+ /*
+ * It's not compliant with the design to re-insert
+ * urgent requests. We want to be able to track this
+ * down.
+ */
+ pr_err("%s(): requeueing an URGENT request", __func__);
+ WARN_ON(!q->dispatched_urgent);
+ q->dispatched_urgent = false;
+ }
elv_requeue_request(q, rq);
}
EXPORT_SYMBOL(blk_requeue_request);
@@ -1107,6 +1117,16 @@
blk_queue_end_tag(q, rq);
BUG_ON(blk_queued_rq(rq));
+ if (rq->cmd_flags & REQ_URGENT) {
+ /*
+ * It's not compliant with the design to re-insert
+ * urgent requests. We want to be able to track this
+ * down.
+ */
+ pr_err("%s(): requeueing an URGENT request", __func__);
+ WARN_ON(!q->dispatched_urgent);
+ q->dispatched_urgent = false;
+ }
return elv_reinsert_request(q, rq);
}
diff --git a/drivers/base/genlock.c b/drivers/base/genlock.c
index 8b7259a..0de37c9 100644
--- a/drivers/base/genlock.c
+++ b/drivers/base/genlock.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -712,6 +712,40 @@
}
EXPORT_SYMBOL(genlock_get_handle_fd);
+/*
+ * Get a file descriptor reference to a lock suitable for sharing with
+ * other processes
+ */
+
+int genlock_get_fd_handle(struct genlock_handle *handle)
+{
+ int ret;
+ struct genlock *lock;
+
+ if (IS_ERR_OR_NULL(handle))
+ return -EINVAL;
+
+ lock = handle->lock;
+
+ if (IS_ERR(lock))
+ return PTR_ERR(lock);
+
+ if (!lock->file) {
+ GENLOCK_LOG_ERR("No file attached to the lock\n");
+ return -EINVAL;
+ }
+
+ ret = get_unused_fd_flags(0);
+
+ if (ret < 0)
+ return ret;
+
+ fd_install(ret, lock->file);
+
+ return ret;
+}
+EXPORT_SYMBOL(genlock_get_fd_handle);
+
#ifdef CONFIG_GENLOCK_MISCDEVICE
static long genlock_dev_ioctl(struct file *filep, unsigned int cmd,
diff --git a/drivers/gpu/ion/ion_priv.h b/drivers/gpu/ion/ion_priv.h
index 28ef1a5..8d45f9d 100644
--- a/drivers/gpu/ion/ion_priv.h
+++ b/drivers/gpu/ion/ion_priv.h
@@ -23,44 +23,9 @@
#include <linux/mutex.h>
#include <linux/rbtree.h>
#include <linux/ion.h>
-#include <linux/iommu.h>
#include <linux/seq_file.h>
-enum {
- DI_PARTITION_NUM = 0,
- DI_DOMAIN_NUM = 1,
- DI_MAX,
-};
-
-/**
- * struct ion_iommu_map - represents a mapping of an ion buffer to an iommu
- * @iova_addr - iommu virtual address
- * @node - rb node to exist in the buffer's tree of iommu mappings
- * @domain_info - contains the partition number and domain number
- * domain_info[1] = domain number
- * domain_info[0] = partition number
- * @ref - for reference counting this mapping
- * @mapped_size - size of the iova space mapped
- * (may not be the same as the buffer size)
- * @flags - iommu domain/partition specific flags.
- *
- * Represents a mapping of one ion buffer to a particular iommu domain
- * and address range. There may exist other mappings of this buffer in
- * different domains or address ranges. All mappings will have the same
- * cacheability and security.
- */
-struct ion_iommu_map {
- unsigned long iova_addr;
- struct rb_node node;
- union {
- int domain_info[DI_MAX];
- uint64_t key;
- };
- struct ion_buffer *buffer;
- struct kref ref;
- int mapped_size;
- unsigned long flags;
-};
+#include "msm_ion_priv.h"
struct ion_buffer *ion_handle_buffer(struct ion_handle *handle);
@@ -190,26 +155,6 @@
bool ion_buffer_fault_user_mappings(struct ion_buffer *buffer);
/**
- * struct mem_map_data - represents information about the memory map for a heap
- * @node: rb node used to store in the tree of mem_map_data
- * @addr: start address of memory region.
- * @addr: end address of memory region.
- * @size: size of memory region
- * @client_name: name of the client who owns this buffer.
- *
- */
-struct mem_map_data {
- struct rb_node node;
- ion_phys_addr_t addr;
- ion_phys_addr_t addr_end;
- unsigned long size;
- const char *client_name;
-};
-
-#define iommu_map_domain(__m) ((__m)->domain_info[1])
-#define iommu_map_partition(__m) ((__m)->domain_info[0])
-
-/**
* ion_device_create - allocates and returns an ion device
* @custom_ioctl: arch specific ioctl function if applicable
*
@@ -251,15 +196,6 @@
struct ion_heap *ion_carveout_heap_create(struct ion_platform_heap *);
void ion_carveout_heap_destroy(struct ion_heap *);
-struct ion_heap *ion_iommu_heap_create(struct ion_platform_heap *);
-void ion_iommu_heap_destroy(struct ion_heap *);
-
-struct ion_heap *ion_cp_heap_create(struct ion_platform_heap *);
-void ion_cp_heap_destroy(struct ion_heap *);
-
-struct ion_heap *ion_reusable_heap_create(struct ion_platform_heap *);
-void ion_reusable_heap_destroy(struct ion_heap *);
-
/**
* kernel api to allocate/free from carveout -- used when carveout is
* used to back an architecture specific custom heap
@@ -269,88 +205,10 @@
void ion_carveout_free(struct ion_heap *heap, ion_phys_addr_t addr,
unsigned long size);
-#ifdef CONFIG_CMA
-struct ion_heap *ion_cma_heap_create(struct ion_platform_heap *);
-void ion_cma_heap_destroy(struct ion_heap *);
-
-struct ion_heap *ion_secure_cma_heap_create(struct ion_platform_heap *);
-void ion_secure_cma_heap_destroy(struct ion_heap *);
-#endif
-
-struct ion_heap *msm_get_contiguous_heap(void);
/**
- * The carveout/cp heap returns physical addresses, since 0 may be a valid
+ * The carveout heap returns physical addresses, since 0 may be a valid
* physical address, this is used to indicate allocation failed
*/
#define ION_CARVEOUT_ALLOCATE_FAIL -1
-#define ION_CP_ALLOCATE_FAIL -1
-/**
- * The reserved heap returns physical addresses, since 0 may be a valid
- * physical address, this is used to indicate allocation failed
- */
-#define ION_RESERVED_ALLOCATE_FAIL -1
-
-/**
- * ion_map_fmem_buffer - map fmem allocated memory into the kernel
- * @buffer - buffer to map
- * @phys_base - physical base of the heap
- * @virt_base - virtual base of the heap
- * @flags - flags for the heap
- *
- * Map fmem allocated memory into the kernel address space. This
- * is designed to be used by other heaps that need fmem behavior.
- * The virtual range must be pre-allocated.
- */
-void *ion_map_fmem_buffer(struct ion_buffer *buffer, unsigned long phys_base,
- void *virt_base, unsigned long flags);
-
-/**
- * ion_do_cache_op - do cache operations.
- *
- * @client - pointer to ION client.
- * @handle - pointer to buffer handle.
- * @uaddr - virtual address to operate on.
- * @offset - offset from physical address.
- * @len - Length of data to do cache operation on.
- * @cmd - Cache operation to perform:
- * ION_IOC_CLEAN_CACHES
- * ION_IOC_INV_CACHES
- * ION_IOC_CLEAN_INV_CACHES
- *
- * Returns 0 on success
- */
-int ion_do_cache_op(struct ion_client *client, struct ion_handle *handle,
- void *uaddr, unsigned long offset, unsigned long len,
- unsigned int cmd);
-
-void ion_cp_heap_get_base(struct ion_heap *heap, unsigned long *base,
- unsigned long *size);
-
-void ion_mem_map_show(struct ion_heap *heap);
-
-
-
-int ion_secure_handle(struct ion_client *client, struct ion_handle *handle,
- int version, void *data, int flags);
-
-int ion_unsecure_handle(struct ion_client *client, struct ion_handle *handle);
-
-int ion_heap_allow_secure_allocation(enum ion_heap_type type);
-
-int ion_heap_allow_heap_secure(enum ion_heap_type type);
-
-int ion_heap_allow_handle_secure(enum ion_heap_type type);
-
-/**
- * ion_create_chunked_sg_table - helper function to create sg table
- * with specified chunk size
- * @buffer_base: The starting address used for the sg dma address
- * @chunk_size: The size of each entry in the sg table
- * @total_size: The total size of the sg table (i.e. the sum of the
- * entries). This will be rounded up to the nearest
- * multiple of `chunk_size'
- */
-struct sg_table *ion_create_chunked_sg_table(phys_addr_t buffer_base,
- size_t chunk_size, size_t total_size);
#endif /* _ION_PRIV_H */
diff --git a/drivers/gpu/ion/msm_ion_priv.h b/drivers/gpu/ion/msm_ion_priv.h
new file mode 100644
index 0000000..44f434a
--- /dev/null
+++ b/drivers/gpu/ion/msm_ion_priv.h
@@ -0,0 +1,150 @@
+/*
+ * drivers/gpu/ion/ion_priv.h
+ *
+ * Copyright (C) 2011 Google, Inc.
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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_ION_PRIV_H
+#define _MSM_ION_PRIV_H
+
+#include <linux/kref.h>
+#include <linux/mm_types.h>
+#include <linux/mutex.h>
+#include <linux/rbtree.h>
+#include <linux/ion.h>
+#include <linux/iommu.h>
+#include <linux/seq_file.h>
+
+enum {
+ DI_PARTITION_NUM = 0,
+ DI_DOMAIN_NUM = 1,
+ DI_MAX,
+};
+
+/**
+ * struct ion_iommu_map - represents a mapping of an ion buffer to an iommu
+ * @iova_addr - iommu virtual address
+ * @node - rb node to exist in the buffer's tree of iommu mappings
+ * @domain_info - contains the partition number and domain number
+ * domain_info[1] = domain number
+ * domain_info[0] = partition number
+ * @ref - for reference counting this mapping
+ * @mapped_size - size of the iova space mapped
+ * (may not be the same as the buffer size)
+ * @flags - iommu domain/partition specific flags.
+ *
+ * Represents a mapping of one ion buffer to a particular iommu domain
+ * and address range. There may exist other mappings of this buffer in
+ * different domains or address ranges. All mappings will have the same
+ * cacheability and security.
+ */
+struct ion_iommu_map {
+ unsigned long iova_addr;
+ struct rb_node node;
+ union {
+ int domain_info[DI_MAX];
+ uint64_t key;
+ };
+ struct ion_buffer *buffer;
+ struct kref ref;
+ int mapped_size;
+ unsigned long flags;
+};
+
+/**
+ * struct mem_map_data - represents information about the memory map for a heap
+ * @node: rb node used to store in the tree of mem_map_data
+ * @addr: start address of memory region.
+ * @addr: end address of memory region.
+ * @size: size of memory region
+ * @client_name: name of the client who owns this buffer.
+ *
+ */
+struct mem_map_data {
+ struct rb_node node;
+ ion_phys_addr_t addr;
+ ion_phys_addr_t addr_end;
+ unsigned long size;
+ const char *client_name;
+};
+
+#define iommu_map_domain(__m) ((__m)->domain_info[1])
+#define iommu_map_partition(__m) ((__m)->domain_info[0])
+
+struct ion_heap *ion_iommu_heap_create(struct ion_platform_heap *);
+void ion_iommu_heap_destroy(struct ion_heap *);
+
+struct ion_heap *ion_cp_heap_create(struct ion_platform_heap *);
+void ion_cp_heap_destroy(struct ion_heap *);
+
+#ifdef CONFIG_CMA
+struct ion_heap *ion_cma_heap_create(struct ion_platform_heap *);
+void ion_cma_heap_destroy(struct ion_heap *);
+
+struct ion_heap *ion_secure_cma_heap_create(struct ion_platform_heap *);
+void ion_secure_cma_heap_destroy(struct ion_heap *);
+#endif
+
+#define ION_CP_ALLOCATE_FAIL -1
+#define ION_RESERVED_ALLOCATE_FAIL -1
+
+/**
+ * ion_do_cache_op - do cache operations.
+ *
+ * @client - pointer to ION client.
+ * @handle - pointer to buffer handle.
+ * @uaddr - virtual address to operate on.
+ * @offset - offset from physical address.
+ * @len - Length of data to do cache operation on.
+ * @cmd - Cache operation to perform:
+ * ION_IOC_CLEAN_CACHES
+ * ION_IOC_INV_CACHES
+ * ION_IOC_CLEAN_INV_CACHES
+ *
+ * Returns 0 on success
+ */
+int ion_do_cache_op(struct ion_client *client, struct ion_handle *handle,
+ void *uaddr, unsigned long offset, unsigned long len,
+ unsigned int cmd);
+
+void ion_cp_heap_get_base(struct ion_heap *heap, unsigned long *base,
+ unsigned long *size);
+
+void ion_mem_map_show(struct ion_heap *heap);
+
+
+
+int ion_secure_handle(struct ion_client *client, struct ion_handle *handle,
+ int version, void *data, int flags);
+
+int ion_unsecure_handle(struct ion_client *client, struct ion_handle *handle);
+
+int ion_heap_allow_secure_allocation(enum ion_heap_type type);
+
+int ion_heap_allow_heap_secure(enum ion_heap_type type);
+
+int ion_heap_allow_handle_secure(enum ion_heap_type type);
+
+/**
+ * ion_create_chunked_sg_table - helper function to create sg table
+ * with specified chunk size
+ * @buffer_base: The starting address used for the sg dma address
+ * @chunk_size: The size of each entry in the sg table
+ * @total_size: The total size of the sg table (i.e. the sum of the
+ * entries). This will be rounded up to the nearest
+ * multiple of `chunk_size'
+ */
+struct sg_table *ion_create_chunked_sg_table(phys_addr_t buffer_base,
+ size_t chunk_size, size_t total_size);
+#endif /* _MSM_ION_PRIV_H */
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index 62b6a71..5589ff0 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -1859,7 +1859,8 @@
}
if (status)
KGSL_FT_ERR(rb->device,
- "Failed to find the command sequence after eop timestamp\n");
+ "Failed to find the command sequence after eop timestamp %x\n",
+ global_eop);
return status;
}
@@ -1972,44 +1973,38 @@
/* find the start of bad command sequence in rb */
context = idr_find(&device->context_idr, ft_data->context_id);
- /* Look for the command stream that is right after the global eop */
-
- if (!context) {
- /*
- * If there is no context then fault tolerance does not need to
- * replay anything, just reset GPU and thats it
- */
- return;
- }
ft_data->ft_policy = adreno_dev->ft_policy;
if (!ft_data->ft_policy)
ft_data->ft_policy = KGSL_FT_DEFAULT_POLICY;
+ /* Look for the command stream that is right after the global eop */
ret = _find_cmd_seq_after_eop_ts(rb, &rb_rptr,
ft_data->global_eop + 1, false);
if (ret) {
ft_data->ft_policy |= KGSL_FT_TEMP_DISABLE;
return;
- } else
+ } else {
+ ft_data->start_of_replay_cmds = rb_rptr;
ft_data->ft_policy &= ~KGSL_FT_TEMP_DISABLE;
+ }
- ft_data->start_of_replay_cmds = rb_rptr;
-
- adreno_context = context->devctxt;
- if (adreno_context->flags & CTXT_FLAGS_PREAMBLE) {
- if (ft_data->ib1) {
- ret = _find_hanging_ib_sequence(rb,
- &rb_rptr, ft_data->ib1);
- if (ret) {
- KGSL_FT_ERR(device,
- "Start not found for replay IB sequence\n");
- ret = 0;
- return;
+ if (context) {
+ adreno_context = context->devctxt;
+ if (adreno_context->flags & CTXT_FLAGS_PREAMBLE) {
+ if (ft_data->ib1) {
+ ret = _find_hanging_ib_sequence(rb,
+ &rb_rptr, ft_data->ib1);
+ if (ret) {
+ KGSL_FT_ERR(device,
+ "Start not found for replay IB seq\n");
+ ret = 0;
+ return;
+ }
+ ft_data->start_of_replay_cmds = rb_rptr;
+ ft_data->replay_for_snapshot = rb_rptr;
}
- ft_data->start_of_replay_cmds = rb_rptr;
- ft_data->replay_for_snapshot = rb_rptr;
}
}
}
@@ -2046,9 +2041,6 @@
_adreno_ft_restart_device(struct kgsl_device *device,
struct kgsl_context *context)
{
-
- struct adreno_context *adreno_context = context->devctxt;
-
/* restart device */
if (adreno_stop(device)) {
KGSL_FT_ERR(device, "Device stop failed\n");
@@ -2065,9 +2057,11 @@
return 1;
}
- if (context)
+ if (context) {
+ struct adreno_context *adreno_context = context->devctxt;
kgsl_mmu_setstate(&device->mmu, adreno_context->pagetable,
KGSL_MEMSTORE_GLOBAL);
+ }
/* If iommu is used then we need to make sure that the iommu clocks
* are on since there could be commands in pipeline that touch iommu */
@@ -2168,13 +2162,22 @@
struct adreno_context *adreno_context = NULL;
struct adreno_context *last_active_ctx = adreno_dev->drawctxt_active;
unsigned int long_ib = 0;
+ static int no_context_ft;
context = idr_find(&device->context_idr, ft_data->context_id);
if (context == NULL) {
KGSL_FT_ERR(device, "Last context unknown id:%d\n",
ft_data->context_id);
- goto play_good_cmds;
+ if (no_context_ft) {
+ /*
+ * If 2 consecutive no context ft occurred then
+ * just reset GPU
+ */
+ no_context_ft = 0;
+ goto play_good_cmds;
+ }
} else {
+ no_context_ft = 0;
adreno_context = context->devctxt;
adreno_context->flags |= CTXT_FLAGS_GPU_HANG;
/*
@@ -2230,7 +2233,7 @@
}
/* Do not try the reply if hang is due to a pagefault */
- if (adreno_context->pagefault) {
+ if (adreno_context && adreno_context->pagefault) {
if ((ft_data->context_id == adreno_context->id) &&
(ft_data->global_eop == adreno_context->pagefault_ts)) {
ft_data->ft_policy &= ~KGSL_FT_REPLAY;
@@ -2295,7 +2298,7 @@
/* EOF not found in RB, discard till EOF in
next IB submission */
- if (i == ft_data->bad_rb_size) {
+ if (adreno_context && (i == ft_data->bad_rb_size)) {
adreno_context->flags |= CTXT_FLAGS_SKIP_EOF;
KGSL_FT_INFO(device,
"EOF not found in RB, skip next issueib till EOF\n");
@@ -2332,8 +2335,14 @@
ft_data->good_rb_buffer, ft_data->good_rb_size);
if (ret) {
- /* If we fail here we can try to invalidate another
- * context and try fault tolerance again */
+ /*
+ * If we fail here we can try to invalidate another
+ * context and try fault tolerance again, although
+ * we will only try ft with no context once to avoid
+ * going into continuous loop of trying ft with no context
+ */
+ if (!context)
+ no_context_ft = 1;
ret = -EAGAIN;
KGSL_FT_ERR(device, "Playing good commands unsuccessful\n");
goto done;
@@ -3166,6 +3175,31 @@
"Fault tolerance no context found\n");
}
}
+ for (i = 0; i < ft_detect_regs_count; i++) {
+ if (curr_reg_val[i] != prev_reg_val[i]) {
+ fast_hang_detected = 0;
+
+ /* Check for long IB here */
+ if ((i >=
+ LONG_IB_DETECT_REG_INDEX_START)
+ &&
+ (i <=
+ LONG_IB_DETECT_REG_INDEX_END))
+ long_ib_detected = 0;
+ }
+ }
+
+ if (fast_hang_detected) {
+ KGSL_FT_ERR(device,
+ "Proc %s, ctxt_id %d ts %d triggered fault tolerance"
+ " on global ts %d\n",
+ curr_context ? curr_context->pid_name : "",
+ curr_context ? curr_context->id : 0,
+ (kgsl_readtimestamp(device, context,
+ KGSL_TIMESTAMP_RETIRED) + 1),
+ curr_global_ts + 1);
+ return 1;
+ }
if (curr_context != NULL) {
@@ -3175,31 +3209,6 @@
curr_context->pid_name, curr_context->ib_gpu_time_used,
curr_global_ts+1);
- for (i = 0; i < ft_detect_regs_count; i++) {
- if (curr_reg_val[i] != prev_reg_val[i]) {
- fast_hang_detected = 0;
-
- /* Check for long IB here */
- if ((i >=
- LONG_IB_DETECT_REG_INDEX_START)
- &&
- (i <=
- LONG_IB_DETECT_REG_INDEX_END))
- long_ib_detected = 0;
- }
- }
-
- if (fast_hang_detected) {
- KGSL_FT_ERR(device,
- "Proc %s, ctxt_id %d ts %d triggered fault tolerance"
- " on global ts %d\n",
- curr_context->pid_name, curr_context->id
- , (kgsl_readtimestamp(device, context,
- KGSL_TIMESTAMP_RETIRED)+1),
- curr_global_ts+1);
- return 1;
- }
-
if ((long_ib_detected) &&
(!(curr_context->flags &
CTXT_FLAGS_NO_FAULT_TOLERANCE))) {
@@ -3229,10 +3238,6 @@
}
}
}
- } else {
- KGSL_FT_ERR(device,
- "Last context unknown id:%d\n",
- curr_context_id);
}
} else {
/* GPU is moving forward */
diff --git a/drivers/gpu/msm/kgsl_drm.c b/drivers/gpu/msm/kgsl_drm.c
index 11d6ffa..007f89a 100644
--- a/drivers/gpu/msm/kgsl_drm.c
+++ b/drivers/gpu/msm/kgsl_drm.c
@@ -18,6 +18,7 @@
#include "drm.h"
#include <linux/msm_ion.h>
+#include <linux/genlock.h>
#include "kgsl.h"
#include "kgsl_device.h"
@@ -119,6 +120,8 @@
uint32_t gpuaddr;
} bufs[DRM_KGSL_GEM_MAX_BUFFERS];
+ struct genlock_handle *glock_handle[DRM_KGSL_GEM_MAX_BUFFERS];
+
int bound;
int lockpid;
/* Put these here to avoid allocing all the time */
@@ -154,6 +157,7 @@
kgsl_gem_alloc_memory(struct drm_gem_object *obj)
{
struct drm_kgsl_gem_object *priv = obj->driver_private;
+ struct kgsl_mmu *mmu;
struct sg_table *sg_table;
struct scatterlist *s;
int index;
@@ -165,7 +169,17 @@
return 0;
if (priv->pagetable == NULL) {
- priv->pagetable = kgsl_mmu_getpagetable(KGSL_MMU_GLOBAL_PT);
+ /* Hard coded to use A2X device for MSM7X27 and MSM8625
+ * Others to use A3X device
+ */
+#if defined(CONFIG_ARCH_MSM7X27) || defined(CONFIG_ARCH_MSM8625)
+ mmu = &kgsl_get_device(KGSL_DEVICE_2D0)->mmu;
+#else
+ mmu = &kgsl_get_device(KGSL_DEVICE_3D0)->mmu;
+#endif
+
+ priv->pagetable = kgsl_mmu_getpagetable(mmu,
+ KGSL_MMU_GLOBAL_PT);
if (priv->pagetable == NULL) {
DRM_ERROR("Unable to get the GPU MMU pagetable\n");
@@ -259,8 +273,7 @@
priv->memdesc.sglen++;
}
- result = kgsl_mmu_map(priv->pagetable, &priv->memdesc,
- GSL_PT_PAGE_RV | GSL_PT_PAGE_WV);
+ result = kgsl_mmu_map(priv->pagetable, &priv->memdesc);
if (result) {
DRM_ERROR(
"kgsl_mmu_map failed. result = %d\n", result);
@@ -293,6 +306,7 @@
kgsl_gem_free_memory(struct drm_gem_object *obj)
{
struct drm_kgsl_gem_object *priv = obj->driver_private;
+ int index;
if (!kgsl_gem_memory_allocated(obj) || TYPE_IS_FD(priv->type))
return;
@@ -311,6 +325,11 @@
memset(&priv->memdesc, 0, sizeof(priv->memdesc));
+ for (index = 0; index < priv->bufcount; index++) {
+ if (priv->glock_handle[index])
+ genlock_put_handle(priv->glock_handle[index]);
+ }
+
kgsl_mmu_putpagetable(priv->pagetable);
priv->pagetable = NULL;
@@ -552,6 +571,7 @@
struct scatterlist *s;
int ret, handle;
unsigned long size;
+ struct kgsl_mmu *mmu;
ion_handle = ion_import_dma_buf(kgsl_drm_ion_client, args->ion_fd);
if (IS_ERR_OR_NULL(ion_handle)) {
@@ -591,7 +611,13 @@
priv->type = DRM_KGSL_GEM_TYPE_KMEM;
list_add(&priv->list, &kgsl_mem_list);
- priv->pagetable = kgsl_mmu_getpagetable(KGSL_MMU_GLOBAL_PT);
+#if defined(CONFIG_ARCH_MSM7X27) || defined(CONFIG_ARCH_MSM8625)
+ mmu = &kgsl_get_device(KGSL_DEVICE_2D0)->mmu;
+#else
+ mmu = &kgsl_get_device(KGSL_DEVICE_3D0)->mmu;
+#endif
+
+ priv->pagetable = kgsl_mmu_getpagetable(mmu, KGSL_MMU_GLOBAL_PT);
priv->memdesc.pagetable = priv->pagetable;
@@ -619,8 +645,7 @@
priv->memdesc.sglen++;
}
- ret = kgsl_mmu_map(priv->pagetable, &priv->memdesc,
- GSL_PT_PAGE_RV | GSL_PT_PAGE_WV);
+ ret = kgsl_mmu_map(priv->pagetable, &priv->memdesc);
if (ret) {
DRM_ERROR("kgsl_mmu_map failed. ret = %d\n", ret);
ion_free(kgsl_drm_ion_client,
@@ -877,6 +902,68 @@
return ret;
}
+/* Get the genlock handles base off the GEM handle
+ */
+
+int
+kgsl_gem_get_glock_handles_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
+{
+ struct drm_kgsl_gem_glockinfo *args = data;
+ struct drm_gem_object *obj;
+ struct drm_kgsl_gem_object *priv;
+ int index;
+
+ obj = drm_gem_object_lookup(dev, file_priv, args->handle);
+
+ if (obj == NULL) {
+ DRM_ERROR("Invalid GEM handle %x\n", args->handle);
+ return -EBADF;
+ }
+
+ mutex_lock(&dev->struct_mutex);
+ priv = obj->driver_private;
+
+ for (index = 0; index < priv->bufcount; index++) {
+ args->glockhandle[index] = genlock_get_fd_handle(
+ priv->glock_handle[index]);
+ }
+
+ drm_gem_object_unreference(obj);
+ mutex_unlock(&dev->struct_mutex);
+ return 0;
+}
+
+int
+kgsl_gem_set_glock_handles_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
+{
+ struct drm_kgsl_gem_glockinfo *args = data;
+ struct drm_gem_object *obj;
+ struct drm_kgsl_gem_object *priv;
+ int index;
+
+ obj = drm_gem_object_lookup(dev, file_priv, args->handle);
+
+ if (obj == NULL) {
+ DRM_ERROR("Invalid GEM handle %x\n", args->handle);
+ return -EBADF;
+ }
+
+ mutex_lock(&dev->struct_mutex);
+ priv = obj->driver_private;
+
+ for (index = 0; index < priv->bufcount; index++) {
+ priv->glock_handle[index] = genlock_get_handle_fd(
+ args->glockhandle[index]);
+ }
+
+ drm_gem_object_unreference(obj);
+ mutex_unlock(&dev->struct_mutex);
+
+ return 0;
+}
+
int
kgsl_gem_set_bufcount_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv)
@@ -919,6 +1006,32 @@
}
int
+kgsl_gem_get_bufcount_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
+{
+ struct drm_kgsl_gem_bufcount *args = data;
+ struct drm_gem_object *obj;
+ struct drm_kgsl_gem_object *priv;
+
+ obj = drm_gem_object_lookup(dev, file_priv, args->handle);
+
+ if (obj == NULL) {
+ DRM_ERROR("Invalid GEM handle %x\n", args->handle);
+ return -EBADF;
+ }
+
+ mutex_lock(&dev->struct_mutex);
+ priv = obj->driver_private;
+
+ args->bufcount = priv->bufcount;
+
+ drm_gem_object_unreference(obj);
+ mutex_unlock(&dev->struct_mutex);
+
+ return 0;
+}
+
+int
kgsl_gem_set_active_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
@@ -1375,9 +1488,15 @@
DRM_IOCTL_DEF_DRV(KGSL_GEM_GET_BUFINFO, kgsl_gem_get_bufinfo_ioctl, 0),
DRM_IOCTL_DEF_DRV(KGSL_GEM_GET_ION_FD, kgsl_gem_get_ion_fd_ioctl, 0),
DRM_IOCTL_DEF_DRV(KGSL_GEM_CREATE_FROM_ION,
- kgsl_gem_create_from_ion_ioctl, 0),
+ kgsl_gem_create_from_ion_ioctl, 0),
DRM_IOCTL_DEF_DRV(KGSL_GEM_SET_BUFCOUNT,
- kgsl_gem_set_bufcount_ioctl, 0),
+ kgsl_gem_set_bufcount_ioctl, 0),
+ DRM_IOCTL_DEF_DRV(KGSL_GEM_GET_BUFCOUNT,
+ kgsl_gem_get_bufcount_ioctl, 0),
+ DRM_IOCTL_DEF_DRV(KGSL_GEM_SET_GLOCK_HANDLES_INFO,
+ kgsl_gem_set_glock_handles_ioctl, 0),
+ DRM_IOCTL_DEF_DRV(KGSL_GEM_GET_GLOCK_HANDLES_INFO,
+ kgsl_gem_get_glock_handles_ioctl, 0),
DRM_IOCTL_DEF_DRV(KGSL_GEM_SET_ACTIVE, kgsl_gem_set_active_ioctl, 0),
DRM_IOCTL_DEF_DRV(KGSL_GEM_LOCK_HANDLE,
kgsl_gem_lock_handle_ioctl, 0),
diff --git a/drivers/gpu/msm/kgsl_sync.c b/drivers/gpu/msm/kgsl_sync.c
index 0e3e046..813305a 100644
--- a/drivers/gpu/msm/kgsl_sync.c
+++ b/drivers/gpu/msm/kgsl_sync.c
@@ -69,6 +69,7 @@
struct kgsl_fence_event_priv {
struct kgsl_context *context;
+ unsigned int timestamp;
};
/**
@@ -85,7 +86,7 @@
void *priv, u32 context_id, u32 timestamp)
{
struct kgsl_fence_event_priv *ev = priv;
- kgsl_sync_timeline_signal(ev->context->timeline, timestamp);
+ kgsl_sync_timeline_signal(ev->context->timeline, ev->timestamp);
kgsl_context_put(ev->context);
kfree(ev);
}
@@ -125,6 +126,7 @@
if (event == NULL)
return -ENOMEM;
event->context = context;
+ event->timestamp = timestamp;
kgsl_context_get(context);
pt = kgsl_sync_pt_create(context->timeline, timestamp);
diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index 330c850..f35f0e7 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -49,7 +49,6 @@
config IOMMU_PGTABLES_L2
bool "Allow SMMU page tables in the L2 cache (Experimental)"
depends on MSM_IOMMU && MMU && SMP && CPU_DCACHE_DISABLE=n
- default y
help
Improves TLB miss latency at the expense of potential L2 pollution.
However, with large multimedia buffers, the TLB should mostly contain
diff --git a/drivers/media/dvb/dvb-core/dvb_demux.c b/drivers/media/dvb/dvb-core/dvb_demux.c
index 4740a80..3f73c4d 100644
--- a/drivers/media/dvb/dvb-core/dvb_demux.c
+++ b/drivers/media/dvb/dvb-core/dvb_demux.c
@@ -376,6 +376,10 @@
else
ccok = ((feed->cc + 1) & 0x0f) == cc;
+ /* discard TS packets holding sections with TEI bit set */
+ if (buf[1] & 0x80)
+ return -EINVAL;
+
feed->first_cc = 0;
feed->cc = cc;
diff --git a/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_common.c b/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_common.c
index 4e36e61..1a481ce 100644
--- a/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_common.c
+++ b/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_common.c
@@ -622,8 +622,77 @@
mpq_demux->sdmx_process_time_max = process_time;
}
-/* Extend dvb-demux debugfs with HW statistics */
-void mpq_dmx_init_hw_statistics(struct mpq_demux *mpq_demux)
+static int mpq_sdmx_log_level_open(struct inode *inode, struct file *file)
+{
+ file->private_data = inode->i_private;
+ return 0;
+}
+
+static ssize_t mpq_sdmx_log_level_read(struct file *fp,
+ char __user *user_buffer, size_t count, loff_t *position)
+{
+ char user_str[16];
+ struct mpq_demux *mpq_demux = fp->private_data;
+ int ret;
+
+ ret = scnprintf(user_str, 16, "%d", mpq_demux->sdmx_log_level);
+ ret = simple_read_from_buffer(user_buffer, count, position,
+ user_str, ret+1);
+
+ return ret;
+}
+
+static ssize_t mpq_sdmx_log_level_write(struct file *fp,
+ const char __user *user_buffer, size_t count, loff_t *position)
+{
+ char user_str[16];
+ int ret;
+ int ret_count;
+ int level;
+ struct mpq_demux *mpq_demux = fp->private_data;
+
+ if (count >= 16)
+ return -EINVAL;
+
+ ret_count = simple_write_to_buffer(user_str, 16, position, user_buffer,
+ count);
+ if (ret_count < 0)
+ return ret_count;
+
+ ret = sscanf(user_str, "%d", &level);
+ if (ret != 1)
+ return -EINVAL;
+
+ if (level < SDMX_LOG_NO_PRINT || level > SDMX_LOG_VERBOSE)
+ return -EINVAL;
+
+ mutex_lock(&mpq_demux->mutex);
+ mpq_demux->sdmx_log_level = level;
+ if (mpq_demux->sdmx_session_handle != SDMX_INVALID_SESSION_HANDLE) {
+ ret = sdmx_set_log_level(mpq_demux->sdmx_session_handle,
+ mpq_demux->sdmx_log_level);
+ if (ret) {
+ MPQ_DVB_ERR_PRINT(
+ "%s: Could not set sdmx log level. ret = %d\n",
+ __func__, ret);
+ mutex_unlock(&mpq_demux->mutex);
+ return -EINVAL;
+ }
+ }
+
+ mutex_unlock(&mpq_demux->mutex);
+ return ret_count;
+}
+
+static const struct file_operations sdmx_debug_fops = {
+ .open = mpq_sdmx_log_level_open,
+ .read = mpq_sdmx_log_level_read,
+ .write = mpq_sdmx_log_level_write,
+ .owner = THIS_MODULE,
+};
+
+/* Extend dvb-demux debugfs with common plug-in entries */
+void mpq_dmx_init_debugfs_entries(struct mpq_demux *mpq_demux)
{
/*
* Extend dvb-demux debugfs with HW statistics.
@@ -745,8 +814,14 @@
S_IRUGO | S_IWUSR | S_IWGRP,
mpq_demux->demux.dmx.debugfs_demux_dir,
&mpq_demux->sdmx_process_packets_min);
+
+ debugfs_create_file("sdmx_log_level",
+ S_IRUGO | S_IWUSR | S_IWGRP,
+ mpq_demux->demux.dmx.debugfs_demux_dir,
+ mpq_demux,
+ &sdmx_debug_fops);
}
-EXPORT_SYMBOL(mpq_dmx_init_hw_statistics);
+EXPORT_SYMBOL(mpq_dmx_init_debugfs_entries);
/* Update dvb-demux debugfs with HW notification statistics */
void mpq_dmx_update_hw_statistics(struct mpq_demux *mpq_demux)
@@ -908,6 +983,7 @@
mpq_demux->sdmx_filter_count = 0;
mpq_demux->sdmx_session_handle = SDMX_INVALID_SESSION_HANDLE;
mpq_demux->sdmx_eos = 0;
+ mpq_demux->sdmx_log_level = SDMX_LOG_NO_PRINT;
if (mpq_demux->demux.feednum > MPQ_MAX_DMX_FILES) {
MPQ_DVB_ERR_PRINT(
@@ -3493,6 +3569,15 @@
return -EINVAL;
}
+ ret = sdmx_set_log_level(mpq_demux->sdmx_session_handle,
+ mpq_demux->sdmx_log_level);
+ if (ret != SDMX_SUCCESS) {
+ MPQ_DVB_ERR_PRINT("%s: Could not set log level. ret=%d\n",
+ __func__, ret);
+ /* Don't fail open session if just log level setting failed */
+ ret = 0;
+ }
+
mpq_demux->sdmx_process_count = 0;
mpq_demux->sdmx_process_time_sum = 0;
mpq_demux->sdmx_process_time_average = 0;
diff --git a/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_common.h b/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_common.h
index 4abf088..4c2a9f4 100644
--- a/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_common.h
+++ b/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_common.h
@@ -438,6 +438,7 @@
u32 sdmx_process_packets_sum;
u32 sdmx_process_packets_average;
u32 sdmx_process_packets_min;
+ enum sdmx_log_level sdmx_log_level;
struct timespec decoder_out_last_time;
struct timespec last_notification_time;
@@ -622,12 +623,13 @@
int mpq_dmx_process_pcr_packet(struct dvb_demux_feed *feed, const u8 *buf);
/**
- * mpq_dmx_init_hw_statistics -
- * Extend dvb-demux debugfs with HW statistics.
+ * mpq_dmx_init_debugfs_entries -
+ * Extend dvb-demux debugfs with mpq related entries (HW statistics and secure
+ * demux log level).
*
* @mpq_demux: The mpq_demux device to initialize.
*/
-void mpq_dmx_init_hw_statistics(struct mpq_demux *mpq_demux);
+void mpq_dmx_init_debugfs_entries(struct mpq_demux *mpq_demux);
/**
* mpq_dmx_update_hw_statistics -
diff --git a/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_tsif.c b/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_tsif.c
index 026d1cb..0d40520 100644
--- a/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_tsif.c
+++ b/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_tsif.c
@@ -719,7 +719,7 @@
}
/* Extend dvb-demux debugfs with TSIF statistics. */
- mpq_dmx_init_hw_statistics(mpq_demux);
+ mpq_dmx_init_debugfs_entries(mpq_demux);
return 0;
diff --git a/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_tspp_v1.c b/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_tspp_v1.c
index e263aef..f0f8fa9 100644
--- a/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_tspp_v1.c
+++ b/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_tspp_v1.c
@@ -1774,7 +1774,7 @@
}
/* Extend dvb-demux debugfs with TSPP statistics. */
- mpq_dmx_init_hw_statistics(mpq_demux);
+ mpq_dmx_init_debugfs_entries(mpq_demux);
return 0;
diff --git a/drivers/media/platform/msm/dvb/demux/mpq_sdmx.c b/drivers/media/platform/msm/dvb/demux/mpq_sdmx.c
index 946b055..14d3a39 100644
--- a/drivers/media/platform/msm/dvb/demux/mpq_sdmx.c
+++ b/drivers/media/platform/msm/dvb/demux/mpq_sdmx.c
@@ -38,7 +38,9 @@
SDMX_PROCESS_CMD,
SDMX_GET_DBG_COUNTERS_CMD,
SDMX_RESET_DBG_COUNTERS_CMD,
- SDMX_GET_VERSION_CMD
+ SDMX_GET_VERSION_CMD,
+ SDMX_INVALIDATE_KL_CMD,
+ SDMX_SET_LOG_LEVEL_CMD
};
struct sdmx_proc_req {
@@ -184,6 +186,15 @@
int32_t version;
};
+struct sdmx_set_log_level_req {
+ enum sdmx_cmd_id cmd_id;
+ enum sdmx_log_level level;
+ u32 session_handle;
+};
+
+struct sdmx_set_log_level_rsp {
+ enum sdmx_status ret;
+};
static void get_cmd_rsp_buffers(int handle_index,
void **cmd,
int *cmd_len,
@@ -935,3 +946,48 @@
return ret;
}
EXPORT_SYMBOL(sdmx_reset_dbg_counters);
+
+/*
+ * Set debug log verbosity level
+ *
+ * @session_handle: secure demux instance
+ * @level: requested log level
+ *
+ * Return error code
+ */
+int sdmx_set_log_level(int session_handle, enum sdmx_log_level level)
+{
+ int res, cmd_len, rsp_len;
+ struct sdmx_set_log_level_req *cmd;
+ struct sdmx_set_log_level_rsp *rsp;
+ enum sdmx_status ret;
+
+ cmd_len = sizeof(struct sdmx_set_log_level_req);
+ rsp_len = sizeof(struct sdmx_set_log_level_rsp);
+
+ /* Get command and response buffers */
+ get_cmd_rsp_buffers(session_handle, (void **)&cmd, &cmd_len,
+ (void **)&rsp, &rsp_len);
+
+ /* Lock shared memory */
+ mutex_lock(&sdmx_lock[session_handle]);
+
+ /* Populate command struct */
+ cmd->cmd_id = SDMX_SET_LOG_LEVEL_CMD;
+ cmd->session_handle = session_handle;
+ cmd->level = level;
+
+ /* Issue QSEECom command */
+ res = qseecom_send_command(sdmx_qseecom_handles[session_handle],
+ (void *)cmd, cmd_len, (void *)rsp, rsp_len);
+ if (res < 0) {
+ mutex_unlock(&sdmx_lock[session_handle]);
+ return SDMX_STATUS_GENERAL_FAILURE;
+ }
+ ret = rsp->ret;
+
+ /* Unlock */
+ mutex_unlock(&sdmx_lock[session_handle]);
+ return ret;
+}
+
diff --git a/drivers/media/platform/msm/dvb/demux/mpq_sdmx.h b/drivers/media/platform/msm/dvb/demux/mpq_sdmx.h
index f9d85aa..6b669e4 100644
--- a/drivers/media/platform/msm/dvb/demux/mpq_sdmx.h
+++ b/drivers/media/platform/msm/dvb/demux/mpq_sdmx.h
@@ -78,6 +78,13 @@
SDMX_195_BYTE_PKT = 195,
};
+enum sdmx_log_level {
+ SDMX_LOG_NO_PRINT,
+ SDMX_LOG_MSG_ERROR,
+ SDMX_LOG_DEBUG,
+ SDMX_LOG_VERBOSE
+};
+
enum sdmx_status {
SDMX_SUCCESS = 0,
SDMX_STATUS_GENERAL_FAILURE = -1,
@@ -250,4 +257,6 @@
int sdmx_reset_dbg_counters(int session_handle);
+int sdmx_set_log_level(int session_handle, enum sdmx_log_level level);
+
#endif /* _MPQ_SDMX_H */
diff --git a/drivers/media/platform/msm/wfd/enc-venus-subdev.c b/drivers/media/platform/msm/wfd/enc-venus-subdev.c
index b719b3f..4f7fb44 100644
--- a/drivers/media/platform/msm/wfd/enc-venus-subdev.c
+++ b/drivers/media/platform/msm/wfd/enc-venus-subdev.c
@@ -28,6 +28,7 @@
#define BUF_TYPE_INPUT V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
static struct ion_client *venc_ion_client;
+static long venc_secure(struct v4l2_subdev *sd);
struct index_bitmap {
unsigned long *bitmap;
@@ -321,8 +322,9 @@
goto venc_open_fail;
}
- inst->secure = false;
inst->vmops = *vmops;
+ inst->secure = vmops->secure; /* We need to inform vidc, but defer
+ until after s_fmt() */
INIT_LIST_HEAD(&inst->registered_output_bufs.list);
INIT_LIST_HEAD(&inst->registered_input_bufs.list);
init_completion(&inst->dq_complete);
@@ -903,6 +905,15 @@
WFD_MSG_ERR("Failed to format for input port\n");
goto venc_set_format_fail;
}
+
+ /* If the device was secured previously, we need to inform vidc _now_ */
+ if (inst->secure) {
+ rc = venc_secure(sd);
+ if (rc) {
+ WFD_MSG_ERR("Failed secure vidc\n");
+ goto venc_set_format_fail;
+ }
+ }
venc_set_format_fail:
return rc;
}
@@ -1329,12 +1340,6 @@
rc = -EEXIST;
}
- if (inst->secure) {
- /* Nothing to do! */
- rc = 0;
- goto secure_fail;
- }
-
ctrl.id = V4L2_CID_MPEG_VIDC_VIDEO_SECURE;
rc = msm_vidc_s_ctrl(inst->vidc_context, &ctrl);
if (rc) {
@@ -1342,7 +1347,6 @@
goto secure_fail;
}
- inst->secure = true;
secure_fail:
return rc;
}
@@ -1419,9 +1423,6 @@
case SET_FRAMERATE_MODE:
rc = venc_set_framerate_mode(sd, arg);
break;
- case ENC_SECURE:
- rc = venc_secure(sd);
- break;
default:
WFD_MSG_ERR("Unknown ioctl %d to enc-subdev\n", cmd);
rc = -ENOTSUPP;
diff --git a/drivers/media/platform/msm/wfd/mdp-5-subdev.c b/drivers/media/platform/msm/wfd/mdp-5-subdev.c
index 16de0d4..55386b9 100644
--- a/drivers/media/platform/msm/wfd/mdp-5-subdev.c
+++ b/drivers/media/platform/msm/wfd/mdp-5-subdev.c
@@ -26,6 +26,8 @@
struct switch_dev sdev;
};
+static int mdp_secure(struct v4l2_subdev *sd, void *arg);
+
int mdp_init(struct v4l2_subdev *sd, u32 val)
{
return 0;
@@ -47,10 +49,6 @@
WFD_MSG_ERR("Invalid arguments\n");
rc = -EINVAL;
goto mdp_open_fail;
- } else if (mops->secure) {
- /* Deprecated API; use MDP_SECURE ioctl */
- WFD_MSG_ERR("Deprecated API for securing subdevice\n");
- return -ENOTSUPP;
}
fbi = msm_fb_get_writeback_fb();
@@ -66,12 +64,25 @@
WFD_MSG_ERR("WFD switch registration failed\n");
goto mdp_open_fail;
}
+
msm_fb_writeback_init(fbi);
+
inst->mdp = fbi;
inst->secure = mops->secure;
+ if (mops->secure) {
+ rc = mdp_secure(sd, inst);
+ if (rc) {
+ WFD_MSG_ERR("Couldn't secure MDP\n");
+ goto mdp_secure_fail;
+ }
+ }
+
mops->cookie = inst;
- return rc;
+ return 0;
+mdp_secure_fail:
+ switch_dev_unregister(&inst->sdev);
+ msm_fb_writeback_terminate(inst->mdp);
mdp_open_fail:
kfree(inst);
return rc;
@@ -118,7 +129,8 @@
}
return 0;
}
-int mdp_close(struct v4l2_subdev *sd, void *arg)
+
+static int mdp_close(struct v4l2_subdev *sd, void *arg)
{
struct mdp_instance *inst = arg;
struct fb_info *fbi = NULL;
@@ -133,7 +145,8 @@
}
return 0;
}
-int mdp_q_buffer(struct v4l2_subdev *sd, void *arg)
+
+static int mdp_q_buffer(struct v4l2_subdev *sd, void *arg)
{
int rc = 0;
struct mdp_buf_info *binfo = arg;
@@ -161,7 +174,8 @@
WFD_MSG_ERR("Failed to queue buffer\n");
return rc;
}
-int mdp_dq_buffer(struct v4l2_subdev *sd, void *arg)
+
+static int mdp_dq_buffer(struct v4l2_subdev *sd, void *arg)
{
int rc = 0;
struct mdp_buf_info *obuf = arg;
@@ -184,7 +198,8 @@
obuf->cookie = (void *)fbdata.priv;
return rc;
}
-int mdp_set_prop(struct v4l2_subdev *sd, void *arg)
+
+static int mdp_set_prop(struct v4l2_subdev *sd, void *arg)
{
struct mdp_prop *prop = (struct mdp_prop *)arg;
struct mdp_instance *inst = prop->inst;
@@ -197,7 +212,7 @@
return 0;
}
-int mdp_mmap(struct v4l2_subdev *sd, void *arg)
+static int mdp_mmap(struct v4l2_subdev *sd, void *arg)
{
int rc = 0, align = 0;
struct mem_region_map *mmap = arg;
@@ -250,7 +265,7 @@
return rc;
}
-int mdp_munmap(struct v4l2_subdev *sd, void *arg)
+static int mdp_munmap(struct v4l2_subdev *sd, void *arg)
{
struct mem_region_map *mmap = arg;
struct mem_region *mregion;
@@ -278,7 +293,7 @@
return 0;
}
-int mdp_secure(struct v4l2_subdev *sd, void *arg)
+static int mdp_secure(struct v4l2_subdev *sd, void *arg)
{
struct mdp_instance *inst = NULL;
int rc = 0;
@@ -331,9 +346,6 @@
case MDP_MUNMAP:
rc = mdp_munmap(sd, arg);
break;
- case MDP_SECURE:
- rc = mdp_secure(sd, arg);
- break;
default:
WFD_MSG_ERR("IOCTL: %u not supported\n", cmd);
rc = -EINVAL;
diff --git a/drivers/media/platform/msm/wfd/wfd-ioctl.c b/drivers/media/platform/msm/wfd/wfd-ioctl.c
index 1d3c9f55..af3cd69 100644
--- a/drivers/media/platform/msm/wfd/wfd-ioctl.c
+++ b/drivers/media/platform/msm/wfd/wfd-ioctl.c
@@ -1040,30 +1040,9 @@
{
int rc = 0;
struct wfd_device *wfd_dev = video_drvdata(filp);
- struct wfd_inst *inst = file_to_inst(filp);
- switch (a->id) {
- case V4L2_CID_MPEG_VIDC_VIDEO_SECURE:
- rc = v4l2_subdev_call(&wfd_dev->enc_sdev, core,
- ioctl, ENC_SECURE, NULL);
- if (rc) {
- WFD_MSG_ERR("Couldn't secure encoder");
- break;
- }
-
- rc = v4l2_subdev_call(&wfd_dev->mdp_sdev, core,
- ioctl, MDP_SECURE, (void *)inst->mdp_inst);
- if (rc) {
- WFD_MSG_ERR("Couldn't secure MDP");
- break;
- }
-
- wfd_dev->secure = true;
- break;
- default:
- rc = v4l2_subdev_call(&wfd_dev->enc_sdev, core,
- ioctl, SET_PROP, a);
- }
+ rc = v4l2_subdev_call(&wfd_dev->enc_sdev, core,
+ ioctl, SET_PROP, a);
if (rc)
WFD_MSG_ERR("Failed to set encoder property\n");
diff --git a/drivers/net/ethernet/msm/msm_rmnet_wwan.c b/drivers/net/ethernet/msm/msm_rmnet_wwan.c
index fe1ac46..f90ee3d 100644
--- a/drivers/net/ethernet/msm/msm_rmnet_wwan.c
+++ b/drivers/net/ethernet/msm/msm_rmnet_wwan.c
@@ -34,6 +34,7 @@
#include <mach/ipa.h>
#define WWAN_DEV_NAME "rmnet%d"
+#define WWAN_METADATA_SHFT 16
#define WWAN_METADATA_MASK 0x00FF0000
#define IPA_RM_INACTIVITY_TIMER 1000
#define WWAN_DEVICE_COUNT (8)
@@ -304,13 +305,15 @@
rx_ipv4_property = &rx_properties.prop[0];
rx_ipv4_property->ip = IPA_IP_v4;
rx_ipv4_property->attrib.attrib_mask |= IPA_FLT_META_DATA;
- rx_ipv4_property->attrib.meta_data = wwan_ptr->ch_id;
+ rx_ipv4_property->attrib.meta_data =
+ wwan_ptr->ch_id << WWAN_METADATA_SHFT;
rx_ipv4_property->attrib.meta_data_mask = WWAN_METADATA_MASK;
rx_ipv4_property->src_pipe = IPA_CLIENT_A2_EMBEDDED_PROD;
rx_ipv6_property = &rx_properties.prop[1];
rx_ipv6_property->ip = IPA_IP_v6;
rx_ipv6_property->attrib.attrib_mask |= IPA_FLT_META_DATA;
- rx_ipv6_property->attrib.meta_data = wwan_ptr->ch_id;
+ rx_ipv6_property->attrib.meta_data =
+ wwan_ptr->ch_id << WWAN_METADATA_SHFT;
rx_ipv6_property->attrib.meta_data_mask = WWAN_METADATA_MASK;
rx_ipv6_property->src_pipe = IPA_CLIENT_A2_EMBEDDED_PROD;
rx_properties.num_props = 2;
diff --git a/drivers/platform/msm/sps/sps_bam.c b/drivers/platform/msm/sps/sps_bam.c
index a117943..a84d99e 100644
--- a/drivers/platform/msm/sps/sps_bam.c
+++ b/drivers/platform/msm/sps/sps_bam.c
@@ -105,7 +105,7 @@
for (n = 0; n < ARRAY_SIZE(opt_event_table); n++) {
if ((u32)opt_event_table[n].option !=
(u32)opt_event_table[n].pipe_irq) {
- SPS_ERR("sps:SPS_O 0x%x != HAL IRQ 0x%x",
+ SPS_ERR("sps:SPS_O 0x%x != HAL IRQ 0x%x\n",
opt_event_table[n].option,
opt_event_table[n].pipe_irq);
return SPS_ERROR;
@@ -141,11 +141,11 @@
source = bam_check_irq_source(dev->base, dev->props.ee,
mask, &cb_case);
- SPS_DBG1("sps:bam_isr:bam=0x%x;source=0x%x;mask=0x%x.",
+ SPS_DBG1("sps:bam_isr:bam=0x%x;source=0x%x;mask=0x%x.\n",
BAM_ID(dev), source, mask);
if ((source & (1UL << 31)) && (dev->props.callback)) {
- SPS_INFO("sps:bam_isr:bam=0x%x;callback for case %d.",
+ SPS_INFO("sps:bam_isr:bam=0x%x;callback for case %d.\n",
BAM_ID(dev), cb_case);
dev->props.callback(cb_case, dev->props.user);
}
@@ -156,7 +156,7 @@
/* If MTIs are used, must poll each active pipe */
source = dev->pipe_active_mask;
- SPS_DBG1("sps:bam_isr for MTI:bam=0x%x;source=0x%x.",
+ SPS_DBG1("sps:bam_isr for MTI:bam=0x%x;source=0x%x.\n",
BAM_ID(dev), source);
}
@@ -177,7 +177,7 @@
/* Process any inactive pipe sources */
if (source) {
- SPS_ERR("sps:IRQ from BAM 0x%x inactive pipe(s) 0x%x",
+ SPS_ERR("sps:IRQ from BAM 0x%x inactive pipe(s) 0x%x\n",
BAM_ID(dev), source);
dev->irq_from_disabled_pipe++;
}
@@ -204,7 +204,7 @@
/* Is there any access to this BAM? */
if ((dev->props.manage & SPS_BAM_MGR_ACCESS_MASK) == SPS_BAM_MGR_NONE) {
- SPS_ERR("sps:No local access to BAM 0x%x", BAM_ID(dev));
+ SPS_ERR("sps:No local access to BAM 0x%x\n", BAM_ID(dev));
return SPS_ERROR;
}
@@ -222,7 +222,7 @@
IRQF_TRIGGER_HIGH, "sps", dev);
if (result) {
- SPS_ERR("sps:Failed to enable BAM 0x%x IRQ %d",
+ SPS_ERR("sps:Failed to enable BAM 0x%x IRQ %d\n",
BAM_ID(dev), dev->props.irq);
return SPS_ERROR;
}
@@ -236,13 +236,13 @@
result = enable_irq_wake(dev->props.irq);
if (result) {
- SPS_ERR("sps:Fail to enable wakeup irq "
- "BAM 0x%x IRQ %d",
+ SPS_ERR(
+ "sps:Fail to enable wakeup irq for BAM 0x%x IRQ %d\n",
BAM_ID(dev), dev->props.irq);
return SPS_ERROR;
} else
- SPS_DBG2("sps:Enable wakeup irq for "
- "BAM 0x%x IRQ %d",
+ SPS_DBG2(
+ "sps:Enable wakeup irq for BAM 0x%x IRQ %d\n",
BAM_ID(dev), dev->props.irq);
}
}
@@ -262,7 +262,7 @@
rc = bam_check(dev->base, &dev->version, &num_pipes);
if (rc) {
- SPS_ERR("sps:Fail to init BAM 0x%x IRQ %d",
+ SPS_ERR("sps:Fail to init BAM 0x%x IRQ %d\n",
BAM_ID(dev), dev->props.irq);
return SPS_ERROR;
}
@@ -281,7 +281,7 @@
* must use MTI. Thus, force EE index to a non-zero value to
* insure that EE zero globals can't be modified.
*/
- SPS_ERR("sps:EE for satellite BAM must be set to non-zero.");
+ SPS_ERR("sps:EE for satellite BAM must be set to non-zero.\n");
return SPS_ERROR;
}
@@ -295,8 +295,9 @@
MTIenabled) {
if (dev->props.irq_gen_addr == 0 ||
dev->props.irq_gen_addr == SPS_ADDR_INVALID) {
- SPS_ERR("sps:MTI destination address not specified "
- "for BAM 0x%x", BAM_ID(dev));
+ SPS_ERR(
+ "sps:MTI destination address not specified for BAM 0x%x\n",
+ BAM_ID(dev));
return SPS_ERROR;
}
dev->state |= BAM_STATE_MTI;
@@ -304,13 +305,13 @@
if (num_pipes) {
dev->props.num_pipes = num_pipes;
- SPS_DBG1("sps:BAM 0x%x number of pipes reported by hw: %d",
+ SPS_DBG1("sps:BAM 0x%x number of pipes reported by hw: %d\n",
BAM_ID(dev), dev->props.num_pipes);
}
/* Check EE index */
if (!MTIenabled && dev->props.ee >= SPS_BAM_NUM_EES) {
- SPS_ERR("sps:Invalid EE BAM 0x%x: %d", BAM_ID(dev),
+ SPS_ERR("sps:Invalid EE BAM 0x%x: %d\n", BAM_ID(dev),
dev->props.ee);
return SPS_ERROR;
}
@@ -323,8 +324,9 @@
struct sps_bam_sec_config_props *p_sec =
dev->props.p_sec_config_props;
if (p_sec == NULL) {
- SPS_ERR("sps:EE config table is not specified for "
- "BAM 0x%x", BAM_ID(dev));
+ SPS_ERR(
+ "sps:EE config table is not specified for BAM 0x%x\n",
+ BAM_ID(dev));
return SPS_ERROR;
}
@@ -351,9 +353,8 @@
for (i = n + 1; i < SPS_BAM_NUM_EES; i++) {
if ((p_sec->ees[n].pipe_mask &
p_sec->ees[i].pipe_mask) != 0) {
- SPS_ERR("sps:Overlapping pipe "
- "assignments for BAM "
- "0x%x: EEs %d and %d",
+ SPS_ERR(
+ "sps:Overlapping pipe assignments for BAM 0x%x: EEs %d and %d\n",
BAM_ID(dev), n, i);
return SPS_ERROR;
}
@@ -432,7 +433,7 @@
/* Is there any access to this BAM? */
if ((dev->props.manage & SPS_BAM_MGR_ACCESS_MASK) == SPS_BAM_MGR_NONE) {
- SPS_ERR("sps:No local access to BAM 0x%x", BAM_ID(dev));
+ SPS_ERR("sps:No local access to BAM 0x%x\n", BAM_ID(dev));
return SPS_ERROR;
}
@@ -456,7 +457,7 @@
dev->state &= ~BAM_STATE_ENABLED;
- SPS_DBG2("sps:BAM 0x%x disabled", BAM_ID(dev));
+ SPS_DBG2("sps:BAM 0x%x disabled\n", BAM_ID(dev));
return 0;
}
@@ -467,7 +468,7 @@
int sps_bam_device_init(struct sps_bam *dev)
{
if (dev->props.virt_addr == NULL) {
- SPS_ERR("sps:NULL BAM virtual address");
+ SPS_ERR("sps:NULL BAM virtual address\n");
return SPS_ERROR;
}
dev->base = (void *) dev->props.virt_addr;
@@ -475,7 +476,7 @@
if (dev->props.num_pipes == 0) {
/* Assume max number of pipes until BAM registers can be read */
dev->props.num_pipes = BAM_MAX_PIPES;
- SPS_DBG2("sps:BAM 0x%x: assuming max number of pipes: %d",
+ SPS_DBG2("sps:BAM 0x%x: assuming max number of pipes: %d\n",
BAM_ID(dev), dev->props.num_pipes);
}
@@ -491,11 +492,11 @@
if ((dev->props.options & SPS_BAM_OPT_ENABLE_AT_BOOT))
if (sps_bam_enable(dev)) {
- SPS_ERR("sps:Fail to enable bam device");
+ SPS_ERR("sps:Fail to enable bam device\n");
return SPS_ERROR;
}
- SPS_DBG2("sps:BAM device: phys 0x%x IRQ %d",
+ SPS_DBG2("sps:BAM device: phys 0x%x IRQ %d\n",
BAM_ID(dev), dev->props.irq);
return 0;
@@ -509,7 +510,7 @@
{
int result;
- SPS_DBG2("sps:BAM device DEINIT: phys 0x%x IRQ %d",
+ SPS_DBG2("sps:BAM device DEINIT: phys 0x%x IRQ %d\n",
BAM_ID(dev), dev->props.irq);
result = sps_bam_disable(dev);
@@ -527,7 +528,7 @@
u32 pipe_index;
int result;
- SPS_DBG2("sps:BAM device RESET: phys 0x%x IRQ %d",
+ SPS_DBG2("sps:BAM device RESET: phys 0x%x IRQ %d\n",
BAM_ID(dev), dev->props.irq);
/* If BAM is enabled, then disable */
@@ -538,8 +539,8 @@
pipe_index++) {
pipe = dev->pipes[pipe_index];
if (BAM_PIPE_IS_ASSIGNED(pipe)) {
- SPS_ERR("sps:BAM device 0x%x RESET failed: "
- "pipe %d in use",
+ SPS_ERR(
+ "sps:BAM device 0x%x RESET failed: pipe %d in use\n",
BAM_ID(dev), pipe_index);
result = SPS_ERROR;
break;
@@ -591,8 +592,9 @@
if (pipe_index == SPS_BAM_PIPE_INVALID) {
/* Allocate a pipe from the BAM */
if ((dev->props.manage & SPS_BAM_MGR_PIPE_NO_ALLOC)) {
- SPS_ERR("sps:Restricted from allocating pipes "
- "on BAM 0x%x", BAM_ID(dev));
+ SPS_ERR(
+ "sps:Restricted from allocating pipes on BAM 0x%x\n",
+ BAM_ID(dev));
return SPS_BAM_PIPE_INVALID;
}
for (pipe_index = 0, pipe_mask = 1;
@@ -605,24 +607,25 @@
break; /* Found an available pipe */
}
if (pipe_index >= dev->props.num_pipes) {
- SPS_ERR("sps:Fail to allocate pipe on BAM 0x%x",
+ SPS_ERR("sps:Fail to allocate pipe on BAM 0x%x\n",
BAM_ID(dev));
return SPS_BAM_PIPE_INVALID;
}
} else {
/* Check that client-specified pipe is available */
if (pipe_index >= dev->props.num_pipes) {
- SPS_ERR("sps:Invalid pipe %d for allocate on BAM 0x%x",
+ SPS_ERR(
+ "sps:Invalid pipe %d for allocate on BAM 0x%x\n",
pipe_index, BAM_ID(dev));
return SPS_BAM_PIPE_INVALID;
}
if ((dev->props.restricted_pipes & (1UL << pipe_index))) {
- SPS_ERR("sps:BAM 0x%x pipe %d is not local",
+ SPS_ERR("sps:BAM 0x%x pipe %d is not local\n",
BAM_ID(dev), pipe_index);
return SPS_BAM_PIPE_INVALID;
}
if (dev->pipes[pipe_index] != NULL) {
- SPS_ERR("sps:Pipe %d already allocated on BAM 0x%x",
+ SPS_ERR("sps:Pipe %d already allocated on BAM 0x%x\n",
pipe_index, BAM_ID(dev));
return SPS_BAM_PIPE_INVALID;
}
@@ -643,7 +646,7 @@
struct sps_pipe *pipe;
if (pipe_index >= dev->props.num_pipes) {
- SPS_ERR("sps:Invalid BAM 0x%x pipe: %d", BAM_ID(dev),
+ SPS_ERR("sps:Invalid BAM 0x%x pipe: %d\n", BAM_ID(dev),
pipe_index);
return;
}
@@ -654,8 +657,8 @@
/* Is the pipe currently allocated? */
if (pipe == NULL) {
- SPS_ERR("sps:Attempt to free unallocated pipe %d on "
- "BAM 0x%x", pipe_index, BAM_ID(dev));
+ SPS_ERR("sps:Attempt to free unallocated pipe %d on BAM 0x%x\n",
+ pipe_index, BAM_ID(dev));
return;
}
@@ -666,7 +669,7 @@
if (!list_empty(&pipe->sys.events_q)) {
struct sps_q_event *sps_event;
- SPS_ERR("sps:Disconnect BAM 0x%x pipe %d with events pending",
+ SPS_ERR("sps:Disconnect BAM 0x%x pipe %d with events pending\n",
BAM_ID(dev), pipe_index);
sps_event = list_entry((&pipe->sys.events_q)->next,
@@ -730,7 +733,7 @@
dev = map_pipe->bam;
pipe_index = map_pipe->pipe_index;
if (pipe_index >= dev->props.num_pipes) {
- SPS_ERR("sps:Invalid BAM 0x%x pipe: %d", BAM_ID(dev),
+ SPS_ERR("sps:Invalid BAM 0x%x pipe: %d\n", BAM_ID(dev),
pipe_index);
return SPS_ERROR;
}
@@ -741,14 +744,14 @@
/* Verify that control of this pipe is allowed */
if ((dev->props.manage & SPS_BAM_MGR_PIPE_NO_CTRL) ||
(dev->props.restricted_pipes & (1UL << pipe_index))) {
- SPS_ERR("sps:BAM 0x%x pipe %d is not local",
+ SPS_ERR("sps:BAM 0x%x pipe %d is not local\n",
BAM_ID(dev), pipe_index);
return SPS_ERROR;
}
/* Control without configuration permission is not supported yet */
if ((dev->props.manage & SPS_BAM_MGR_PIPE_NO_CONFIG)) {
- SPS_ERR("sps:BAM 0x%x pipe %d remote config is not supported",
+ SPS_ERR("sps:BAM 0x%x pipe %d remote config is not supported\n",
BAM_ID(dev), pipe_index);
return SPS_ERROR;
}
@@ -766,8 +769,9 @@
if (map->desc.phys_base == SPS_ADDR_INVALID ||
map->data.phys_base == SPS_ADDR_INVALID ||
map->desc.size == 0 || map->data.size == 0) {
- SPS_ERR("sps:FIFO buffers are not allocated for BAM "
- "0x%x pipe %d.", BAM_ID(dev), pipe_index);
+ SPS_ERR(
+ "sps:FIFO buffers are not allocated for BAM 0x%x pipe %d.\n",
+ BAM_ID(dev), pipe_index);
return SPS_ERROR;
}
hw_params.data_base = map->data.phys_base;
@@ -799,8 +803,8 @@
/* Get virtual address for descriptor FIFO */
if (map->desc.phys_base != SPS_ADDR_INVALID) {
if (map->desc.size < (2 * sizeof(struct sps_iovec))) {
- SPS_ERR("sps:Invalid descriptor FIFO size "
- "for BAM 0x%x pipe %d: %d",
+ SPS_ERR(
+ "sps:Invalid descriptor FIFO size for BAM 0x%x pipe %d: %d\n",
BAM_ID(dev), pipe_index, map->desc.size);
return SPS_ERROR;
}
@@ -833,7 +837,7 @@
/* Check pipe allocation */
if (dev->pipes[pipe_index] != BAM_PIPE_UNASSIGNED) {
- SPS_ERR("sps:Invalid pipe %d on BAM 0x%x for connect",
+ SPS_ERR("sps:Invalid pipe %d on BAM 0x%x for connect\n",
pipe_index, BAM_ID(dev));
return SPS_ERROR;
}
@@ -850,7 +854,7 @@
}
if (bam_pipe_init(dev->base, pipe_index, &hw_params, dev->props.ee)) {
- SPS_ERR("sps:BAM 0x%x pipe %d init error",
+ SPS_ERR("sps:BAM 0x%x pipe %d init error\n",
BAM_ID(dev), pipe_index);
goto exit_err;
}
@@ -925,7 +929,7 @@
int result;
if (pipe_index >= dev->props.num_pipes) {
- SPS_ERR("sps:Invalid BAM 0x%x pipe: %d", BAM_ID(dev),
+ SPS_ERR("sps:Invalid BAM 0x%x pipe: %d\n", BAM_ID(dev),
pipe_index);
return SPS_ERROR;
}
@@ -959,7 +963,7 @@
}
if (result)
- SPS_ERR("sps:BAM 0x%x pipe %d already disconnected",
+ SPS_ERR("sps:BAM 0x%x pipe %d already disconnected\n",
BAM_ID(dev), pipe_index);
return result;
@@ -1002,7 +1006,7 @@
irq_enable = BAM_DISABLE;
pipe->polled = true;
if (poll == 0 && pipe->irq_mask)
- SPS_DBG2("sps:BAM 0x%x pipe %d forced to use polling",
+ SPS_DBG2("sps:BAM 0x%x pipe %d forced to use polling\n",
BAM_ID(dev), pipe_index);
}
if ((pipe->state & BAM_STATE_MTI) == 0)
@@ -1050,8 +1054,8 @@
if (pipe->sys.desc_wr_count > 0 &&
(no_queue != pipe->sys.no_queue
|| ack_xfers != pipe->sys.ack_xfers)) {
- SPS_ERR("sps:Queue/ack mode change after transfer: "
- "BAM 0x%x pipe %d opt 0x%x",
+ SPS_ERR(
+ "sps:Queue/ack mode change after transfer: BAM 0x%x pipe %d opt 0x%x\n",
BAM_ID(dev), pipe_index, options);
return SPS_ERROR;
}
@@ -1060,8 +1064,9 @@
/* Is client setting invalid options for a BAM-to-BAM connection? */
if ((pipe->state & BAM_STATE_BAM2BAM) &&
(options & BAM2BAM_O_INVALID)) {
- SPS_ERR("sps:Invalid option for BAM-to-BAM: BAM 0x%x pipe %d "
- "opt 0x%x", BAM_ID(dev), pipe_index, options);
+ SPS_ERR(
+ "sps:Invalid option for BAM-to-BAM: BAM 0x%x pipe %d opt 0x%x\n",
+ BAM_ID(dev), pipe_index, options);
return SPS_ERROR;
}
@@ -1079,7 +1084,8 @@
vmalloc(pipe->desc_size + size);
if (pipe->sys.desc_cache == NULL) {
- SPS_ERR("sps:No memory for pipe %d of BAM 0x%x",
+ SPS_ERR(
+ "sps:No memory for pipe %d of BAM 0x%x\n",
pipe_index, BAM_ID(dev));
return -ENOMEM;
}
@@ -1089,7 +1095,7 @@
if (pipe->sys.desc_cache == NULL) {
/*** MUST BE LAST POINT OF FAILURE (see below) *****/
- SPS_ERR("sps:Desc cache error: BAM 0x%x pipe %d: %d",
+ SPS_ERR("sps:Desc cache error: BAM 0x%x pipe %d: %d\n",
BAM_ID(dev), pipe_index,
pipe->desc_size + size);
return SPS_ERROR;
@@ -1165,8 +1171,8 @@
if (pipe->sys.no_queue && reg->xfer_done != NULL &&
reg->mode != SPS_TRIGGER_CALLBACK) {
- SPS_ERR("sps:Only callback events support for NO_Q: "
- "BAM 0x%x pipe %d mode %d",
+ SPS_ERR(
+ "sps:Only callback events support for NO_Q: BAM 0x%x pipe %d mode %d\n",
BAM_ID(dev), pipe_index, reg->mode);
return SPS_ERROR;
}
@@ -1180,9 +1186,9 @@
index = SPS_EVENT_INDEX(opt_event_table[n].event_id);
if (index < 0)
- SPS_ERR("sps:Negative event index: "
- "BAM 0x%x pipe %d mode %d",
- BAM_ID(dev), pipe_index, reg->mode);
+ SPS_ERR(
+ "sps:Negative event index: BAM 0x%x pipe %d mode %d\n",
+ BAM_ID(dev), pipe_index, reg->mode);
else {
event_reg = &pipe->sys.event_regs[index];
event_reg->xfer_done = reg->xfer_done;
@@ -1211,7 +1217,7 @@
/* Is this a BAM-to-BAM or satellite connection? */
if ((pipe->state & (BAM_STATE_BAM2BAM | BAM_STATE_REMOTE))) {
- SPS_ERR("sps:Transfer on BAM-to-BAM: BAM 0x%x pipe %d",
+ SPS_ERR("sps:Transfer on BAM-to-BAM: BAM 0x%x pipe %d\n",
BAM_ID(dev), pipe_index);
return SPS_ERROR;
}
@@ -1221,7 +1227,7 @@
* SPS_O_NO_Q option.
*/
if (pipe->sys.no_queue && user != NULL) {
- SPS_ERR("sps:User pointer arg non-NULL: BAM 0x%x pipe %d",
+ SPS_ERR("sps:User pointer arg non-NULL: BAM 0x%x pipe %d\n",
BAM_ID(dev), pipe_index);
return SPS_ERROR;
}
@@ -1242,24 +1248,27 @@
if (next_write == pipe->sys.acked_offset) {
if (!show_recom) {
show_recom = true;
- SPS_ERR("sps:Client of BAM 0x%x pipe %d is recommended to have flow control",
+ SPS_ERR(
+ "sps:Client of BAM 0x%x pipe %d is recommended to have flow control\n",
BAM_ID(dev), pipe_index);
}
- SPS_DBG2("sps:Descriptor FIFO is full for BAM "
- "0x%x pipe %d after pipe_handler_eot",
+ SPS_DBG2(
+ "sps:Descriptor FIFO is full for BAM 0x%x pipe %d after pipe_handler_eot\n",
BAM_ID(dev), pipe_index);
return SPS_ERROR;
}
} else {
if (!show_recom) {
show_recom = true;
- SPS_ERR("sps:Client of BAM 0x%x pipe %d is recommended to have flow control.",
+ SPS_ERR(
+ "sps:Client of BAM 0x%x pipe %d is recommended to have flow control.\n",
BAM_ID(dev), pipe_index);
}
- SPS_DBG2("sps:Descriptor FIFO is full for "
- "BAM 0x%x pipe %d", BAM_ID(dev), pipe_index);
+ SPS_DBG2(
+ "sps:Descriptor FIFO is full for BAM 0x%x pipe %d\n",
+ BAM_ID(dev), pipe_index);
return SPS_ERROR;
}
}
@@ -1335,14 +1344,14 @@
int result;
if (transfer->iovec_count == 0) {
- SPS_ERR("sps:iovec count zero: BAM 0x%x pipe %d",
+ SPS_ERR("sps:iovec count zero: BAM 0x%x pipe %d\n",
BAM_ID(dev), pipe_index);
return SPS_ERROR;
}
sps_bam_get_free_count(dev, pipe_index, &count);
if (count < transfer->iovec_count) {
- SPS_ERR("sps:Insufficient free desc: BAM 0x%x pipe %d: %d",
+ SPS_ERR("sps:Insufficient free desc: BAM 0x%x pipe %d: %d\n",
BAM_ID(dev), pipe_index, count);
return SPS_ERROR;
}
@@ -1413,18 +1422,18 @@
struct sps_q_event *sps_event)
{
if (sps_event == NULL) {
- SPS_DBG("sps:trigger_event.sps_event is NULL.");
+ SPS_DBG("sps:trigger_event.sps_event is NULL.\n");
return;
}
if (event_reg->xfer_done) {
complete(event_reg->xfer_done);
- SPS_DBG("sps:trigger_event.done=%d.",
+ SPS_DBG("sps:trigger_event.done=%d.\n",
event_reg->xfer_done->done);
}
if (event_reg->callback) {
- SPS_DBG("sps:trigger_event.using callback.");
+ SPS_DBG("sps:trigger_event.using callback.\n");
event_reg->callback(&sps_event->notify);
}
@@ -1696,7 +1705,7 @@
pipe_index = pipe->pipe_index;
status = bam_pipe_get_and_clear_irq_status(dev->base, pipe_index);
- SPS_DBG("sps:pipe_handler.bam 0x%x.pipe %d.status=0x%x.",
+ SPS_DBG("sps:pipe_handler.bam 0x%x.pipe %d.status=0x%x.\n",
BAM_ID(dev), pipe_index, status);
/* Check for enabled interrupt sources */
@@ -1768,8 +1777,8 @@
struct sps_q_event *event_queue;
if (pipe->sys.no_queue) {
- SPS_ERR("sps:Invalid connection for event: "
- "BAM 0x%x pipe %d context 0x%x",
+ SPS_ERR(
+ "sps:Invalid connection for event: BAM 0x%x pipe %d context 0x%x\n",
BAM_ID(dev), pipe_index, (u32) pipe);
notify->event_id = SPS_EVENT_INVALID;
return SPS_ERROR;
@@ -1782,9 +1791,10 @@
/* Pull an event off the synchronous event queue */
if (list_empty(&pipe->sys.events_q)) {
event_queue = NULL;
- SPS_DBG("sps:events_q of bam 0x%x is empty.", BAM_ID(dev));
+ SPS_DBG("sps:events_q of bam 0x%x is empty.\n", BAM_ID(dev));
} else {
- SPS_DBG("sps:events_q of bam 0x%x is not empty.", BAM_ID(dev));
+ SPS_DBG("sps:events_q of bam 0x%x is not empty.\n",
+ BAM_ID(dev));
event_queue =
list_first_entry(&pipe->sys.events_q, struct sps_q_event,
list);
@@ -1873,7 +1883,7 @@
/* Is this a satellite connection? */
if ((pipe->state & BAM_STATE_REMOTE)) {
- SPS_ERR("sps:Is empty on remote: BAM 0x%x pipe %d",
+ SPS_ERR("sps:Is empty on remote: BAM 0x%x pipe %d\n",
BAM_ID(dev), pipe_index);
return SPS_ERROR;
}
@@ -1912,8 +1922,9 @@
/* Is this a BAM-to-BAM or satellite connection? */
if ((pipe->state & (BAM_STATE_BAM2BAM | BAM_STATE_REMOTE))) {
- SPS_ERR("sps:Free count on BAM-to-BAM or remote: BAM "
- "0x%x pipe %d", BAM_ID(dev), pipe_index);
+ SPS_ERR(
+ "sps:Free count on BAM-to-BAM or remote: BAM 0x%x pipe %d\n",
+ BAM_ID(dev), pipe_index);
*count = 0;
return SPS_ERROR;
}
@@ -1948,14 +1959,15 @@
*/
if ((dev->props.manage & SPS_BAM_MGR_MULTI_EE) == 0 ||
(dev->props.manage & SPS_BAM_MGR_DEVICE_REMOTE)) {
- SPS_ERR("sps:Cannot grant satellite control to BAM 0x%x "
- "pipe %d", BAM_ID(dev), pipe_index);
+ SPS_ERR(
+ "sps:Cannot grant satellite control to BAM 0x%x pipe %d\n",
+ BAM_ID(dev), pipe_index);
return SPS_ERROR;
}
/* Is this pipe locally controlled? */
if ((dev->pipe_active_mask & (1UL << pipe_index)) == 0) {
- SPS_ERR("sps:BAM 0x%x pipe %d not local and active",
+ SPS_ERR("sps:BAM 0x%x pipe %d not local and active\n",
BAM_ID(dev), pipe_index);
return SPS_ERROR;
}
@@ -2003,7 +2015,7 @@
/* Is this pipe locally controlled? */
if ((dev->pipe_active_mask & (1UL << pipe_index)) == 0) {
- SPS_ERR("sps:BAM 0x%x pipe %d not local and active",
+ SPS_ERR("sps:BAM 0x%x pipe %d not local and active\n",
BAM_ID(dev), pipe_index);
return SPS_ERROR;
}
diff --git a/drivers/slimbus/slim-msm-ngd.c b/drivers/slimbus/slim-msm-ngd.c
index 10c69c3..63d3750 100644
--- a/drivers/slimbus/slim-msm-ngd.c
+++ b/drivers/slimbus/slim-msm-ngd.c
@@ -761,7 +761,13 @@
pr_info("ADSP P.C. CTRL state:%d NGD not enumerated:0x%x",
dev->state, laddr);
}
-
+ /* ADSP SSR scenario, need to disconnect pipe before connecting */
+ if (dev->use_rx_msgqs == MSM_MSGQ_DOWN) {
+ struct msm_slim_endp *endpoint = &dev->rx_msgq;
+ sps_disconnect(endpoint->sps);
+ sps_free_endpoint(endpoint->sps);
+ dev->use_rx_msgqs = MSM_MSGQ_RESET;
+ }
/*
* ADSP power collapse case (OR SSR), where HW was reset
* BAM programming will happen when capability message is received
@@ -911,6 +917,8 @@
ngd_slim_enable(dev, false);
/* disconnect BAM pipes */
+ if (dev->use_rx_msgqs == MSM_MSGQ_ENABLED)
+ dev->use_rx_msgqs = MSM_MSGQ_DOWN;
msm_slim_sps_exit(dev, false);
mutex_lock(&ctrl->m_ctrl);
/* device up should be called again after SSR */
diff --git a/drivers/slimbus/slim-msm.c b/drivers/slimbus/slim-msm.c
index 3e19f9b..30341e2 100644
--- a/drivers/slimbus/slim-msm.c
+++ b/drivers/slimbus/slim-msm.c
@@ -581,7 +581,7 @@
void msm_slim_sps_exit(struct msm_slim_ctrl *dev, bool dereg)
{
- if (dev->use_rx_msgqs == MSM_MSGQ_ENABLED) {
+ if (dev->use_rx_msgqs >= MSM_MSGQ_ENABLED) {
struct msm_slim_endp *endpoint = &dev->rx_msgq;
struct sps_connect *config = &endpoint->config;
struct sps_mem_buffer *descr = &config->desc;
@@ -590,10 +590,12 @@
memset(&sps_event, 0x00, sizeof(sps_event));
msm_slim_sps_mem_free(dev, mem);
sps_register_event(endpoint->sps, &sps_event);
- sps_disconnect(endpoint->sps);
+ if (dev->use_rx_msgqs == MSM_MSGQ_ENABLED) {
+ sps_disconnect(endpoint->sps);
+ msm_slim_free_endpoint(endpoint);
+ dev->use_rx_msgqs = MSM_MSGQ_RESET;
+ }
msm_slim_sps_mem_free(dev, descr);
- msm_slim_free_endpoint(endpoint);
- dev->use_rx_msgqs = MSM_MSGQ_RESET;
}
if (dereg) {
sps_deregister_bam_device(dev->bam.hdl);
diff --git a/drivers/slimbus/slim-msm.h b/drivers/slimbus/slim-msm.h
index 6e329b3..6ff3f19 100644
--- a/drivers/slimbus/slim-msm.h
+++ b/drivers/slimbus/slim-msm.h
@@ -159,6 +159,7 @@
MSM_MSGQ_DISABLED,
MSM_MSGQ_RESET,
MSM_MSGQ_ENABLED,
+ MSM_MSGQ_DOWN,
};
struct msm_slim_sps_bam {
diff --git a/drivers/thermal/msm8974-tsens.c b/drivers/thermal/msm8974-tsens.c
index ee80975..9ba954a 100644
--- a/drivers/thermal/msm8974-tsens.c
+++ b/drivers/thermal/msm8974-tsens.c
@@ -1504,11 +1504,10 @@
},
};
-static int __init tsens_tm_init_driver(void)
+int __init tsens_tm_init_driver(void)
{
return platform_driver_register(&tsens_tm_driver);
}
-arch_initcall(tsens_tm_init_driver);
static int __init tsens_thermal_register(void)
{
diff --git a/drivers/usb/gadget/ci13xxx_udc.c b/drivers/usb/gadget/ci13xxx_udc.c
index e0255ce..6fca910 100644
--- a/drivers/usb/gadget/ci13xxx_udc.c
+++ b/drivers/usb/gadget/ci13xxx_udc.c
@@ -66,7 +66,8 @@
#include <linux/usb/gadget.h>
#include <linux/usb/otg.h>
#include <linux/usb/msm_hsusb.h>
-
+#include <linux/tracepoint.h>
+#include <mach/usb_trace.h>
#include "ci13xxx_udc.h"
/* Turns on streaming. overrides CI13XXX_DISABLE_STREAMING */
@@ -139,6 +140,21 @@
return n ? n-1 : 32;
}
+struct ci13xxx_ebi_err_entry {
+ u32 *usb_req_buf;
+ u32 usb_req_length;
+ u32 ep_info;
+ struct ci13xxx_ebi_err_entry *next;
+};
+
+struct ci13xxx_ebi_err_data {
+ u32 ebi_err_addr;
+ u32 apkt0;
+ u32 apkt1;
+ struct ci13xxx_ebi_err_entry *ebi_err_entry;
+};
+static struct ci13xxx_ebi_err_data *ebi_err_data;
+
/******************************************************************************
* HW block
*****************************************************************************/
@@ -1738,6 +1754,72 @@
return 0;
}
+static void dump_usb_info(void *ignore, unsigned int ebi_addr,
+ unsigned int ebi_apacket0, unsigned int ebi_apacket1)
+{
+ struct ci13xxx *udc = _udc;
+ unsigned long flags;
+ struct list_head *ptr = NULL;
+ struct ci13xxx_req *req = NULL;
+ struct ci13xxx_ep *mEp;
+ unsigned i;
+ struct ci13xxx_ebi_err_entry *temp_dump;
+ static int count;
+ u32 epdir = 0;
+
+ if (count)
+ return;
+ count++;
+
+ pr_info("%s: USB EBI error detected\n", __func__);
+
+ ebi_err_data = kmalloc(sizeof(struct ci13xxx_ebi_err_data),
+ GFP_ATOMIC);
+ if (!ebi_err_data) {
+ pr_err("%s: memory alloc failed for ebi_err_data\n", __func__);
+ return;
+ }
+
+ ebi_err_data->ebi_err_entry = kmalloc(
+ sizeof(struct ci13xxx_ebi_err_entry),
+ GFP_ATOMIC);
+ if (!ebi_err_data->ebi_err_entry) {
+ kfree(ebi_err_data);
+ pr_err("%s: memory alloc failed for ebi_err_entry\n", __func__);
+ return;
+ }
+
+ ebi_err_data->ebi_err_addr = ebi_addr;
+ ebi_err_data->apkt0 = ebi_apacket0;
+ ebi_err_data->apkt1 = ebi_apacket1;
+
+ temp_dump = ebi_err_data->ebi_err_entry;
+ pr_info("\n DUMPING USB Requests Information\n");
+ spin_lock_irqsave(udc->lock, flags);
+ for (i = 0; i < hw_ep_max; i++) {
+ list_for_each(ptr, &udc->ci13xxx_ep[i].qh.queue) {
+ mEp = &udc->ci13xxx_ep[i];
+ req = list_entry(ptr, struct ci13xxx_req, queue);
+
+ temp_dump->usb_req_buf = req->req.buf;
+ temp_dump->usb_req_length = req->req.length;
+ epdir = mEp->dir;
+ temp_dump->ep_info = mEp->num | (epdir << 15);
+
+ temp_dump->next = kmalloc(
+ sizeof(struct ci13xxx_ebi_err_entry),
+ GFP_ATOMIC);
+ if (!temp_dump->next) {
+ pr_err("%s: memory alloc failed\n", __func__);
+ spin_unlock_irqrestore(udc->lock, flags);
+ return;
+ }
+ temp_dump = temp_dump->next;
+ }
+ }
+ spin_unlock_irqrestore(udc->lock, flags);
+}
+
/******************************************************************************
* UTIL block
*****************************************************************************/
@@ -3692,6 +3774,11 @@
pm_runtime_no_callbacks(&udc->gadget.dev);
pm_runtime_enable(&udc->gadget.dev);
+ retval = register_trace_usb_daytona_invalid_access(dump_usb_info,
+ NULL);
+ if (retval)
+ pr_err("Registering trace failed\n");
+
_udc = udc;
return retval;
@@ -3725,11 +3812,17 @@
static void udc_remove(void)
{
struct ci13xxx *udc = _udc;
+ int retval;
if (udc == NULL) {
err("EINVAL");
return;
}
+ retval = unregister_trace_usb_daytona_invalid_access(dump_usb_info,
+ NULL);
+ if (retval)
+ pr_err("Unregistering trace failed\n");
+
usb_del_gadget_udc(&udc->gadget);
if (udc->transceiver) {
diff --git a/include/drm/kgsl_drm.h b/include/drm/kgsl_drm.h
index 2ad1ab2..1e65a5f 100644
--- a/include/drm/kgsl_drm.h
+++ b/include/drm/kgsl_drm.h
@@ -21,6 +21,10 @@
#define DRM_KGSL_GEM_CREATE_FD 0x0E
#define DRM_KGSL_GEM_GET_ION_FD 0x0F
#define DRM_KGSL_GEM_CREATE_FROM_ION 0x10
+#define DRM_KGSL_GEM_SET_GLOCK_HANDLES_INFO 0x11
+#define DRM_KGSL_GEM_GET_GLOCK_HANDLES_INFO 0x12
+#define DRM_KGSL_GEM_GET_BUFCOUNT 0x13
+
#define DRM_IOCTL_KGSL_GEM_CREATE \
DRM_IOWR(DRM_COMMAND_BASE + DRM_KGSL_GEM_CREATE, struct drm_kgsl_gem_create)
@@ -57,6 +61,10 @@
DRM_IOWR(DRM_COMMAND_BASE + DRM_KGSL_GEM_SET_BUFCOUNT, \
struct drm_kgsl_gem_bufcount)
+#define DRM_IOCTL_KGSL_GEM_GET_BUFCOUNT \
+DRM_IOWR(DRM_COMMAND_BASE + DRM_KGSL_GEM_GET_BUFCOUNT, \
+ struct drm_kgsl_gem_bufcount)
+
#define DRM_IOCTL_KGSL_GEM_SET_ACTIVE \
DRM_IOWR(DRM_COMMAND_BASE + DRM_KGSL_GEM_SET_ACTIVE, \
struct drm_kgsl_gem_active)
@@ -85,6 +93,16 @@
DRM_IOWR(DRM_COMMAND_BASE + DRM_KGSL_GEM_CREATE_FROM_ION, \
struct drm_kgsl_gem_create_from_ion)
+#define DRM_IOCTL_KGSL_GEM_SET_GLOCK_HANDLES_INFO \
+DRM_IOWR(DRM_COMMAND_BASE + DRM_KGSL_GEM_SET_GLOCK_HANDLES_INFO, \
+struct drm_kgsl_gem_glockinfo)
+
+#define DRM_IOCTL_KGSL_GEM_GET_GLOCK_HANDLES_INFO \
+DRM_IOWR(DRM_COMMAND_BASE + DRM_KGSL_GEM_GET_GLOCK_HANDLES_INFO, \
+struct drm_kgsl_gem_glockinfo)
+
+
+
/* Maximum number of sub buffers per GEM object */
#define DRM_KGSL_GEM_MAX_BUFFERS 3
@@ -167,6 +185,11 @@
uint32_t gpuaddr[DRM_KGSL_GEM_MAX_BUFFERS];
};
+struct drm_kgsl_gem_glockinfo {
+ uint32_t handle;
+ int glockhandle[DRM_KGSL_GEM_MAX_BUFFERS];
+};
+
struct drm_kgsl_gem_bufcount {
uint32_t handle;
uint32_t bufcount;
diff --git a/include/linux/genlock.h b/include/linux/genlock.h
index 587c49d..e233662 100644
--- a/include/linux/genlock.h
+++ b/include/linux/genlock.h
@@ -8,6 +8,7 @@
struct genlock_handle *genlock_get_handle(void);
struct genlock_handle *genlock_get_handle_fd(int fd);
+int genlock_get_fd_handle(struct genlock_handle *handle);
void genlock_put_handle(struct genlock_handle *handle);
struct genlock *genlock_create_lock(struct genlock_handle *);
struct genlock *genlock_attach_lock(struct genlock_handle *, int fd);
diff --git a/include/linux/ion.h b/include/linux/ion.h
index 67b5e6c..88ad9a0 100644
--- a/include/linux/ion.h
+++ b/include/linux/ion.h
@@ -29,10 +29,6 @@
* @ION_HEAP_TYPE_CARVEOUT: memory allocated from a prereserved
* carveout heap, allocations are physically
* contiguous
- * @ION_HEAP_TYPE_IOMMU: IOMMU memory
- * @ION_HEAP_TYPE_CP: memory allocated from a prereserved
- * carveout heap, allocations are physically
- * contiguous. Used for content protection.
* @ION_HEAP_END: helper for iterating over heaps
*/
enum ion_heap_type {
@@ -104,11 +100,6 @@
* struct ion_platform_data - array of platform heaps passed from board file
* @has_outer_cache: set to 1 if outer cache is used, 0 otherwise.
* @nr: number of structures in the array
- * @request_region: function to be called when the number of allocations goes
- * from 0 -> 1
- * @release_region: function to be called when the number of allocations goes
- * from 1 -> 0
- * @setup_region: function to be called upon ion registration
* @heaps: array of platform_heap structions
*
* Provided by the board file in the form of platform data to a platform device.
@@ -116,9 +107,6 @@
struct ion_platform_data {
unsigned int has_outer_cache;
int nr;
- int (*request_region)(void *);
- int (*release_region)(void *);
- void *(*setup_region)(void);
struct ion_platform_heap *heaps;
};
@@ -145,17 +133,6 @@
unsigned int heap_mask, const char *name);
/**
- * msm_ion_client_create - allocate a client using the ion_device specified in
- * drivers/gpu/ion/msm/msm_ion.c
- *
- * heap_mask and name are the same as ion_client_create, return values
- * are the same as ion_client_create.
- */
-
-struct ion_client *msm_ion_client_create(unsigned int heap_mask,
- const char *name);
-
-/**
* ion_client_destroy() - free's a client and all it's handles
* @client: the client
*
@@ -257,124 +234,6 @@
*/
struct ion_handle *ion_import_dma_buf(struct ion_client *client, int fd);
-/**
- * ion_handle_get_flags - get the flags for a given handle
- *
- * @client - client who allocated the handle
- * @handle - handle to get the flags
- * @flags - pointer to store the flags
- *
- * Gets the current flags for a handle. These flags indicate various options
- * of the buffer (caching, security, etc.)
- */
-int ion_handle_get_flags(struct ion_client *client, struct ion_handle *handle,
- unsigned long *flags);
-
-
-/**
- * ion_map_iommu - map the given handle into an iommu
- *
- * @client - client who allocated the handle
- * @handle - handle to map
- * @domain_num - domain number to map to
- * @partition_num - partition number to allocate iova from
- * @align - alignment for the iova
- * @iova_length - length of iova to map. If the iova length is
- * greater than the handle length, the remaining
- * address space will be mapped to a dummy buffer.
- * @iova - pointer to store the iova address
- * @buffer_size - pointer to store the size of the buffer
- * @flags - flags for options to map
- * @iommu_flags - flags specific to the iommu.
- *
- * Maps the handle into the iova space specified via domain number. Iova
- * will be allocated from the partition specified via partition_num.
- * Returns 0 on success, negative value on error.
- */
-int ion_map_iommu(struct ion_client *client, struct ion_handle *handle,
- int domain_num, int partition_num, unsigned long align,
- unsigned long iova_length, unsigned long *iova,
- unsigned long *buffer_size,
- unsigned long flags, unsigned long iommu_flags);
-
-
-/**
- * ion_handle_get_size - get the allocated size of a given handle
- *
- * @client - client who allocated the handle
- * @handle - handle to get the size
- * @size - pointer to store the size
- *
- * gives the allocated size of a handle. returns 0 on success, negative
- * value on error
- *
- * NOTE: This is intended to be used only to get a size to pass to map_iommu.
- * You should *NOT* rely on this for any other usage.
- */
-
-int ion_handle_get_size(struct ion_client *client, struct ion_handle *handle,
- unsigned long *size);
-
-/**
- * ion_unmap_iommu - unmap the handle from an iommu
- *
- * @client - client who allocated the handle
- * @handle - handle to unmap
- * @domain_num - domain to unmap from
- * @partition_num - partition to unmap from
- *
- * Decrement the reference count on the iommu mapping. If the count is
- * 0, the mapping will be removed from the iommu.
- */
-void ion_unmap_iommu(struct ion_client *client, struct ion_handle *handle,
- int domain_num, int partition_num);
-
-
-/**
- * ion_secure_heap - secure a heap
- *
- * @client - a client that has allocated from the heap heap_id
- * @heap_id - heap id to secure.
- * @version - version of content protection
- * @data - extra data needed for protection
- *
- * Secure a heap
- * Returns 0 on success
- */
-int ion_secure_heap(struct ion_device *dev, int heap_id, int version,
- void *data);
-
-/**
- * ion_unsecure_heap - un-secure a heap
- *
- * @client - a client that has allocated from the heap heap_id
- * @heap_id - heap id to un-secure.
- * @version - version of content protection
- * @data - extra data needed for protection
- *
- * Un-secure a heap
- * Returns 0 on success
- */
-int ion_unsecure_heap(struct ion_device *dev, int heap_id, int version,
- void *data);
-
-/**
- * msm_ion_do_cache_op - do cache operations.
- *
- * @client - pointer to ION client.
- * @handle - pointer to buffer handle.
- * @vaddr - virtual address to operate on.
- * @len - Length of data to do cache operation on.
- * @cmd - Cache operation to perform:
- * ION_IOC_CLEAN_CACHES
- * ION_IOC_INV_CACHES
- * ION_IOC_CLEAN_INV_CACHES
- *
- * Returns 0 on success
- */
-int msm_ion_do_cache_op(struct ion_client *client, struct ion_handle *handle,
- void *vaddr, unsigned long len, unsigned int cmd);
-
#else
static inline void ion_reserve(struct ion_platform_data *data)
{
@@ -387,12 +246,6 @@
return ERR_PTR(-ENODEV);
}
-static inline struct ion_client *msm_ion_client_create(unsigned int heap_mask,
- const char *name)
-{
- return ERR_PTR(-ENODEV);
-}
-
static inline void ion_client_destroy(struct ion_client *client) { }
static inline struct ion_handle *ion_alloc(struct ion_client *client,
@@ -444,54 +297,6 @@
return -ENODEV;
}
-static inline int ion_map_iommu(struct ion_client *client,
- struct ion_handle *handle, int domain_num,
- int partition_num, unsigned long align,
- unsigned long iova_length, unsigned long *iova,
- unsigned long *buffer_size,
- unsigned long flags,
- unsigned long iommu_flags)
-{
- return -ENODEV;
-}
-
-static inline int ion_handle_get_size(struct ion_client *client,
- struct ion_handle *handle, unsigned long *size)
-{
- return -ENODEV;
-}
-
-static inline void ion_unmap_iommu(struct ion_client *client,
- struct ion_handle *handle, int domain_num,
- int partition_num)
-{
- return;
-}
-
-static inline int ion_secure_heap(struct ion_device *dev, int heap_id,
- int version, void *data)
-{
- return -ENODEV;
-
-}
-
-static inline int ion_unsecure_heap(struct ion_device *dev, int heap_id,
- int version, void *data)
-{
- return -ENODEV;
-}
-
-static inline void ion_mark_dangling_buffers_locked(struct ion_device *dev)
-{
-}
-
-static inline int msm_ion_do_cache_op(struct ion_client *client,
- struct ion_handle *handle, void *vaddr,
- unsigned long len, unsigned int cmd)
-{
- return -ENODEV;
-}
-
#endif /* CONFIG_ION */
#endif /* __KERNEL__ */
diff --git a/include/linux/msm_ion.h b/include/linux/msm_ion.h
index 3c3c7a9..396fcd8 100644
--- a/include/linux/msm_ion.h
+++ b/include/linux/msm_ion.h
@@ -194,9 +194,138 @@
#ifdef CONFIG_ION
/**
+ * msm_ion_client_create - allocate a client using the ion_device specified in
+ * drivers/gpu/ion/msm/msm_ion.c
+ *
+ * heap_mask and name are the same as ion_client_create, return values
+ * are the same as ion_client_create.
+ */
+
+struct ion_client *msm_ion_client_create(unsigned int heap_mask,
+ const char *name);
+
+/**
+ * ion_handle_get_flags - get the flags for a given handle
+ *
+ * @client - client who allocated the handle
+ * @handle - handle to get the flags
+ * @flags - pointer to store the flags
+ *
+ * Gets the current flags for a handle. These flags indicate various options
+ * of the buffer (caching, security, etc.)
+ */
+int ion_handle_get_flags(struct ion_client *client, struct ion_handle *handle,
+ unsigned long *flags);
+
+
+/**
+ * ion_map_iommu - map the given handle into an iommu
+ *
+ * @client - client who allocated the handle
+ * @handle - handle to map
+ * @domain_num - domain number to map to
+ * @partition_num - partition number to allocate iova from
+ * @align - alignment for the iova
+ * @iova_length - length of iova to map. If the iova length is
+ * greater than the handle length, the remaining
+ * address space will be mapped to a dummy buffer.
+ * @iova - pointer to store the iova address
+ * @buffer_size - pointer to store the size of the buffer
+ * @flags - flags for options to map
+ * @iommu_flags - flags specific to the iommu.
+ *
+ * Maps the handle into the iova space specified via domain number. Iova
+ * will be allocated from the partition specified via partition_num.
+ * Returns 0 on success, negative value on error.
+ */
+int ion_map_iommu(struct ion_client *client, struct ion_handle *handle,
+ int domain_num, int partition_num, unsigned long align,
+ unsigned long iova_length, unsigned long *iova,
+ unsigned long *buffer_size,
+ unsigned long flags, unsigned long iommu_flags);
+
+
+/**
+ * ion_handle_get_size - get the allocated size of a given handle
+ *
+ * @client - client who allocated the handle
+ * @handle - handle to get the size
+ * @size - pointer to store the size
+ *
+ * gives the allocated size of a handle. returns 0 on success, negative
+ * value on error
+ *
+ * NOTE: This is intended to be used only to get a size to pass to map_iommu.
+ * You should *NOT* rely on this for any other usage.
+ */
+
+int ion_handle_get_size(struct ion_client *client, struct ion_handle *handle,
+ unsigned long *size);
+
+/**
+ * ion_unmap_iommu - unmap the handle from an iommu
+ *
+ * @client - client who allocated the handle
+ * @handle - handle to unmap
+ * @domain_num - domain to unmap from
+ * @partition_num - partition to unmap from
+ *
+ * Decrement the reference count on the iommu mapping. If the count is
+ * 0, the mapping will be removed from the iommu.
+ */
+void ion_unmap_iommu(struct ion_client *client, struct ion_handle *handle,
+ int domain_num, int partition_num);
+
+
+/**
+ * ion_secure_heap - secure a heap
+ *
+ * @client - a client that has allocated from the heap heap_id
+ * @heap_id - heap id to secure.
+ * @version - version of content protection
+ * @data - extra data needed for protection
+ *
+ * Secure a heap
+ * Returns 0 on success
+ */
+int ion_secure_heap(struct ion_device *dev, int heap_id, int version,
+ void *data);
+
+/**
+ * ion_unsecure_heap - un-secure a heap
+ *
+ * @client - a client that has allocated from the heap heap_id
+ * @heap_id - heap id to un-secure.
+ * @version - version of content protection
+ * @data - extra data needed for protection
+ *
+ * Un-secure a heap
+ * Returns 0 on success
+ */
+int ion_unsecure_heap(struct ion_device *dev, int heap_id, int version,
+ void *data);
+
+/**
+ * msm_ion_do_cache_op - do cache operations.
+ *
+ * @client - pointer to ION client.
+ * @handle - pointer to buffer handle.
+ * @vaddr - virtual address to operate on.
+ * @len - Length of data to do cache operation on.
+ * @cmd - Cache operation to perform:
+ * ION_IOC_CLEAN_CACHES
+ * ION_IOC_INV_CACHES
+ * ION_IOC_CLEAN_INV_CACHES
+ *
+ * Returns 0 on success
+ */
+int msm_ion_do_cache_op(struct ion_client *client, struct ion_handle *handle,
+ void *vaddr, unsigned long len, unsigned int cmd);
+
+/**
* msm_ion_secure_heap - secure a heap. Wrapper around ion_secure_heap.
*
- * @heap_id - heap id to secure.
+ * @heap_id - heap id to secure.
*
* Secure a heap
* Returns 0 on success
@@ -257,6 +386,60 @@
int msm_ion_unsecure_buffer(struct ion_client *client,
struct ion_handle *handle);
#else
+static inline struct ion_client *msm_ion_client_create(unsigned int heap_mask,
+ const char *name)
+{
+ return ERR_PTR(-ENODEV);
+}
+
+static inline int ion_map_iommu(struct ion_client *client,
+ struct ion_handle *handle, int domain_num,
+ int partition_num, unsigned long align,
+ unsigned long iova_length, unsigned long *iova,
+ unsigned long *buffer_size,
+ unsigned long flags,
+ unsigned long iommu_flags)
+{
+ return -ENODEV;
+}
+
+static inline int ion_handle_get_size(struct ion_client *client,
+ struct ion_handle *handle, unsigned long *size)
+{
+ return -ENODEV;
+}
+
+static inline void ion_unmap_iommu(struct ion_client *client,
+ struct ion_handle *handle, int domain_num,
+ int partition_num)
+{
+ return;
+}
+
+static inline int ion_secure_heap(struct ion_device *dev, int heap_id,
+ int version, void *data)
+{
+ return -ENODEV;
+
+}
+
+static inline int ion_unsecure_heap(struct ion_device *dev, int heap_id,
+ int version, void *data)
+{
+ return -ENODEV;
+}
+
+static inline void ion_mark_dangling_buffers_locked(struct ion_device *dev)
+{
+}
+
+static inline int msm_ion_do_cache_op(struct ion_client *client,
+ struct ion_handle *handle, void *vaddr,
+ unsigned long len, unsigned int cmd)
+{
+ return -ENODEV;
+}
+
static inline int msm_ion_secure_heap(int heap_id)
{
return -ENODEV;
diff --git a/include/linux/msm_tsens.h b/include/linux/msm_tsens.h
index 8aa7c17..757f1dc 100644
--- a/include/linux/msm_tsens.h
+++ b/include/linux/msm_tsens.h
@@ -41,6 +41,14 @@
int32_t tsens_get_temp(struct tsens_device *dev, unsigned long *temp);
int msm_tsens_early_init(struct tsens_platform_data *pdata);
+
+#if defined(CONFIG_THERMAL_TSENS8974)
+int __init tsens_tm_init_driver(void);
+#else
+static inline int __init tsens_tm_init_driver(void)
+{ return -ENXIO; }
+#endif
+
#if defined(CONFIG_THERMAL_TSENS8974) || defined(CONFIG_THERMAL_TSENS8960)
int tsens_get_max_sensor_num(uint32_t *tsens_num_sensors);
#else
diff --git a/mm/dmapool.c b/mm/dmapool.c
index c5ab33b..da1b0f0 100644
--- a/mm/dmapool.c
+++ b/mm/dmapool.c
@@ -50,7 +50,6 @@
size_t allocation;
size_t boundary;
char name[32];
- wait_queue_head_t waitq;
struct list_head pools;
};
@@ -62,8 +61,6 @@
unsigned int offset;
};
-#define POOL_TIMEOUT_JIFFIES ((100 /* msec */ * HZ) / 1000)
-
static DEFINE_MUTEX(pools_lock);
static ssize_t
@@ -172,7 +169,6 @@
retval->size = size;
retval->boundary = boundary;
retval->allocation = allocation;
- init_waitqueue_head(&retval->waitq);
if (dev) {
int ret;
@@ -227,7 +223,6 @@
memset(page->vaddr, POOL_POISON_FREED, pool->allocation);
#endif
pool_initialise_page(pool, page);
- list_add(&page->page_list, &pool->page_list);
page->in_use = 0;
page->offset = 0;
} else {
@@ -315,30 +310,21 @@
might_sleep_if(mem_flags & __GFP_WAIT);
spin_lock_irqsave(&pool->lock, flags);
- restart:
list_for_each_entry(page, &pool->page_list, page_list) {
if (page->offset < pool->allocation)
goto ready;
}
- page = pool_alloc_page(pool, GFP_ATOMIC);
- if (!page) {
- if (mem_flags & __GFP_WAIT) {
- DECLARE_WAITQUEUE(wait, current);
- __set_current_state(TASK_UNINTERRUPTIBLE);
- __add_wait_queue(&pool->waitq, &wait);
- spin_unlock_irqrestore(&pool->lock, flags);
+ /* pool_alloc_page() might sleep, so temporarily drop &pool->lock */
+ spin_unlock_irqrestore(&pool->lock, flags);
- schedule_timeout(POOL_TIMEOUT_JIFFIES);
+ page = pool_alloc_page(pool, mem_flags);
+ if (!page)
+ return NULL;
- spin_lock_irqsave(&pool->lock, flags);
- __remove_wait_queue(&pool->waitq, &wait);
- goto restart;
- }
- retval = NULL;
- goto done;
- }
+ spin_lock_irqsave(&pool->lock, flags);
+ list_add(&page->page_list, &pool->page_list);
ready:
page->in_use++;
offset = page->offset;
@@ -348,7 +334,6 @@
#ifdef DMAPOOL_DEBUG
memset(retval, POOL_POISON_ALLOCATED, pool->size);
#endif
- done:
spin_unlock_irqrestore(&pool->lock, flags);
return retval;
}
@@ -435,8 +420,6 @@
page->in_use--;
*(int *)vaddr = page->offset;
page->offset = offset;
- if (waitqueue_active(&pool->waitq))
- wake_up_locked(&pool->waitq);
/*
* Resist a temptation to do
* if (!is_page_busy(page)) pool_free_page(pool, page);
diff --git a/sound/soc/codecs/wcd9xxx-mbhc.c b/sound/soc/codecs/wcd9xxx-mbhc.c
index 652992f..aacc9df 100644
--- a/sound/soc/codecs/wcd9xxx-mbhc.c
+++ b/sound/soc/codecs/wcd9xxx-mbhc.c
@@ -230,14 +230,14 @@
pr_debug("Polling is not active, do not start polling\n");
return;
}
+
+ snd_soc_write(codec, WCD9XXX_A_MBHC_SCALING_MUX_1, 0x04);
ret = wcd9xxx_enable_mux_bias_block(codec, mbhc);
if (ret) {
pr_err("%s: Error returned, ret: %d\n", __func__, ret);
return;
}
- snd_soc_write(codec, WCD9XXX_A_MBHC_SCALING_MUX_1, 0x04);
-
if (!mbhc->no_mic_headset_override &&
mbhc_state == MBHC_STATE_POTENTIAL) {
pr_debug("%s recovering MBHC state machine\n", __func__);
@@ -964,10 +964,10 @@
if (ret)
goto gen_err;
snd_soc_update_bits(codec, WCD9XXX_A_CDC_MBHC_CLK_CTL, 0x2, 0x2);
+ snd_soc_write(codec, WCD9XXX_A_MBHC_SCALING_MUX_1, 0x04);
ret = wcd9xxx_enable_mux_bias_block(codec, mbhc);
if (ret)
goto gen_err;
- snd_soc_write(codec, WCD9XXX_A_MBHC_SCALING_MUX_1, 0x04);
snd_soc_update_bits(codec, WCD9XXX_A_TX_7_MBHC_EN, 0x80, 0x80);
snd_soc_update_bits(codec, WCD9XXX_A_TX_7_MBHC_EN, 0x1F, 0x1C);
@@ -2729,10 +2729,10 @@
reg1 = snd_soc_read(codec, WCD9XXX_A_MAD_ANA_CTRL);
snd_soc_update_bits(codec, WCD9XXX_A_MAD_ANA_CTRL, 1 << 4, 1 << 0);
/* Connect the MUX to micbias */
+ snd_soc_write(codec, WCD9XXX_A_MBHC_SCALING_MUX_1, 0x02);
ret = wcd9xxx_enable_mux_bias_block(codec, mbhc);
if (ret)
goto gen_err;
- snd_soc_write(codec, WCD9XXX_A_MBHC_SCALING_MUX_1, 0x02);
usleep_range(WCD9XXX_MUX_SWITCH_READY_WAIT_US,
WCD9XXX_MUX_SWITCH_READY_WAIT_US +
WCD9XXX_USLEEP_RANGE_MARGIN_US);
@@ -2751,10 +2751,10 @@
/* DCE measurment for MB voltage */
snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_CLK_CTL, 0x0A);
snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_CLK_CTL, 0x02);
+ snd_soc_write(codec, WCD9XXX_A_MBHC_SCALING_MUX_1, 0x02);
ret = wcd9xxx_enable_mux_bias_block(codec, mbhc);
if (ret)
goto gen_err;
- snd_soc_write(codec, WCD9XXX_A_MBHC_SCALING_MUX_1, 0x02);
usleep_range(100, 100);
snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_EN_CTL, 0x04);
usleep_range(mbhc->mbhc_data.t_dce, mbhc->mbhc_data.t_dce);
@@ -2764,10 +2764,10 @@
snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_CLK_CTL, 0x0A);
snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_EN_CTL, 0x02);
snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_CLK_CTL, 0x02);
+ snd_soc_write(codec, WCD9XXX_A_MBHC_SCALING_MUX_1, 0x02);
ret = wcd9xxx_enable_mux_bias_block(codec, mbhc);
if (ret)
goto gen_err;
- snd_soc_write(codec, WCD9XXX_A_MBHC_SCALING_MUX_1, 0x02);
usleep_range(100, 100);
snd_soc_write(codec, WCD9XXX_A_CDC_MBHC_EN_CTL, 0x02);
usleep_range(mbhc->mbhc_data.t_sta, mbhc->mbhc_data.t_sta);
@@ -2776,10 +2776,10 @@
/* Restore default settings. */
snd_soc_update_bits(codec, WCD9XXX_A_CDC_MBHC_B1_CTL, 0x04, 0x00);
snd_soc_write(codec, mbhc->mbhc_bias_regs.cfilt_ctl, cfilt_mode);
+ snd_soc_write(codec, WCD9XXX_A_MBHC_SCALING_MUX_1, 0x04);
ret = wcd9xxx_enable_mux_bias_block(codec, mbhc);
if (ret)
goto gen_err;
- snd_soc_write(codec, WCD9XXX_A_MBHC_SCALING_MUX_1, 0x04);
usleep_range(100, 100);
wcd9xxx_enable_irq(codec->control_data, WCD9XXX_IRQ_MBHC_POTENTIAL);
diff --git a/sound/soc/msm/msm8974.c b/sound/soc/msm/msm8974.c
index 75d6906..8affc09 100644
--- a/sound/soc/msm/msm8974.c
+++ b/sound/soc/msm/msm8974.c
@@ -193,6 +193,7 @@
static int msm_btsco_ch = 1;
static int msm_hdmi_rx_ch = 2;
static int slim0_rx_sample_rate = SAMPLING_RATE_48KHZ;
+static int msm_proxy_rx_ch = 2;
static struct mutex cdc_mclk_mutex;
static struct q_clkdiv *codec_clk;
@@ -591,6 +592,9 @@
static char const *rx_bit_format_text[] = {"S16_LE", "S24_LE"};
static char const *slim0_rx_sample_rate_text[] = {"KHZ_48", "KHZ_96",
"KHZ_192"};
+static const char *const proxy_rx_ch_text[] = {"One", "Two", "Three", "Four",
+ "Five", "Six", "Seven", "Eight"};
+
static const char *const btsco_rate_text[] = {"8000", "16000"};
static const struct soc_enum msm_btsco_enum[] = {
SOC_ENUM_SINGLE_EXT(2, btsco_rate_text),
@@ -854,6 +858,23 @@
}
return 0;
}
+static int msm_proxy_rx_ch_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ pr_debug("%s: msm_proxy_rx_ch = %d\n", __func__,
+ msm_proxy_rx_ch);
+ ucontrol->value.integer.value[0] = msm_proxy_rx_ch - 1;
+ return 0;
+}
+
+static int msm_proxy_rx_ch_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ msm_proxy_rx_ch = ucontrol->value.integer.value[0] + 1;
+ pr_debug("%s: msm_proxy_rx_ch = %d\n", __func__,
+ msm_proxy_rx_ch);
+ return 1;
+}
static int msm_auxpcm_be_params_fixup(struct snd_soc_pcm_runtime *rtd,
struct snd_pcm_hw_params *params)
@@ -870,15 +891,31 @@
return 0;
}
-static int msm_proxy_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
- struct snd_pcm_hw_params *params)
+static int msm_proxy_rx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
+ struct snd_pcm_hw_params *params)
{
struct snd_interval *rate = hw_param_interval(params,
- SNDRV_PCM_HW_PARAM_RATE);
+ SNDRV_PCM_HW_PARAM_RATE);
- pr_debug("%s()\n", __func__);
+ struct snd_interval *channels = hw_param_interval(params,
+ SNDRV_PCM_HW_PARAM_CHANNELS);
+
+ pr_debug("%s: msm_proxy_rx_ch =%d\n", __func__, msm_proxy_rx_ch);
+
+ if (channels->max < 2)
+ channels->min = channels->max = 2;
+ channels->min = channels->max = msm_proxy_rx_ch;
rate->min = rate->max = 48000;
+ return 0;
+}
+static int msm_proxy_tx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_interval *rate = hw_param_interval(params,
+ SNDRV_PCM_HW_PARAM_RATE);
+
+ rate->min = rate->max = 48000;
return 0;
}
@@ -1150,6 +1187,7 @@
SOC_ENUM_SINGLE_EXT(7, hdmi_rx_ch_text),
SOC_ENUM_SINGLE_EXT(2, rx_bit_format_text),
SOC_ENUM_SINGLE_EXT(3, slim0_rx_sample_rate_text),
+ SOC_ENUM_SINGLE_EXT(8, proxy_rx_ch_text),
};
static const struct snd_kcontrol_new msm_snd_controls[] = {
@@ -1169,6 +1207,8 @@
slim0_rx_sample_rate_get, slim0_rx_sample_rate_put),
SOC_ENUM_EXT("HDMI_RX Bit Format", msm_snd_enum[4],
hdmi_rx_bit_format_get, hdmi_rx_bit_format_put),
+ SOC_ENUM_EXT("PROXY_RX Channels", msm_snd_enum[6],
+ msm_proxy_rx_ch_get, msm_proxy_rx_ch_put),
};
static bool msm8974_swap_gnd_mic(struct snd_soc_codec *codec)
@@ -1809,7 +1849,7 @@
.codec_dai_name = "msm-stub-rx",
.no_pcm = 1,
.be_id = MSM_BACKEND_DAI_AFE_PCM_RX,
- .be_hw_params_fixup = msm_proxy_be_hw_params_fixup,
+ .be_hw_params_fixup = msm_proxy_rx_be_hw_params_fixup,
/* this dainlink has playback support */
.ignore_pmdown_time = 1,
.ignore_suspend = 1,
@@ -1823,7 +1863,7 @@
.codec_dai_name = "msm-stub-tx",
.no_pcm = 1,
.be_id = MSM_BACKEND_DAI_AFE_PCM_TX,
- .be_hw_params_fixup = msm_proxy_be_hw_params_fixup,
+ .be_hw_params_fixup = msm_proxy_tx_be_hw_params_fixup,
.ignore_suspend = 1,
},
/* HDMI Hostless */
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.c
index 96ddcf6..2a64ae2 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-afe-v2.c
@@ -32,16 +32,22 @@
#include <linux/memory_alloc.h>
#include "msm-pcm-afe-v2.h"
-#define MIN_PERIOD_SIZE (128 * 2)
-#define MAX_PERIOD_SIZE (128 * 2 * 2 * 6)
-#define MAX_NUM_PERIODS 384
-#define MIN_NUM_PERIODS 32
-static struct snd_pcm_hardware msm_afe_hardware = {
- .info = (SNDRV_PCM_INFO_MMAP |
+#define MIN_PLAYBACK_PERIOD_SIZE (128 * 2)
+#define MAX_PLAYBACK_PERIOD_SIZE (128 * 2 * 2 * 6)
+#define MIN_PLAYBACK_NUM_PERIODS (32)
+#define MAX_PLAYBACK_NUM_PERIODS (384)
+
+#define MIN_CAPTURE_PERIOD_SIZE (128 * 2 * 4)
+#define MAX_CAPTURE_PERIOD_SIZE (128 * 2 * 2 * 6 * 4)
+#define MIN_CAPTURE_NUM_PERIODS (32)
+#define MAX_CAPTURE_NUM_PERIODS (384)
+
+static struct snd_pcm_hardware msm_afe_hardware_playback = {
+ .info = (SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
SNDRV_PCM_INFO_MMAP_VALID |
SNDRV_PCM_INFO_INTERLEAVED),
- .formats = SNDRV_PCM_FMTBIT_S16_LE |
+ .formats = SNDRV_PCM_FMTBIT_S16_LE|
SNDRV_PCM_FMTBIT_S24_LE,
.rates = (SNDRV_PCM_RATE_8000 |
SNDRV_PCM_RATE_16000 |
@@ -50,13 +56,39 @@
.rate_max = 48000,
.channels_min = 1,
.channels_max = 6,
- .buffer_bytes_max = MAX_PERIOD_SIZE * MIN_NUM_PERIODS,
- .period_bytes_min = MIN_PERIOD_SIZE,
- .period_bytes_max = MAX_PERIOD_SIZE,
- .periods_min = MIN_NUM_PERIODS,
- .periods_max = MAX_NUM_PERIODS,
+ .buffer_bytes_max = MAX_PLAYBACK_PERIOD_SIZE *
+ MIN_PLAYBACK_NUM_PERIODS,
+ .period_bytes_min = MIN_PLAYBACK_PERIOD_SIZE,
+ .period_bytes_max = MAX_PLAYBACK_PERIOD_SIZE,
+ .periods_min = MIN_PLAYBACK_NUM_PERIODS,
+ .periods_max = MAX_PLAYBACK_NUM_PERIODS,
.fifo_size = 0,
};
+
+static struct snd_pcm_hardware msm_afe_hardware_capture = {
+ .info = (SNDRV_PCM_INFO_MMAP |
+ SNDRV_PCM_INFO_BLOCK_TRANSFER |
+ SNDRV_PCM_INFO_MMAP_VALID |
+ SNDRV_PCM_INFO_INTERLEAVED),
+ .formats = SNDRV_PCM_FMTBIT_S16_LE|
+ SNDRV_PCM_FMTBIT_S24_LE,
+ .rates = (SNDRV_PCM_RATE_8000 |
+ SNDRV_PCM_RATE_16000 |
+ SNDRV_PCM_RATE_48000),
+ .rate_min = 8000,
+ .rate_max = 48000,
+ .channels_min = 1,
+ .channels_max = 6,
+ .buffer_bytes_max = MAX_CAPTURE_PERIOD_SIZE *
+ MIN_CAPTURE_NUM_PERIODS,
+ .period_bytes_min = MIN_CAPTURE_PERIOD_SIZE,
+ .period_bytes_max = MAX_CAPTURE_PERIOD_SIZE,
+ .periods_min = MIN_CAPTURE_NUM_PERIODS,
+ .periods_max = MAX_CAPTURE_NUM_PERIODS,
+ .fifo_size = 0,
+};
+
+
static enum hrtimer_restart afe_hrtimer_callback(struct hrtimer *hrt);
static enum hrtimer_restart afe_hrtimer_rec_callback(struct hrtimer *hrt);
@@ -130,6 +162,8 @@
struct snd_pcm_substream *substream = NULL;
struct snd_pcm_runtime *runtime = NULL;
uint16_t event;
+ uint64_t period_bytes;
+ uint64_t bytes_one_sec;
if (prtd == NULL)
return;
@@ -143,12 +177,28 @@
switch (event) {
case AFE_EVENT_RTPORT_START: {
prtd->dsp_cnt = 0;
- prtd->poll_time = ((unsigned long)((
- snd_pcm_lib_period_bytes
- (prtd->substream) *
- 1000 * 1000)/
- (runtime->rate *
- runtime->channels * 2)));
+ /* Calculate poll time.
+ * Split steps to avoid overflow.
+ * Poll time-time corresponding to one period
+ * in bytes.
+ * (Samplerate * channelcount * format) =
+ * bytes in 1 sec.
+ * Poll time =
+ * (period bytes / bytes in one sec) *
+ * 1000000 micro seconds.
+ * Multiplication by 1000000 is done in two
+ * steps to keep the accuracy of poll time.
+ */
+ period_bytes = ((uint64_t)(
+ (snd_pcm_lib_period_bytes(
+ prtd->substream)) *
+ 1000));
+ bytes_one_sec =
+ (runtime->rate * runtime->channels * 2);
+ bytes_one_sec =
+ div_u64(bytes_one_sec, 1000);
+ prtd->poll_time =
+ div_u64(period_bytes, bytes_one_sec);
pr_debug("prtd->poll_time: %d",
prtd->poll_time);
break;
@@ -197,6 +247,8 @@
struct snd_pcm_substream *substream = NULL;
struct snd_pcm_runtime *runtime = NULL;
uint16_t event;
+ uint64_t period_bytes;
+ uint64_t bytes_one_sec;
if (prtd == NULL)
return;
@@ -210,11 +262,22 @@
switch (event) {
case AFE_EVENT_RTPORT_START: {
prtd->dsp_cnt = 0;
- prtd->poll_time = ((unsigned long)((
- snd_pcm_lib_period_bytes(prtd->substream)
- * 1000 * 1000)/(runtime->rate
- * runtime->channels * 2)));
- pr_debug("prtd->poll_time : %d", prtd->poll_time);
+ /* Calculate poll time. Split steps to avoid overflow.
+ * Poll time-time corresponding to one period in bytes.
+ * (Samplerate * channelcount * format)=bytes in 1 sec.
+ * Poll time = (period bytes / bytes in one sec) *
+ * 1000000 micro seconds.
+ * Multiplication by 1000000 is done in two steps to
+ * keep the accuracy of poll time.
+ */
+ period_bytes = ((uint64_t)(
+ (snd_pcm_lib_period_bytes(prtd->substream)) *
+ 1000));
+ bytes_one_sec = (runtime->rate * runtime->channels * 2);
+ bytes_one_sec = div_u64(bytes_one_sec , 1000);
+ prtd->poll_time =
+ div_u64(period_bytes, bytes_one_sec);
+ pr_debug("prtd->poll_time : %d\n", prtd->poll_time);
break;
}
case AFE_EVENT_RTPORT_STOP:
@@ -326,7 +389,11 @@
mutex_lock(&prtd->lock);
- runtime->hw = msm_afe_hardware;
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ runtime->hw = msm_afe_hardware_playback;
+ else
+ runtime->hw = msm_afe_hardware_capture;
+
prtd->substream = substream;
runtime->private_data = prtd;
prtd->audio_client = q6afe_audio_client_alloc(prtd);
@@ -355,6 +422,18 @@
if (ret < 0)
pr_err("snd_pcm_hw_constraint_integer failed\n");
+ if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
+ ret = snd_pcm_hw_constraint_minmax(runtime,
+ SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
+ MIN_CAPTURE_NUM_PERIODS * MIN_CAPTURE_PERIOD_SIZE,
+ MAX_CAPTURE_NUM_PERIODS * MAX_CAPTURE_PERIOD_SIZE);
+
+ if (ret < 0) {
+ pr_err("constraint for buffer bytes min max ret = %d\n",
+ ret);
+ }
+ }
+
return 0;
}
@@ -497,10 +576,18 @@
dir = IN;
else
dir = OUT;
+
rc = q6afe_audio_client_buf_alloc_contiguous(dir,
- prtd->audio_client,
- runtime->hw.period_bytes_min,
- runtime->hw.periods_max);
+ prtd->audio_client,
+ (params_buffer_bytes(params) / params_periods(params)),
+ params_periods(params));
+ pr_debug("params_buffer_bytes(params) = %d\n",
+ (params_buffer_bytes(params)));
+ pr_debug("params_periods(params) = %d\n",
+ (params_periods(params)));
+ pr_debug("params_periodsize(params) = %d\n",
+ (params_buffer_bytes(params) / params_periods(params)));
+
if (rc < 0) {
pr_err("Audio Start: Buffer Allocation failed rc = %d\n", rc);
mutex_unlock(&prtd->lock);
@@ -519,14 +606,18 @@
dma_buf->private_data = NULL;
dma_buf->area = buf[0].data;
dma_buf->addr = buf[0].phys;
- dma_buf->bytes = runtime->hw.buffer_bytes_max;
+
+ dma_buf->bytes = params_buffer_bytes(params);
+
if (!dma_buf->area) {
pr_err("%s:MSM AFE physical memory allocation failed\n",
__func__);
mutex_unlock(&prtd->lock);
return -ENOMEM;
}
- memset(dma_buf->area, 0, runtime->hw.buffer_bytes_max);
+
+ memset(dma_buf->area, 0, params_buffer_bytes(params));
+
prtd->dma_addr = (u32) dma_buf->addr;
mutex_unlock(&prtd->lock);
diff --git a/sound/soc/msm/qdsp6v2/q6afe.c b/sound/soc/msm/qdsp6v2/q6afe.c
index 09d6a0f..9d6896e 100644
--- a/sound/soc/msm/qdsp6v2/q6afe.c
+++ b/sound/soc/msm/qdsp6v2/q6afe.c
@@ -944,7 +944,7 @@
i = port_id - SLIMBUS_0_RX;
if (i < 0 || i > ARRAY_SIZE(afe_ports_mad_type)) {
- pr_err("%s: Invalid port_id 0x%x\n", __func__, port_id);
+ pr_debug("%s: Non Slimbus port_id 0x%x\n", __func__, port_id);
return MAD_HW_NONE;
}
return (enum afe_mad_type) atomic_read(&afe_ports_mad_type[i]);
diff --git a/sound/soc/msm/qdsp6v2/q6voice.c b/sound/soc/msm/qdsp6v2/q6voice.c
index a417b26..80bc4f9 100644
--- a/sound/soc/msm/qdsp6v2/q6voice.c
+++ b/sound/soc/msm/qdsp6v2/q6voice.c
@@ -4116,6 +4116,11 @@
if (v != NULL)
v->voc_state = VOC_ERROR;
+ session_id = voc_get_session_id(VOICE2_SESSION_NAME);
+ v = voice_get_session(session_id);
+ if (v != NULL)
+ v->voc_state = VOC_ERROR;
+
session_id = voc_get_session_id(VOLTE_SESSION_NAME);
v = voice_get_session(session_id);
if (v != NULL)
@@ -4250,6 +4255,11 @@
if (v != NULL)
v->voc_state = VOC_ERROR;
+ session_id = voc_get_session_id(VOICE2_SESSION_NAME);
+ v = voice_get_session(session_id);
+ if (v != NULL)
+ v->voc_state = VOC_ERROR;
+
session_id = voc_get_session_id(VOLTE_SESSION_NAME);
v = voice_get_session(session_id);
if (v != NULL)
@@ -4515,6 +4525,11 @@
if (v != NULL)
v->voc_state = VOC_ERROR;
+ session_id = voc_get_session_id(VOICE2_SESSION_NAME);
+ v = voice_get_session(session_id);
+ if (v != NULL)
+ v->voc_state = VOC_ERROR;
+
session_id = voc_get_session_id(VOLTE_SESSION_NAME);
v = voice_get_session(session_id);
if (v != NULL)