Merge "msm: kgsl: Add a command dispatcher to manage the ringbuffer"
diff --git a/arch/arm/boot/dts/apq8074-v2-cdp.dts b/arch/arm/boot/dts/apq8074-v2.0-1-cdp.dts
similarity index 92%
rename from arch/arm/boot/dts/apq8074-v2-cdp.dts
rename to arch/arm/boot/dts/apq8074-v2.0-1-cdp.dts
index 1dc0912..0489b55 100644
--- a/arch/arm/boot/dts/apq8074-v2-cdp.dts
+++ b/arch/arm/boot/dts/apq8074-v2.0-1-cdp.dts
@@ -12,11 +12,11 @@
/dts-v1/;
-/include/ "apq8074-v2.dtsi"
+/include/ "apq8074-v2.0-1.dtsi"
/include/ "msm8974-cdp.dtsi"
/ {
- model = "Qualcomm APQ 8074v2 CDP";
+ model = "Qualcomm APQ 8074v2.0-1 CDP";
compatible = "qcom,apq8074-cdp", "qcom,apq8074", "qcom,cdp";
qcom,msm-id = <184 1 0x20000>;
};
diff --git a/arch/arm/boot/dts/apq8074-v2-dragonboard.dts b/arch/arm/boot/dts/apq8074-v2.0-1-dragonboard.dts
similarity index 89%
rename from arch/arm/boot/dts/apq8074-v2-dragonboard.dts
rename to arch/arm/boot/dts/apq8074-v2.0-1-dragonboard.dts
index 5a6f5f3..128d8bd 100644
--- a/arch/arm/boot/dts/apq8074-v2-dragonboard.dts
+++ b/arch/arm/boot/dts/apq8074-v2.0-1-dragonboard.dts
@@ -12,11 +12,11 @@
/dts-v1/;
-/include/ "apq8074-v2.dtsi"
+/include/ "apq8074-v2.0-1.dtsi"
/include/ "apq8074-dragonboard.dtsi"
/ {
- model = "Qualcomm APQ 8074v2 DRAGONBOARD";
+ model = "Qualcomm APQ 8074v2.0-1 DRAGONBOARD";
compatible = "qcom,apq8074-dragonboard", "qcom,apq8074", "qcom,dragonboard";
qcom,msm-id = <184 10 0x20000>;
};
diff --git a/arch/arm/boot/dts/apq8074-v2-liquid.dts b/arch/arm/boot/dts/apq8074-v2.0-1-liquid.dts
similarity index 89%
rename from arch/arm/boot/dts/apq8074-v2-liquid.dts
rename to arch/arm/boot/dts/apq8074-v2.0-1-liquid.dts
index a0ecb50..63c32f3 100644
--- a/arch/arm/boot/dts/apq8074-v2-liquid.dts
+++ b/arch/arm/boot/dts/apq8074-v2.0-1-liquid.dts
@@ -12,11 +12,11 @@
/dts-v1/;
-/include/ "apq8074-v2.dtsi"
+/include/ "apq8074-v2.0-1.dtsi"
/include/ "msm8974-liquid.dtsi"
/ {
- model = "Qualcomm APQ 8074v2 LIQUID";
+ model = "Qualcomm APQ 8074v2.0-1 LIQUID";
compatible = "qcom,apq8074-liquid", "qcom,apq8074", "qcom,liquid";
qcom,msm-id = <184 9 0x20000>;
};
diff --git a/arch/arm/boot/dts/apq8074-v2.dtsi b/arch/arm/boot/dts/apq8074-v2.0-1.dtsi
similarity index 97%
rename from arch/arm/boot/dts/apq8074-v2.dtsi
rename to arch/arm/boot/dts/apq8074-v2.0-1.dtsi
index c700a5c..8314fab 100644
--- a/arch/arm/boot/dts/apq8074-v2.dtsi
+++ b/arch/arm/boot/dts/apq8074-v2.0-1.dtsi
@@ -16,7 +16,7 @@
* msm8974.dtsi file.
*/
-/include/ "msm8974-v2.dtsi"
+/include/ "msm8974-v2.0-1.dtsi"
&soc {
qcom,qseecom@a700000 {
diff --git a/arch/arm/boot/dts/apq8084.dtsi b/arch/arm/boot/dts/apq8084.dtsi
index b027f7d..943f2a3 100644
--- a/arch/arm/boot/dts/apq8084.dtsi
+++ b/arch/arm/boot/dts/apq8084.dtsi
@@ -344,6 +344,12 @@
qcom,pet-time = <10000>;
qcom,ipi-ping;
};
+
+ qcom,msm-rng@f9bff000{
+ compatible = "qcom,msm-rng";
+ reg = <0xf9bff000 0x200>;
+ qcom,msm-rng-iface-clk;
+ };
};
&gdsc_venus {
diff --git a/arch/arm/boot/dts/msm8610-qrd-skuab.dts b/arch/arm/boot/dts/msm8610-qrd-skuab.dts
index c435038..947a312 100644
--- a/arch/arm/boot/dts/msm8610-qrd-skuab.dts
+++ b/arch/arm/boot/dts/msm8610-qrd-skuab.dts
@@ -76,7 +76,7 @@
vdd-supply = <&pm8110_l19>;
vio-supply = <&pm8110_l14>;
fsl,irq-gpio = <&msmgpio 81 0x00>;
- fsl,sensors-position = <5>;
+ fsl,sensors-position = <1>;
};
};
diff --git a/arch/arm/boot/dts/msm8974-v1.dtsi b/arch/arm/boot/dts/msm8974-v1.dtsi
index 7b801da..86a61cd 100644
--- a/arch/arm/boot/dts/msm8974-v1.dtsi
+++ b/arch/arm/boot/dts/msm8974-v1.dtsi
@@ -148,3 +148,20 @@
&usb_otg {
qcom,hsusb-otg-pnoc-errata-fix;
};
+
+&gdsc_venus {
+ qcom,skip-logic-collapse;
+ qcom,retain-periph;
+ qcom,retain-mem;
+};
+
+&gdsc_mdss {
+ qcom,skip-logic-collapse;
+ qcom,retain-periph;
+ qcom,retain-mem;
+};
+
+&gdsc_oxili_gx {
+ qcom,retain-mem;
+ qcom,retain-periph;
+};
diff --git a/arch/arm/boot/dts/msm8974-v2-cdp.dts b/arch/arm/boot/dts/msm8974-v2.0-1-cdp.dts
similarity index 90%
rename from arch/arm/boot/dts/msm8974-v2-cdp.dts
rename to arch/arm/boot/dts/msm8974-v2.0-1-cdp.dts
index f4014aa..875b3fc 100644
--- a/arch/arm/boot/dts/msm8974-v2-cdp.dts
+++ b/arch/arm/boot/dts/msm8974-v2.0-1-cdp.dts
@@ -12,11 +12,11 @@
/dts-v1/;
-/include/ "msm8974-v2.dtsi"
+/include/ "msm8974-v2.0-1.dtsi"
/include/ "msm8974-cdp.dtsi"
/ {
- model = "Qualcomm MSM 8974v2 CDP";
+ model = "Qualcomm MSM 8974v2.0/1 CDP";
compatible = "qcom,msm8974-cdp", "qcom,msm8974", "qcom,cdp";
qcom,msm-id = <126 1 0x20000>,
<185 1 0x20000>,
diff --git a/arch/arm/boot/dts/msm8974-v2-fluid.dts b/arch/arm/boot/dts/msm8974-v2.0-1-fluid.dts
similarity index 90%
rename from arch/arm/boot/dts/msm8974-v2-fluid.dts
rename to arch/arm/boot/dts/msm8974-v2.0-1-fluid.dts
index 9c9e3c0..236593d 100644
--- a/arch/arm/boot/dts/msm8974-v2-fluid.dts
+++ b/arch/arm/boot/dts/msm8974-v2.0-1-fluid.dts
@@ -12,11 +12,11 @@
/dts-v1/;
-/include/ "msm8974-v2.dtsi"
+/include/ "msm8974-v2.0-1.dtsi"
/include/ "msm8974-fluid.dtsi"
/ {
- model = "Qualcomm MSM 8974v2 FLUID";
+ model = "Qualcomm MSM 8974v2.0/1 FLUID";
compatible = "qcom,msm8974-fluid", "qcom,msm8974", "qcom,fluid";
qcom,msm-id = <126 3 0x20000>,
<185 3 0x20000>,
diff --git a/arch/arm/boot/dts/msm8974-v2-liquid.dts b/arch/arm/boot/dts/msm8974-v2.0-1-liquid.dts
similarity index 90%
rename from arch/arm/boot/dts/msm8974-v2-liquid.dts
rename to arch/arm/boot/dts/msm8974-v2.0-1-liquid.dts
index ddae6fe..23292f6 100644
--- a/arch/arm/boot/dts/msm8974-v2-liquid.dts
+++ b/arch/arm/boot/dts/msm8974-v2.0-1-liquid.dts
@@ -12,11 +12,11 @@
/dts-v1/;
-/include/ "msm8974-v2.dtsi"
+/include/ "msm8974-v2.0-1.dtsi"
/include/ "msm8974-liquid.dtsi"
/ {
- model = "Qualcomm MSM 8974v2 LIQUID";
+ model = "Qualcomm MSM 8974v2.0/1 LIQUID";
compatible = "qcom,msm8974-liquid", "qcom,msm8974", "qcom,liquid";
qcom,msm-id = <126 9 0x20000>,
<185 9 0x20000>,
diff --git a/arch/arm/boot/dts/msm8974-v2-mtp.dts b/arch/arm/boot/dts/msm8974-v2.0-1-mtp.dts
similarity index 91%
rename from arch/arm/boot/dts/msm8974-v2-mtp.dts
rename to arch/arm/boot/dts/msm8974-v2.0-1-mtp.dts
index 021b626..de9e6a3 100644
--- a/arch/arm/boot/dts/msm8974-v2-mtp.dts
+++ b/arch/arm/boot/dts/msm8974-v2.0-1-mtp.dts
@@ -12,11 +12,11 @@
/dts-v1/;
-/include/ "msm8974-v2.dtsi"
+/include/ "msm8974-v2.0-1.dtsi"
/include/ "msm8974-mtp.dtsi"
/ {
- model = "Qualcomm MSM 8974v2 MTP";
+ model = "Qualcomm MSM 8974v2.0/1 MTP";
compatible = "qcom,msm8974-mtp", "qcom,msm8974", "qcom,mtp";
qcom,msm-id = <126 8 0x20000>,
<185 8 0x20000>,
diff --git a/arch/arm/boot/dts/msm8974-v2.0-1.dtsi b/arch/arm/boot/dts/msm8974-v2.0-1.dtsi
new file mode 100644
index 0000000..1fad868
--- /dev/null
+++ b/arch/arm/boot/dts/msm8974-v2.0-1.dtsi
@@ -0,0 +1,36 @@
+/* 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.
+ */
+
+/*
+ * As a general rule, only version-specific property overrides should be placed
+ * inside this file. However, device definitions should be placed inside the
+ * msm8974.dtsi file.
+ */
+
+/include/ "msm8974-v2.dtsi"
+
+&gdsc_venus {
+ qcom,skip-logic-collapse;
+ qcom,retain-periph;
+ qcom,retain-mem;
+};
+
+&gdsc_mdss {
+ qcom,skip-logic-collapse;
+ qcom,retain-periph;
+ qcom,retain-mem;
+};
+
+&gdsc_oxili_gx {
+ qcom,retain-mem;
+ qcom,retain-periph;
+};
diff --git a/arch/arm/boot/dts/msm8974-v2.2.dtsi b/arch/arm/boot/dts/msm8974-v2.2.dtsi
index 09455b1..0ca021b 100644
--- a/arch/arm/boot/dts/msm8974-v2.2.dtsi
+++ b/arch/arm/boot/dts/msm8974-v2.2.dtsi
@@ -103,3 +103,8 @@
};
};
};
+
+&gdsc_mdss {
+ qcom,retain-periph;
+ qcom,retain-mem;
+};
diff --git a/arch/arm/boot/dts/msm8974.dtsi b/arch/arm/boot/dts/msm8974.dtsi
index 59e8dac..4360fe0 100644
--- a/arch/arm/boot/dts/msm8974.dtsi
+++ b/arch/arm/boot/dts/msm8974.dtsi
@@ -1651,17 +1651,11 @@
&gdsc_venus {
qcom,clock-names = "core_clk";
- qcom,skip-logic-collapse;
- qcom,retain-periph;
- qcom,retain-mem;
status = "ok";
};
&gdsc_mdss {
qcom,clock-names = "core_clk", "lut_clk";
- qcom,skip-logic-collapse;
- qcom,retain-periph;
- qcom,retain-mem;
status = "ok";
};
@@ -1678,8 +1672,6 @@
&gdsc_oxili_gx {
qcom,clock-names = "core_clk";
- qcom,retain-mem;
- qcom,retain-periph;
status = "ok";
};
diff --git a/arch/arm/configs/msm8610_defconfig b/arch/arm/configs/msm8610_defconfig
index cfd346e..a5f0704 100644
--- a/arch/arm/configs/msm8610_defconfig
+++ b/arch/arm/configs/msm8610_defconfig
@@ -71,7 +71,6 @@
CONFIG_MSM_RTB_SEPARATE_CPUS=y
CONFIG_MSM_ENABLE_WDOG_DEBUG_CONTROL=y
CONFIG_MSM_BOOT_STATS=y
-CONFIG_MSM_XPU_ERR_FATAL=y
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
CONFIG_SMP=y
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index b80949c..76bd74c 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -284,6 +284,7 @@
select MSM_ULTRASOUND_B
select MSM_RPM_LOG
select ARCH_WANT_KMAP_ATOMIC_FLUSH
+ select KRAIT_REGULATOR
config ARCH_APQ8084
bool "APQ8084"
@@ -3060,4 +3061,11 @@
Support the wallclk directory in sysfs filesystem to enable the
wall clock simulation and read the current SFN.
+config KRAIT_REGULATOR
+ bool "Support Kraits powered via ganged regulators in the pmic"
+ help
+ Certain MSMs have the Krait CPUs powered via a single supply
+ line from the PMIC. This supply line is powered by multiple
+ regulators running in ganged mode inside the PMIC. Enable
+ this option to support such configurations.
endif
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index 8c42b8d..cd71104 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -296,7 +296,7 @@
obj-$(CONFIG_ARCH_MSM8610) += gdsc.o
obj-$(CONFIG_ARCH_MPQ8092) += gdsc.o
obj-$(CONFIG_ARCH_APQ8084) += gdsc.o
-obj-$(CONFIG_ARCH_MSM8974) += krait-regulator.o
+obj-$(CONFIG_KRAIT_REGULATOR) += krait-regulator.o
obj-$(CONFIG_ARCH_MSMKRYPTON) += board-krypton.o board-krypton-gpiomux.o
obj-$(CONFIG_ARCH_MSMSAMARIUM) += board-samarium.o board-samarium-gpiomux.o
obj-$(CONFIG_ARCH_MSM9625) += board-9625.o board-9625-gpiomux.o
diff --git a/arch/arm/mach-msm/Makefile.boot b/arch/arm/mach-msm/Makefile.boot
index 3505afe..72472f9 100644
--- a/arch/arm/mach-msm/Makefile.boot
+++ b/arch/arm/mach-msm/Makefile.boot
@@ -53,13 +53,13 @@
dtb-$(CONFIG_ARCH_MSM8974) += msm8974-v1-mtp.dtb
dtb-$(CONFIG_ARCH_MSM8974) += msm8974-v1-rumi.dtb
dtb-$(CONFIG_ARCH_MSM8974) += msm8974-v1-sim.dtb
- dtb-$(CONFIG_ARCH_MSM8974) += msm8974-v2-cdp.dtb
- dtb-$(CONFIG_ARCH_MSM8974) += msm8974-v2-fluid.dtb
- dtb-$(CONFIG_ARCH_MSM8974) += msm8974-v2-liquid.dtb
- dtb-$(CONFIG_ARCH_MSM8974) += msm8974-v2-mtp.dtb
- dtb-$(CONFIG_ARCH_MSM8974) += apq8074-v2-cdp.dtb
- dtb-$(CONFIG_ARCH_MSM8974) += apq8074-v2-liquid.dtb
- dtb-$(CONFIG_ARCH_MSM8974) += apq8074-v2-dragonboard.dtb
+ dtb-$(CONFIG_ARCH_MSM8974) += msm8974-v2.0-1-cdp.dtb
+ dtb-$(CONFIG_ARCH_MSM8974) += msm8974-v2.0-1-fluid.dtb
+ dtb-$(CONFIG_ARCH_MSM8974) += msm8974-v2.0-1-liquid.dtb
+ dtb-$(CONFIG_ARCH_MSM8974) += msm8974-v2.0-1-mtp.dtb
+ dtb-$(CONFIG_ARCH_MSM8974) += apq8074-v2.0-1-cdp.dtb
+ dtb-$(CONFIG_ARCH_MSM8974) += apq8074-v2.0-1-liquid.dtb
+ dtb-$(CONFIG_ARCH_MSM8974) += apq8074-v2.0-1-dragonboard.dtb
# APQ8084
zreladdr-$(CONFIG_ARCH_APQ8084) := 0x00008000
diff --git a/arch/arm/mach-msm/include/mach/msm_smem.h b/arch/arm/mach-msm/include/mach/msm_smem.h
index 64ab6bf..a121791 100644
--- a/arch/arm/mach-msm/include/mach/msm_smem.h
+++ b/arch/arm/mach-msm/include/mach/msm_smem.h
@@ -136,6 +136,7 @@
SMEM_BAM_PIPE_MEMORY, /* 468 */
SMEM_IMAGE_VERSION_TABLE, /* 469 */
SMEM_LC_DEBUGGER, /* 470 */
+ SMEM_FLASH_NAND_DEV_INFO, /* 471 */
SMEM_NUM_ITEMS,
};
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_board_9625.c b/arch/arm/mach-msm/msm_bus/msm_bus_board_9625.c
index 3a996eb..4538c4f 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_board_9625.c
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_board_9625.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
@@ -524,6 +524,7 @@
.mode = NOC_QOS_MODE_FIXED,
.qport = qports_ipa,
.mas_hw_id = MAS_IPA,
+ .hw_sel = MSM_BUS_NOC,
},
{
.id = MSM_BUS_MASTER_QDSS_ETR,
diff --git a/drivers/char/diag/diagchar.h b/drivers/char/diag/diagchar.h
index cf21b82..7ef1d80 100644
--- a/drivers/char/diag/diagchar.h
+++ b/drivers/char/diag/diagchar.h
@@ -308,7 +308,7 @@
mempool_t *diag_hdlc_pool;
mempool_t *diag_user_pool;
mempool_t *diag_write_struct_pool;
- struct mutex diagmem_mutex;
+ spinlock_t diag_mem_lock;
int count;
int count_hdlc_pool;
int count_user_pool;
diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c
index 099dc09..24d7fac 100644
--- a/drivers/char/diag/diagchar_core.c
+++ b/drivers/char/diag/diagchar_core.c
@@ -131,12 +131,8 @@
mutex_lock(&driver->diagchar_mutex);
if (buf_hdlc) {
err = diag_device_write(buf_hdlc, APPS_DATA, NULL);
- if (err) {
- /*Free the buffer right away if write failed */
+ if (err)
diagmem_free(driver, buf_hdlc, POOL_TYPE_HDLC);
- diagmem_free(driver, (unsigned char *)driver->
- write_ptr_svc, POOL_TYPE_WRITE_STRUCT);
- }
buf_hdlc = NULL;
#ifdef DIAG_DEBUG
pr_debug("diag: Number of bytes written "
@@ -1818,10 +1814,6 @@
if (HDLC_OUT_BUF_SIZE - driver->used <= (2*payload_size) + 3) {
err = diag_device_write(buf_hdlc, APPS_DATA, NULL);
if (err) {
- /*Free the buffer right away if write failed */
- if (driver->logging_mode == USB_MODE)
- diagmem_free(driver, (unsigned char *)driver->
- write_ptr_svc, POOL_TYPE_WRITE_STRUCT);
ret = -EIO;
goto fail_free_hdlc;
}
@@ -1846,10 +1838,6 @@
(unsigned int)(buf_hdlc + HDLC_OUT_BUF_SIZE)) {
err = diag_device_write(buf_hdlc, APPS_DATA, NULL);
if (err) {
- /*Free the buffer right away if write failed */
- if (driver->logging_mode == USB_MODE)
- diagmem_free(driver, (unsigned char *)driver->
- write_ptr_svc, POOL_TYPE_WRITE_STRUCT);
ret = -EIO;
goto fail_free_hdlc;
}
@@ -1871,10 +1859,6 @@
if (pkt_type == DATA_TYPE_RESPONSE) {
err = diag_device_write(buf_hdlc, APPS_DATA, NULL);
if (err) {
- /*Free the buffer right away if write failed */
- if (driver->logging_mode == USB_MODE)
- diagmem_free(driver, (unsigned char *)driver->
- write_ptr_svc, POOL_TYPE_WRITE_STRUCT);
ret = -EIO;
goto fail_free_hdlc;
}
diff --git a/drivers/char/diag/diagfwd.c b/drivers/char/diag/diagfwd.c
index 609d6cd..a1f6b2c 100644
--- a/drivers/char/diag/diagfwd.c
+++ b/drivers/char/diag/diagfwd.c
@@ -789,8 +789,16 @@
driver->write_ptr_svc->buf = buf;
err = usb_diag_write(driver->legacy_ch,
driver->write_ptr_svc);
- } else
- err = -1;
+ /* Free the buffer if write failed */
+ if (err) {
+ diagmem_free(driver,
+ (unsigned char *)driver->
+ write_ptr_svc,
+ POOL_TYPE_WRITE_STRUCT);
+ }
+ } else {
+ err = -ENOMEM;
+ }
} else if ((data_type >= MODEM_DATA) &&
(data_type <= WCNSS_DATA)) {
write_ptr->buf = buf;
@@ -1762,6 +1770,9 @@
}
#endif
if (!found_it) {
+ if (driver->logging_mode != USB_MODE)
+ pr_debug("diag: freeing buffer when not in usb mode\n");
+
diagmem_free(driver, (unsigned char *)buf,
POOL_TYPE_HDLC);
diagmem_free(driver, (unsigned char *)diag_write_ptr,
diff --git a/drivers/char/diag/diagmem.c b/drivers/char/diag/diagmem.c
index a6ef3ca..4ceca4f 100644
--- a/drivers/char/diag/diagmem.c
+++ b/drivers/char/diag/diagmem.c
@@ -25,22 +25,24 @@
void *diagmem_alloc(struct diagchar_dev *driver, int size, int pool_type)
{
void *buf = NULL;
+ unsigned long flags;
int index;
+ spin_lock_irqsave(&driver->diag_mem_lock, flags);
index = 0;
if (pool_type == POOL_TYPE_COPY) {
if (driver->diagpool) {
- mutex_lock(&driver->diagmem_mutex);
- if (driver->count < driver->poolsize) {
+ if ((driver->count < driver->poolsize) &&
+ (size <= driver->itemsize)) {
atomic_add(1, (atomic_t *)&driver->count);
buf = mempool_alloc(driver->diagpool,
GFP_ATOMIC);
}
- mutex_unlock(&driver->diagmem_mutex);
}
} else if (pool_type == POOL_TYPE_HDLC) {
if (driver->diag_hdlc_pool) {
- if (driver->count_hdlc_pool < driver->poolsize_hdlc) {
+ if ((driver->count_hdlc_pool < driver->poolsize_hdlc) &&
+ (size <= driver->itemsize_hdlc)) {
atomic_add(1,
(atomic_t *)&driver->count_hdlc_pool);
buf = mempool_alloc(driver->diag_hdlc_pool,
@@ -49,7 +51,8 @@
}
} else if (pool_type == POOL_TYPE_USER) {
if (driver->diag_user_pool) {
- if (driver->count_user_pool < driver->poolsize_user) {
+ if ((driver->count_user_pool < driver->poolsize_user) &&
+ (size <= driver->itemsize_user)) {
atomic_add(1,
(atomic_t *)&driver->count_user_pool);
buf = mempool_alloc(driver->diag_user_pool,
@@ -58,8 +61,9 @@
}
} else if (pool_type == POOL_TYPE_WRITE_STRUCT) {
if (driver->diag_write_struct_pool) {
- if (driver->count_write_struct_pool <
- driver->poolsize_write_struct) {
+ if ((driver->count_write_struct_pool <
+ driver->poolsize_write_struct) &&
+ (size <= driver->itemsize_write_struct)) {
atomic_add(1,
(atomic_t *)&driver->count_write_struct_pool);
buf = mempool_alloc(
@@ -71,8 +75,9 @@
pool_type == POOL_TYPE_HSIC_2) {
index = pool_type - POOL_TYPE_HSIC;
if (diag_hsic[index].diag_hsic_pool) {
- if (diag_hsic[index].count_hsic_pool <
- diag_hsic[index].poolsize_hsic) {
+ if ((diag_hsic[index].count_hsic_pool <
+ diag_hsic[index].poolsize_hsic) &&
+ (size <= diag_hsic[index].itemsize_hsic)) {
atomic_add(1, (atomic_t *)
&diag_hsic[index].count_hsic_pool);
buf = mempool_alloc(
@@ -85,7 +90,8 @@
index = pool_type - POOL_TYPE_HSIC_WRITE;
if (diag_hsic[index].diag_hsic_write_pool) {
if (diag_hsic[index].count_hsic_write_pool <
- diag_hsic[index].poolsize_hsic_write) {
+ diag_hsic[index].poolsize_hsic_write &&
+ (size <= diag_hsic[index].itemsize_hsic_write)) {
atomic_add(1, (atomic_t *)
&diag_hsic[index].
count_hsic_write_pool);
@@ -96,14 +102,17 @@
}
#endif
}
+ spin_unlock_irqrestore(&driver->diag_mem_lock, flags);
return buf;
}
void diagmem_exit(struct diagchar_dev *driver, int pool_type)
{
int index;
+ unsigned long flags;
index = 0;
+ spin_lock_irqsave(&driver->diag_mem_lock, flags);
if (driver->diagpool) {
if (driver->count == 0 && driver->ref_count == 0) {
mempool_destroy(driver->diagpool);
@@ -176,12 +185,18 @@
}
}
#endif
+ spin_unlock_irqrestore(&driver->diag_mem_lock, flags);
}
void diagmem_free(struct diagchar_dev *driver, void *buf, int pool_type)
{
int index;
+ unsigned long flags;
+ if (!buf)
+ return;
+
+ spin_lock_irqsave(&driver->diag_mem_lock, flags);
index = 0;
if (pool_type == POOL_TYPE_COPY) {
if (driver->diagpool != NULL && driver->count > 0) {
@@ -246,13 +261,13 @@
__func__, pool_type);
}
-
+ spin_unlock_irqrestore(&driver->diag_mem_lock, flags);
diagmem_exit(driver, pool_type);
}
void diagmem_init(struct diagchar_dev *driver)
{
- mutex_init(&driver->diagmem_mutex);
+ spin_lock_init(&driver->diag_mem_lock);
if (driver->count == 0) {
driver->diagpool = mempool_create_kmalloc_pool(
diff --git a/drivers/gpu/msm/kgsl_pwrscale_trustzone.c b/drivers/gpu/msm/kgsl_pwrscale_trustzone.c
index 40649d2..8fc1753 100644
--- a/drivers/gpu/msm/kgsl_pwrscale_trustzone.c
+++ b/drivers/gpu/msm/kgsl_pwrscale_trustzone.c
@@ -235,8 +235,10 @@
tz_pwrlevels[0] = j;
ret = scm_call(SCM_SVC_DCVS, TZ_INIT_ID, tz_pwrlevels,
sizeof(tz_pwrlevels), NULL, 0);
- if (ret)
+ if (ret) {
+ KGSL_DRV_ERR(device, "Fall back to idle based GPU DCVS algo");
priv->idle_dcvs = 1;
+ }
return 0;
}
#else
diff --git a/drivers/iommu/msm_iommu-v1.c b/drivers/iommu/msm_iommu-v1.c
index b9c4cae..53c7c30 100644
--- a/drivers/iommu/msm_iommu-v1.c
+++ b/drivers/iommu/msm_iommu-v1.c
@@ -692,7 +692,6 @@
if (ret)
goto fail;
- ret = __flush_iotlb_va(domain, va);
fail:
mutex_unlock(&msm_iommu_lock);
return ret;
@@ -742,7 +741,6 @@
if (ret)
goto fail;
- __flush_iotlb(domain);
fail:
mutex_unlock(&msm_iommu_lock);
return ret;
diff --git a/drivers/iommu/msm_iommu_sec.c b/drivers/iommu/msm_iommu_sec.c
index 474efdf..78fffb2 100644
--- a/drivers/iommu/msm_iommu_sec.c
+++ b/drivers/iommu/msm_iommu_sec.c
@@ -371,7 +371,7 @@
map.info.ctx_id = ctx_drvdata->num;
map.info.va = va;
map.info.size = len;
- map.flags = IOMMU_TLBINVAL_FLAG;
+ map.flags = 0;
flush_va = &pa;
flush_pa = virt_to_phys(&pa);
@@ -421,7 +421,7 @@
map.info.ctx_id = ctx_drvdata->num;
map.info.va = va;
map.info.size = len;
- map.flags = IOMMU_TLBINVAL_FLAG;
+ map.flags = 0;
if (sg->length == len) {
pa = get_phys_addr(sg);
diff --git a/drivers/media/dvb/dvb-core/dvb_demux.c b/drivers/media/dvb/dvb-core/dvb_demux.c
index 692a04e..9d606a1 100644
--- a/drivers/media/dvb/dvb-core/dvb_demux.c
+++ b/drivers/media/dvb/dvb-core/dvb_demux.c
@@ -128,6 +128,20 @@
DMX_IDX_H264_NON_IDR_START
};
+static const struct dvb_dmx_video_patterns h264_non_access_unit_del = {
+ {0x00, 0x00, 0x01, 0x09},
+ {0xFF, 0xFF, 0xFF, 0x1F},
+ 4,
+ DMX_IDX_H264_ACCESS_UNIT_DEL
+};
+
+static const struct dvb_dmx_video_patterns h264_non_sei = {
+ {0x00, 0x00, 0x01, 0x06},
+ {0xFF, 0xFF, 0xFF, 0x1F},
+ 4,
+ DMX_IDX_H264_SEI
+};
+
static const struct dvb_dmx_video_patterns vc1_seq_hdr = {
{0x00, 0x00, 0x01, 0x0F},
{0xFF, 0xFF, 0xFF, 0xFF},
@@ -1791,6 +1805,12 @@
case DMX_IDX_H264_NON_IDR_START:
return &h264_non_idr;
+ case DMX_IDX_H264_ACCESS_UNIT_DEL:
+ return &h264_non_access_unit_del;
+
+ case DMX_IDX_H264_SEI:
+ return &h264_non_sei;
+
case DMX_IDX_VC1_SEQ_HEADER:
return &vc1_seq_hdr;
@@ -1913,6 +1933,20 @@
}
if ((feed->pattern_num < DVB_DMX_MAX_SEARCH_PATTERN_NUM) &&
+ (feed->idx_params.types & DMX_IDX_H264_ACCESS_UNIT_DEL)) {
+ feed->patterns[feed->pattern_num] =
+ dvb_dmx_get_pattern(DMX_IDX_H264_ACCESS_UNIT_DEL);
+ feed->pattern_num++;
+ }
+
+ if ((feed->pattern_num < DVB_DMX_MAX_SEARCH_PATTERN_NUM) &&
+ (feed->idx_params.types & DMX_IDX_H264_SEI)) {
+ feed->patterns[feed->pattern_num] =
+ dvb_dmx_get_pattern(DMX_IDX_H264_SEI);
+ feed->pattern_num++;
+ }
+
+ if ((feed->pattern_num < DVB_DMX_MAX_SEARCH_PATTERN_NUM) &&
(feed->idx_params.types &
(DMX_IDX_VC1_SEQ_HEADER |
DMX_IDX_VC1_FIRST_SEQ_FRAME_START |
diff --git a/drivers/media/platform/msm/camera_v2/camera/camera.c b/drivers/media/platform/msm/camera_v2/camera/camera.c
index d3618c0..c70e151 100644
--- a/drivers/media/platform/msm/camera_v2/camera/camera.c
+++ b/drivers/media/platform/msm/camera_v2/camera/camera.c
@@ -328,6 +328,10 @@
pr_debug("%s: num planes :%c\n", __func__,
user_fmt->num_planes);
+ /*num_planes need to bound checked, otherwise for loop
+ can execute forever */
+ if (WARN_ON(user_fmt->num_planes > VIDEO_MAX_PLANES))
+ return -EINVAL;
for (i = 0; i < user_fmt->num_planes; i++)
pr_debug("%s: plane size[%d]\n", __func__,
user_fmt->plane_sizes[i]);
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp.h b/drivers/media/platform/msm/camera_v2/isp/msm_isp.h
index f1f4c17..8c42ed2 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp.h
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp.h
@@ -90,7 +90,8 @@
void (*enable_wm) (struct vfe_device *vfe_dev,
uint8_t wm_idx, uint8_t enable);
void (*cfg_io_format) (struct vfe_device *vfe_dev,
- struct msm_vfe_axi_stream *stream_info);
+ enum msm_vfe_axi_stream_src stream_src,
+ uint32_t io_format);
void (*cfg_framedrop) (struct vfe_device *vfe_dev,
struct msm_vfe_axi_stream *stream_info);
void (*clear_framedrop) (struct vfe_device *vfe_dev,
@@ -289,6 +290,7 @@
enum msm_vfe_inputmux input_mux;
uint32_t width;
long pixel_clock;
+ uint32_t input_format;
};
enum msm_wm_ub_cfg_type {
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp32.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp32.c
index 07a66e6..3722066 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp32.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp32.c
@@ -481,11 +481,11 @@
}
static void msm_vfe32_cfg_io_format(struct vfe_device *vfe_dev,
- struct msm_vfe_axi_stream *stream_info)
+ enum msm_vfe_axi_stream_src stream_src, uint32_t io_format)
{
int bpp, bpp_reg = 0;
uint32_t io_format_reg;
- bpp = msm_isp_get_bit_per_pixel(stream_info->output_format);
+ bpp = msm_isp_get_bit_per_pixel(io_format);
switch (bpp) {
case 8:
@@ -499,7 +499,9 @@
break;
}
io_format_reg = msm_camera_io_r(vfe_dev->vfe_base + 0x6F8);
- switch (stream_info->stream_src) {
+ switch (stream_src) {
+ case PIX_ENCODER:
+ case PIX_VIEWFINDER:
case CAMIF_RAW:
io_format_reg &= 0xFFFFCFFF;
io_format_reg |= bpp_reg << 12;
@@ -508,8 +510,6 @@
io_format_reg &= 0xFFFFFFC8;
io_format_reg |= bpp_reg << 4;
break;
- case PIX_ENCODER:
- case PIX_VIEWFINDER:
case RDI_INTF_0:
case RDI_INTF_1:
case RDI_INTF_2:
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c
index 2db25a6..84b95f1 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp40.c
@@ -688,11 +688,11 @@
}
static void msm_vfe40_cfg_io_format(struct vfe_device *vfe_dev,
- struct msm_vfe_axi_stream *stream_info)
+ enum msm_vfe_axi_stream_src stream_src, uint32_t io_format)
{
int bpp, bpp_reg = 0;
uint32_t io_format_reg;
- bpp = msm_isp_get_bit_per_pixel(stream_info->output_format);
+ bpp = msm_isp_get_bit_per_pixel(io_format);
switch (bpp) {
case 8:
@@ -706,7 +706,9 @@
break;
}
io_format_reg = msm_camera_io_r(vfe_dev->vfe_base + 0x54);
- switch (stream_info->stream_src) {
+ switch (stream_src) {
+ case PIX_ENCODER:
+ case PIX_VIEWFINDER:
case CAMIF_RAW:
io_format_reg &= 0xFFFFCFFF;
io_format_reg |= bpp_reg << 12;
@@ -715,8 +717,6 @@
io_format_reg &= 0xFFFFFFC8;
io_format_reg |= bpp_reg << 4;
break;
- case PIX_ENCODER:
- case PIX_VIEWFINDER:
case RDI_INTF_0:
case RDI_INTF_1:
case RDI_INTF_2:
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
index d3138ed..5b7658d 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
@@ -474,6 +474,7 @@
int msm_isp_request_axi_stream(struct vfe_device *vfe_dev, void *arg)
{
int rc = 0, i;
+ uint32_t io_format = 0;
struct msm_vfe_axi_stream_request_cmd *stream_cfg_cmd = arg;
struct msm_vfe_axi_stream *stream_info;
@@ -497,10 +498,20 @@
stream_info[HANDLE_TO_IDX(stream_cfg_cmd->axi_stream_handle)];
msm_isp_axi_reserve_wm(&vfe_dev->axi_data, stream_info);
- if (stream_cfg_cmd->stream_src == CAMIF_RAW ||
- stream_cfg_cmd->stream_src == IDEAL_RAW)
- vfe_dev->hw_info->vfe_ops.axi_ops.
- cfg_io_format(vfe_dev, stream_info);
+ if (stream_info->stream_src < RDI_INTF_0) {
+ io_format = vfe_dev->axi_data.src_info[VFE_PIX_0].input_format;
+ if (stream_info->stream_src == CAMIF_RAW ||
+ stream_info->stream_src == IDEAL_RAW) {
+ if (stream_info->stream_src == CAMIF_RAW &&
+ io_format != stream_info->output_format)
+ pr_warn("%s: Overriding input format\n",
+ __func__);
+
+ io_format = stream_info->output_format;
+ }
+ vfe_dev->hw_info->vfe_ops.axi_ops.cfg_io_format(
+ vfe_dev, stream_info->stream_src, io_format);
+ }
msm_isp_calculate_framedrop(&vfe_dev->axi_data, stream_cfg_cmd);
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
index 3806213..590b636 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
@@ -273,6 +273,9 @@
return rc;
}
+ vfe_dev->axi_data.src_info[VFE_PIX_0].input_format =
+ input_cfg->d.pix_cfg.input_format;
+
vfe_dev->hw_info->vfe_ops.core_ops.cfg_camif(
vfe_dev, &input_cfg->d.pix_cfg);
return rc;
diff --git a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c
index a4eb274..822c0c8 100644
--- a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c
+++ b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c
@@ -1219,6 +1219,14 @@
goto ERROR1;
}
+ if ((new_frame->msg_len == 0) ||
+ (new_frame->msg_len > MSM_CPP_MAX_FRAME_LENGTH)) {
+ pr_err("%s:%d: Invalid frame len:%d\n", __func__,
+ __LINE__, new_frame->msg_len);
+ rc = -EINVAL;
+ goto ERROR1;
+ }
+
cpp_frame_msg = kzalloc(sizeof(uint32_t)*new_frame->msg_len,
GFP_KERNEL);
if (!cpp_frame_msg) {
@@ -1380,7 +1388,10 @@
pr_err("ioctl_ptr is null\n");
return -EINVAL;
}
-
+ if (cpp_dev == NULL) {
+ pr_err("cpp_dev is null\n");
+ return -EINVAL;
+ }
mutex_lock(&cpp_dev->mutex);
CPP_DBG("E cmd: %d\n", cmd);
switch (cmd) {
@@ -1396,8 +1407,16 @@
case VIDIOC_MSM_CPP_LOAD_FIRMWARE: {
if (cpp_dev->is_firmware_loaded == 0) {
- kfree(cpp_dev->fw_name_bin);
- cpp_dev->fw_name_bin = NULL;
+ if (cpp_dev->fw_name_bin != NULL) {
+ kfree(cpp_dev->fw_name_bin);
+ cpp_dev->fw_name_bin = NULL;
+ }
+ if ((ioctl_ptr->len == 0) ||
+ (ioctl_ptr->len > MSM_CPP_MAX_FW_NAME_LEN)) {
+ pr_err("ioctl_ptr->len is 0\n");
+ mutex_unlock(&cpp_dev->mutex);
+ return -EINVAL;
+ }
cpp_dev->fw_name_bin = kzalloc(ioctl_ptr->len+1,
GFP_KERNEL);
if (!cpp_dev->fw_name_bin) {
@@ -1406,13 +1425,9 @@
mutex_unlock(&cpp_dev->mutex);
return -EINVAL;
}
-
if (ioctl_ptr->ioctl_ptr == NULL) {
pr_err("ioctl_ptr->ioctl_ptr=NULL\n");
- return -EINVAL;
- }
- if (ioctl_ptr->len == 0) {
- pr_err("ioctl_ptr->len is 0\n");
+ mutex_unlock(&cpp_dev->mutex);
return -EINVAL;
}
rc = (copy_from_user(cpp_dev->fw_name_bin,
@@ -1426,11 +1441,6 @@
return -EINVAL;
}
*(cpp_dev->fw_name_bin+ioctl_ptr->len) = '\0';
- if (cpp_dev == NULL) {
- pr_err("cpp_dev is null\n");
- return -EINVAL;
- }
-
disable_irq(cpp_dev->irq->start);
cpp_load_fw(cpp_dev, cpp_dev->fw_name_bin);
enable_irq(cpp_dev->irq->start);
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 8de8997..2bc460b 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
@@ -198,7 +198,8 @@
patterns[1] = dvb_dmx_get_pattern(DMX_IDX_H264_PPS);
patterns[2] = dvb_dmx_get_pattern(DMX_IDX_H264_IDR_START);
patterns[3] = dvb_dmx_get_pattern(DMX_IDX_H264_NON_IDR_START);
- *patterns_num = 4;
+ patterns[4] = dvb_dmx_get_pattern(DMX_IDX_H264_SEI);
+ *patterns_num = 5;
break;
case DMX_VIDEO_CODEC_VC1:
diff --git a/drivers/media/platform/msm/dvb/video/mpq_dvb_video.c b/drivers/media/platform/msm/dvb/video/mpq_dvb_video.c
index 0908a6e..9ddb9b7 100644
--- a/drivers/media/platform/msm/dvb/video/mpq_dvb_video.c
+++ b/drivers/media/platform/msm/dvb/video/mpq_dvb_video.c
@@ -134,6 +134,8 @@
case DMX_IDX_H264_SPS:
case DMX_IDX_MPEG_SEQ_HEADER:
case DMX_IDX_VC1_SEQ_HEADER:
+ case DMX_IDX_H264_ACCESS_UNIT_DEL:
+ case DMX_IDX_H264_SEI:
DBG("SPS FOUND\n");
frame_found = false;
break;
diff --git a/drivers/media/platform/msm/vidc/hfi_response_handler.c b/drivers/media/platform/msm/vidc/hfi_response_handler.c
index a63ee61..653ba46 100644
--- a/drivers/media/platform/msm/vidc/hfi_response_handler.c
+++ b/drivers/media/platform/msm/vidc/hfi_response_handler.c
@@ -45,6 +45,7 @@
case HFI_ERR_SESSION_UNSUPPORTED_PROPERTY:
case HFI_ERR_SESSION_UNSUPPORTED_SETTING:
case HFI_ERR_SESSION_INSUFFICIENT_RESOURCES:
+ case HFI_ERR_SESSION_UNSUPPORTED_STREAM:
vidc_err = VIDC_ERR_NOT_SUPPORTED;
break;
case HFI_ERR_SYS_MAX_SESSIONS_REACHED:
@@ -786,6 +787,8 @@
data_done.input_done.offset = pkt->offset;
data_done.input_done.filled_len = pkt->filled_len;
data_done.input_done.packet_buffer = pkt->packet_buffer;
+ data_done.input_done.status =
+ hfi_map_err_status((u32) pkt->error_type);
callback(SESSION_ETB_DONE, &data_done);
}
@@ -1003,7 +1006,6 @@
struct hfi_msg_sys_session_end_done_packet *pkt)
{
struct msm_vidc_cb_cmd_done cmd_done;
- struct hal_session *sess_close;
dprintk(VIDC_DBG, "RECEIVED:SESSION_END_DONE");
@@ -1021,12 +1023,6 @@
cmd_done.status = hfi_map_err_status((u32)pkt->error_type);
cmd_done.data = NULL;
cmd_done.size = 0;
- sess_close = (struct hal_session *)pkt->session_id;
- dprintk(VIDC_INFO, "deleted the session: 0x%x",
- sess_close->session_id);
- list_del(&sess_close->list);
- kfree(sess_close);
- sess_close = NULL;
callback(SESSION_END_DONE, &cmd_done);
}
@@ -1035,7 +1031,6 @@
struct hfi_msg_sys_session_abort_done_packet *pkt)
{
struct msm_vidc_cb_cmd_done cmd_done;
- struct hal_session *sess_close;
dprintk(VIDC_DBG, "RECEIVED:SESSION_ABORT_DONE");
@@ -1053,16 +1048,6 @@
cmd_done.data = NULL;
cmd_done.size = 0;
- sess_close = (struct hal_session *)pkt->session_id;
- if (!sess_close) {
- dprintk(VIDC_ERR, "%s: invalid session pointer\n", __func__);
- return;
- }
- dprintk(VIDC_ERR, "deleted the session: 0x%x",
- sess_close->session_id);
- list_del(&sess_close->list);
- kfree(sess_close);
- sess_close = NULL;
callback(SESSION_ABORT_DONE, &cmd_done);
}
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.c b/drivers/media/platform/msm/vidc/msm_vidc_common.c
index 57b98dc..ad34d45 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_common.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_common.c
@@ -627,6 +627,8 @@
if (inst->core)
hdev = inst->core->device;
if (hdev && inst->session) {
+ dprintk(VIDC_DBG,
+ "cleaning up inst: 0x%p", inst);
rc = call_hfi_op(hdev, session_clean,
(void *) inst->session);
if (rc)
@@ -693,10 +695,24 @@
{
struct msm_vidc_cb_cmd_done *response = data;
struct msm_vidc_inst *inst;
+ struct hfi_device *hdev = NULL;
+
if (response) {
inst = (struct msm_vidc_inst *)response->session_id;
- signal_session_msg_receipt(cmd, inst);
+ if (!inst || !inst->core || !inst->core->device) {
+ dprintk(VIDC_ERR, "%s invalid params\n", __func__);
+ return;
+ }
+ hdev = inst->core->device;
+ mutex_lock(&inst->lock);
+ if (inst->session) {
+ dprintk(VIDC_DBG, "cleaning up inst: 0x%p", inst);
+ call_hfi_op(hdev, session_clean,
+ (void *) inst->session);
+ }
inst->session = NULL;
+ mutex_unlock(&inst->lock);
+ signal_session_msg_receipt(cmd, inst);
show_stats(inst);
} else {
dprintk(VIDC_ERR,
@@ -737,12 +753,19 @@
struct msm_vidc_cb_data_done *response = data;
struct vb2_buffer *vb;
struct msm_vidc_inst *inst;
+ struct vidc_hal_ebd *empty_buf_done;
+
if (!response) {
dprintk(VIDC_ERR, "Invalid response from vidc_hal\n");
return;
}
vb = response->clnt_data;
inst = (struct msm_vidc_inst *)response->session_id;
+ if (!inst) {
+ dprintk(VIDC_ERR, "%s Invalid response from vidc_hal\n",
+ __func__);
+ return;
+ }
if (vb) {
vb->v4l2_planes[0].bytesused = response->input_done.filled_len;
vb->v4l2_planes[0].data_offset = response->input_done.offset;
@@ -753,6 +776,22 @@
if ((u8 *)vb->v4l2_planes[0].m.userptr !=
response->input_done.packet_buffer)
dprintk(VIDC_ERR, "Error: unexpected buffer address\n");
+ vb->v4l2_buf.flags = 0;
+ empty_buf_done = (struct vidc_hal_ebd *)&response->input_done;
+ if (empty_buf_done) {
+ if (empty_buf_done->status == VIDC_ERR_NOT_SUPPORTED) {
+ dprintk(VIDC_INFO,
+ "Failed : Unsupported input stream\n");
+ vb->v4l2_buf.flags |=
+ V4L2_QCOM_BUF_INPUT_UNSUPPORTED;
+ }
+ if (empty_buf_done->status == VIDC_ERR_BITSTREAM_ERR) {
+ dprintk(VIDC_INFO,
+ "Failed : Corrupted input stream\n");
+ vb->v4l2_buf.flags |=
+ V4L2_QCOM_BUF_DATA_CORRUPT;
+ }
+ }
mutex_lock(&inst->bufq[OUTPUT_PORT].lock);
vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
mutex_unlock(&inst->bufq[OUTPUT_PORT].lock);
diff --git a/drivers/media/platform/msm/vidc/vidc_hfi_api.h b/drivers/media/platform/msm/vidc/vidc_hfi_api.h
index 5c22552..010f15d 100644
--- a/drivers/media/platform/msm/vidc/vidc_hfi_api.h
+++ b/drivers/media/platform/msm/vidc/vidc_hfi_api.h
@@ -936,6 +936,7 @@
u32 timestamp_hi;
u32 timestamp_lo;
u32 flags;
+ u32 status;
u32 mark_target;
u32 mark_data;
u32 stats;
diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c
index bd838fc..b750602 100644
--- a/drivers/misc/qseecom.c
+++ b/drivers/misc/qseecom.c
@@ -2647,6 +2647,11 @@
struct qseecom_dev_handle *data = file->private_data;
void __user *argp = (void __user *) arg;
+ if (!data) {
+ pr_err("Invalid/uninitialized device handle\n");
+ return -EINVAL;
+ }
+
if (data->abort) {
pr_err("Aborting qseecom driver\n");
return -ENODEV;
diff --git a/drivers/net/ethernet/msm/msm_rmnet_bam.c b/drivers/net/ethernet/msm/msm_rmnet_bam.c
index 83f486c..3f3d76a 100644
--- a/drivers/net/ethernet/msm/msm_rmnet_bam.c
+++ b/drivers/net/ethernet/msm/msm_rmnet_bam.c
@@ -55,7 +55,7 @@
#define DBG2(x...) DBG(DEBUG_MASK_LVL2, x)
/* Configure device instances */
-#define RMNET_DEVICE_COUNT (8)
+#define RMNET_DEVICE_COUNT 9
/* allow larger frames */
#define RMNET_DATA_LEN 2000
@@ -85,6 +85,7 @@
u32 operation_mode; /* IOCTL specified mode (protocol, QoS header) */
uint8_t device_up;
uint8_t in_reset;
+ struct platform_driver *bam_pdev;
};
#ifdef CONFIG_MSM_RMNET_DEBUG
@@ -401,6 +402,14 @@
__func__, p->ch_id, r);
return -ENODEV;
}
+
+ r = platform_driver_register(p->bam_pdev);
+ if (r) {
+ pr_err("%s: bam pdev registration failed n=%d rc=%d\n",
+ __func__, p->ch_id, r);
+ msm_bam_dmux_close(p->ch_id);
+ return r;
+ }
}
p->device_up = DEVICE_ACTIVE;
@@ -711,6 +720,11 @@
break;
}
+ if (i >= RMNET_DEVICE_COUNT) {
+ pr_err("%s: wrong netdev %s\n", __func__, pdev->name);
+ return -ENODEV;
+ }
+
p = netdev_priv(netdevs[i]);
if (p->in_reset) {
p->in_reset = 0;
@@ -766,7 +780,7 @@
if (i >= RMNET_REV_DEVICE_COUNT) {
pr_err("%s: wrong netdev %s\n", __func__, pdev->name);
- return 0;
+ return -ENODEV;
}
p = netdev_priv(netdevs_rev[i]);
@@ -871,8 +885,13 @@
#endif
for (n = 0; n < RMNET_DEVICE_COUNT; n++) {
+ const char *dev_name = "rmnet%d";
+
+ if (n == BAM_DMUX_USB_RMNET_0)
+ dev_name = "rmnet_usb%d";
+
dev = alloc_netdev(sizeof(struct rmnet_private),
- "rmnet%d", rmnet_setup);
+ dev_name, rmnet_setup);
if (!dev) {
pr_err("%s: no memory for netdev %d\n", __func__, n);
@@ -898,6 +917,7 @@
if (ret) {
pr_err("%s: unable to register netdev"
" %d rc=%d\n", __func__, n, ret);
+ netdevs[n] = NULL;
free_netdev(dev);
return ret;
}
@@ -921,18 +941,16 @@
bam_rmnet_drivers[n].probe = bam_rmnet_probe;
bam_rmnet_drivers[n].remove = bam_rmnet_remove;
tempname = kmalloc(BAM_DMUX_CH_NAME_MAX_LEN, GFP_KERNEL);
- if (tempname == NULL)
- return -ENOMEM;
+ if (tempname == NULL) {
+ netdevs[n] = NULL;
+ ret = -ENOMEM;
+ goto error;
+ }
scnprintf(tempname, BAM_DMUX_CH_NAME_MAX_LEN, "bam_dmux_ch_%d",
n);
bam_rmnet_drivers[n].driver.name = tempname;
bam_rmnet_drivers[n].driver.owner = THIS_MODULE;
- ret = platform_driver_register(&bam_rmnet_drivers[n]);
- if (ret) {
- pr_err("%s: registration failed n=%d rc=%d\n",
- __func__, n, ret);
- return ret;
- }
+ p->bam_pdev = &bam_rmnet_drivers[n];
}
/*Support for new rmnet ports */
for (n = 0; n < RMNET_REV_DEVICE_COUNT; n++) {
@@ -960,6 +978,7 @@
if (ret) {
pr_err("%s: unable to register rev netdev %d rc=%d\n",
__func__, n, ret);
+ netdevs_rev[n] = NULL;
free_netdev(dev);
return ret;
}
@@ -968,20 +987,23 @@
bam_rmnet_rev_drivers[n].probe = bam_rmnet_rev_probe;
bam_rmnet_rev_drivers[n].remove = bam_rmnet_rev_remove;
tempname = kmalloc(BAM_DMUX_CH_NAME_MAX_LEN, GFP_KERNEL);
- if (tempname == NULL)
- return -ENOMEM;
+ if (tempname == NULL) {
+ netdevs_rev[n] = NULL;
+ ret = -ENOMEM;
+ goto error;
+ }
scnprintf(tempname, BAM_DMUX_CH_NAME_MAX_LEN, "bam_dmux_ch_%d",
(n+BAM_DMUX_DATA_REV_RMNET_0));
bam_rmnet_rev_drivers[n].driver.name = tempname;
bam_rmnet_rev_drivers[n].driver.owner = THIS_MODULE;
- ret = platform_driver_register(&bam_rmnet_rev_drivers[n]);
- if (ret) {
- pr_err("%s: new rev driver registration failed n=%d rc=%d\n",
- __func__, n, ret);
- return ret;
- }
+ p->bam_pdev = &bam_rmnet_rev_drivers[n];
}
return 0;
+
+error:
+ unregister_netdev(dev);
+ free_netdev(dev);
+ return ret;
}
module_init(rmnet_init);
diff --git a/drivers/power/qpnp-charger.c b/drivers/power/qpnp-charger.c
index e93d085..950b88a 100644
--- a/drivers/power/qpnp-charger.c
+++ b/drivers/power/qpnp-charger.c
@@ -306,8 +306,8 @@
unsigned int maxinput_dc_ma;
unsigned int hot_batt_p;
unsigned int cold_batt_p;
- unsigned int warm_bat_decidegc;
- unsigned int cool_bat_decidegc;
+ int warm_bat_decidegc;
+ int cool_bat_decidegc;
unsigned int safe_current;
unsigned int revision;
unsigned int type;
diff --git a/include/linux/dvb/dmx.h b/include/linux/dvb/dmx.h
index dd675f3..02ecb0c 100644
--- a/include/linux/dvb/dmx.h
+++ b/include/linux/dvb/dmx.h
@@ -152,6 +152,8 @@
#define DMX_IDX_VC1_FIRST_SEQ_FRAME_END 0x00800000
#define DMX_IDX_VC1_FRAME_START 0x01000000
#define DMX_IDX_VC1_FRAME_END 0x02000000
+#define DMX_IDX_H264_ACCESS_UNIT_DEL 0x04000000
+#define DMX_IDX_H264_SEI 0x08000000
struct dmx_pes_filter_params
{
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index 2424518..101325e 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -704,6 +704,7 @@
#define V4L2_QCOM_BUF_FLAG_DECODEONLY 0x40000
#define V4L2_QCOM_BUF_DATA_CORRUPT 0x80000
#define V4L2_QCOM_BUF_DROP_FRAME 0x100000
+#define V4L2_QCOM_BUF_INPUT_UNSUPPORTED 0x200000
/*
* O V E R L A Y P R E V I E W
diff --git a/include/media/msmb_isp.h b/include/media/msmb_isp.h
index 5ae852a..ec8ec9a 100644
--- a/include/media/msmb_isp.h
+++ b/include/media/msmb_isp.h
@@ -98,6 +98,7 @@
struct msm_vfe_camif_cfg camif_cfg;
enum msm_vfe_inputmux input_mux;
enum ISP_START_PIXEL_PATTERN pixel_pattern;
+ uint32_t input_format;
};
struct msm_vfe_rdi_cfg {
diff --git a/include/media/msmb_pproc.h b/include/media/msmb_pproc.h
index 162729a..de42c38 100644
--- a/include/media/msmb_pproc.h
+++ b/include/media/msmb_pproc.h
@@ -13,6 +13,8 @@
#define MAX_NUM_CPP_STRIPS 8
#define MSM_CPP_MAX_NUM_PLANES 3
+#define MSM_CPP_MAX_FRAME_LENGTH 1024
+#define MSM_CPP_MAX_FW_NAME_LEN 32
enum msm_cpp_frame_type {
MSM_CPP_OFFLINE_FRAME,
diff --git a/sound/soc/codecs/wcd9306.c b/sound/soc/codecs/wcd9306.c
index a6390dd..ff190cd 100644
--- a/sound/soc/codecs/wcd9306.c
+++ b/sound/soc/codecs/wcd9306.c
@@ -38,6 +38,9 @@
#include "wcd9xxx-resmgr.h"
#include "wcd9xxx-common.h"
+#define TAPAN_HPH_PA_SETTLE_COMP_ON 3000
+#define TAPAN_HPH_PA_SETTLE_COMP_OFF 13000
+
static atomic_t kp_tapan_priv;
static int spkr_drv_wrnd_param_set(const char *val,
const struct kernel_param *kp);
@@ -224,8 +227,8 @@
};
static const u32 comp_shift[] = {
- 4, /* Compander 0's clock source is on interpolator 7 */
0,
+ 1,
2,
};
@@ -234,47 +237,44 @@
COMPANDER_1,
COMPANDER_2,
COMPANDER_2,
- COMPANDER_2,
- COMPANDER_2,
- COMPANDER_0,
COMPANDER_MAX,
};
static const struct comp_sample_dependent_params comp_samp_params[] = {
{
/* 8 Khz */
- .peak_det_timeout = 0x02,
+ .peak_det_timeout = 0x06,
.rms_meter_div_fact = 0x09,
.rms_meter_resamp_fact = 0x06,
},
{
/* 16 Khz */
- .peak_det_timeout = 0x03,
+ .peak_det_timeout = 0x07,
.rms_meter_div_fact = 0x0A,
.rms_meter_resamp_fact = 0x0C,
},
{
/* 32 Khz */
- .peak_det_timeout = 0x05,
+ .peak_det_timeout = 0x08,
.rms_meter_div_fact = 0x0B,
.rms_meter_resamp_fact = 0x1E,
},
{
/* 48 Khz */
- .peak_det_timeout = 0x05,
+ .peak_det_timeout = 0x09,
.rms_meter_div_fact = 0x0B,
.rms_meter_resamp_fact = 0x28,
},
{
/* 96 Khz */
- .peak_det_timeout = 0x06,
+ .peak_det_timeout = 0x0A,
.rms_meter_div_fact = 0x0C,
.rms_meter_resamp_fact = 0x50,
},
{
/* 192 Khz */
- .peak_det_timeout = 0x07,
- .rms_meter_div_fact = 0xD,
+ .peak_det_timeout = 0x0B,
+ .rms_meter_div_fact = 0xC,
.rms_meter_resamp_fact = 0xA0,
},
};
@@ -673,6 +673,37 @@
dev_dbg(codec->dev, "%s: Compander %d enable current %d, new %d\n",
__func__, comp, tapan->comp_enabled[comp], value);
tapan->comp_enabled[comp] = value;
+
+ if (comp == COMPANDER_1 &&
+ tapan->comp_enabled[comp] == 1) {
+ /* Wavegen to 5 msec */
+ snd_soc_write(codec, TAPAN_A_RX_HPH_CNP_WG_CTL, 0xDA);
+ snd_soc_write(codec, TAPAN_A_RX_HPH_CNP_WG_TIME, 0x15);
+ snd_soc_write(codec, TAPAN_A_RX_HPH_BIAS_WG_OCP, 0x2A);
+
+ /* Enable Chopper */
+ snd_soc_update_bits(codec,
+ TAPAN_A_RX_HPH_CHOP_CTL, 0x80, 0x80);
+
+ snd_soc_write(codec, TAPAN_A_NCP_DTEST, 0x20);
+ pr_debug("%s: Enabled Chopper and set wavegen to 5 msec\n",
+ __func__);
+ } else if (comp == COMPANDER_1 &&
+ tapan->comp_enabled[comp] == 0) {
+ /* Wavegen to 20 msec */
+ snd_soc_write(codec, TAPAN_A_RX_HPH_CNP_WG_CTL, 0xDB);
+ snd_soc_write(codec, TAPAN_A_RX_HPH_CNP_WG_TIME, 0x58);
+ snd_soc_write(codec, TAPAN_A_RX_HPH_BIAS_WG_OCP, 0x1A);
+
+ /* Disable CHOPPER block */
+ snd_soc_update_bits(codec,
+ TAPAN_A_RX_HPH_CHOP_CTL, 0x80, 0x00);
+
+ snd_soc_write(codec, TAPAN_A_NCP_DTEST, 0x10);
+ pr_debug("%s: Disabled Chopper and set wavegen to 20 msec\n",
+ __func__);
+ }
+
return 0;
}
@@ -708,26 +739,52 @@
static void tapan_discharge_comp(struct snd_soc_codec *codec, int comp)
{
- /* Update RSM to 1, DIVF to 5 */
- snd_soc_write(codec, TAPAN_A_CDC_COMP0_B3_CTL + (comp * 8), 1);
+ /* Level meter DIV Factor to 5*/
snd_soc_update_bits(codec, TAPAN_A_CDC_COMP0_B2_CTL + (comp * 8), 0xF0,
- 1 << 5);
- /* Wait for 1ms */
- usleep_range(1000, 1000);
+ 0x05 << 4);
+ /* RMS meter Sampling to 0x01 */
+ snd_soc_write(codec, TAPAN_A_CDC_COMP0_B3_CTL + (comp * 8), 0x01);
+
+ /* Worst case timeout for compander CnP sleep timeout */
+ usleep_range(3000, 3000);
+}
+
+static enum wcd9xxx_buck_volt tapan_codec_get_buck_mv(
+ struct snd_soc_codec *codec)
+{
+ int buck_volt = WCD9XXX_CDC_BUCK_UNSUPPORTED;
+ struct tapan_priv *tapan = snd_soc_codec_get_drvdata(codec);
+ struct wcd9xxx_pdata *pdata = tapan->resmgr.pdata;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(pdata->regulator); i++) {
+ if (!strncmp(pdata->regulator[i].name,
+ WCD9XXX_SUPPLY_BUCK_NAME,
+ sizeof(WCD9XXX_SUPPLY_BUCK_NAME))) {
+ if ((pdata->regulator[i].min_uV ==
+ WCD9XXX_CDC_BUCK_MV_1P8) ||
+ (pdata->regulator[i].min_uV ==
+ WCD9XXX_CDC_BUCK_MV_2P15))
+ buck_volt = pdata->regulator[i].min_uV;
+ break;
+ }
+ }
+ pr_debug("%s: S4 voltage requested is %d\n", __func__, buck_volt);
+ return buck_volt;
}
static int tapan_config_compander(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
- int mask, emask;
- bool timedout;
- unsigned long timeout;
+ int mask, enable_mask;
+ u8 rdac5_mux;
struct snd_soc_codec *codec = w->codec;
struct tapan_priv *tapan = snd_soc_codec_get_drvdata(codec);
const int comp = w->shift;
const u32 rate = tapan->comp_fs[comp];
const struct comp_sample_dependent_params *comp_params =
&comp_samp_params[rate];
+ enum wcd9xxx_buck_volt buck_mv;
dev_dbg(codec->dev, "%s: %s event %d compander %d, enabled %d",
__func__, w->name, event, comp, tapan->comp_enabled[comp]);
@@ -737,72 +794,105 @@
/* Compander 0 has single channel */
mask = (comp == COMPANDER_0 ? 0x01 : 0x03);
- emask = (comp == COMPANDER_0 ? 0x02 : 0x03);
+ buck_mv = tapan_codec_get_buck_mv(codec);
+
+ rdac5_mux = snd_soc_read(codec, TAPAN_A_CDC_CONN_MISC);
+ rdac5_mux = (rdac5_mux & 0x04) >> 2;
+
+ if (comp == COMPANDER_0) { /* SPK compander */
+ enable_mask = 0x02;
+ } else if (comp == COMPANDER_1) { /* HPH compander */
+ enable_mask = 0x03;
+ } else if (comp == COMPANDER_2) { /* LO compander */
+
+ if (rdac5_mux == 0) { /* DEM4 */
+
+ /* for LO Stereo SE, enable Compander 2 left
+ * channel on RX3 interpolator Path and Compander 2
+ * rigt channel on RX4 interpolator Path.
+ */
+ enable_mask = 0x03;
+ } else if (rdac5_mux == 1) { /* DEM3_INV */
+
+ /* for LO mono differential only enable Compander 2
+ * left channel on RX3 interpolator Path.
+ */
+ enable_mask = 0x02;
+ } else {
+ dev_err(codec->dev, "%s: invalid rdac5_mux val %d",
+ __func__, rdac5_mux);
+ return -EINVAL;
+ }
+ } else {
+ dev_err(codec->dev, "%s: invalid compander %d", __func__, comp);
+ return -EINVAL;
+ }
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
+ /* Set compander Sample rate */
+ snd_soc_update_bits(codec,
+ TAPAN_A_CDC_COMP0_FS_CFG + (comp * 8),
+ 0x07, rate);
+ /* Set the static gain offset for HPH Path */
+ if (comp == COMPANDER_1) {
+ if (buck_mv == WCD9XXX_CDC_BUCK_MV_2P15)
+ snd_soc_update_bits(codec,
+ TAPAN_A_CDC_COMP0_B4_CTL + (comp * 8),
+ 0x80, 0x00);
+ else
+ snd_soc_update_bits(codec,
+ TAPAN_A_CDC_COMP0_B4_CTL + (comp * 8),
+ 0x80, 0x80);
+ }
+ /* Enable RX interpolation path compander clocks */
+ snd_soc_update_bits(codec, TAPAN_A_CDC_CLK_RX_B2_CTL,
+ 0x01 << comp_shift[comp],
+ 0x01 << comp_shift[comp]);
+
+ /* Toggle compander reset bits */
+ snd_soc_update_bits(codec, TAPAN_A_CDC_CLK_OTHR_RESET_B2_CTL,
+ 0x01 << comp_shift[comp],
+ 0x01 << comp_shift[comp]);
+ snd_soc_update_bits(codec, TAPAN_A_CDC_CLK_OTHR_RESET_B2_CTL,
+ 0x01 << comp_shift[comp], 0);
+
/* Set gain source to compander */
tapan_config_gain_compander(codec, comp, true);
- /* Enable RX interpolation path clocks */
- snd_soc_update_bits(codec, TAPAN_A_CDC_CLK_RX_B2_CTL,
- mask << comp_shift[comp],
- mask << comp_shift[comp]);
+
+ /* Compander enable */
+ snd_soc_update_bits(codec, TAPAN_A_CDC_COMP0_B1_CTL +
+ (comp * 8), enable_mask, enable_mask);
tapan_discharge_comp(codec, comp);
- /* Clear compander halt */
- snd_soc_update_bits(codec, TAPAN_A_CDC_COMP0_B1_CTL +
- (comp * 8),
- 1 << 2, 0);
+ /* Set sample rate dependent paramater */
+ snd_soc_write(codec, TAPAN_A_CDC_COMP0_B3_CTL + (comp * 8),
+ comp_params->rms_meter_resamp_fact);
+ snd_soc_update_bits(codec,
+ TAPAN_A_CDC_COMP0_B2_CTL + (comp * 8),
+ 0xF0, comp_params->rms_meter_div_fact << 4);
+ snd_soc_update_bits(codec,
+ TAPAN_A_CDC_COMP0_B2_CTL + (comp * 8),
+ 0x0F, comp_params->peak_det_timeout);
+ break;
+ case SND_SOC_DAPM_PRE_PMD:
+ /* Disable compander */
+ snd_soc_update_bits(codec,
+ TAPAN_A_CDC_COMP0_B1_CTL + (comp * 8),
+ enable_mask, 0x00);
+
/* Toggle compander reset bits */
snd_soc_update_bits(codec, TAPAN_A_CDC_CLK_OTHR_RESET_B2_CTL,
mask << comp_shift[comp],
mask << comp_shift[comp]);
snd_soc_update_bits(codec, TAPAN_A_CDC_CLK_OTHR_RESET_B2_CTL,
mask << comp_shift[comp], 0);
- break;
- case SND_SOC_DAPM_POST_PMU:
- /* Set sample rate dependent paramater */
- snd_soc_update_bits(codec,
- TAPAN_A_CDC_COMP0_FS_CFG + (comp * 8),
- 0x07, rate);
- snd_soc_write(codec, TAPAN_A_CDC_COMP0_B3_CTL + (comp * 8),
- comp_params->rms_meter_resamp_fact);
- snd_soc_update_bits(codec,
- TAPAN_A_CDC_COMP0_B2_CTL + (comp * 8),
- 0x0F, comp_params->peak_det_timeout);
- snd_soc_update_bits(codec,
- TAPAN_A_CDC_COMP0_B2_CTL + (comp * 8),
- 0xF0, comp_params->rms_meter_div_fact << 4);
- /* Compander enable */
- snd_soc_update_bits(codec, TAPAN_A_CDC_COMP0_B1_CTL +
- (comp * 8), emask, emask);
- break;
- case SND_SOC_DAPM_PRE_PMD:
- /* Halt compander */
- snd_soc_update_bits(codec,
- TAPAN_A_CDC_COMP0_B1_CTL + (comp * 8),
- 1 << 2, 1 << 2);
- /* Wait up to a second for shutdown complete */
- timeout = jiffies + HZ;
- do {
- if ((snd_soc_read(codec,
- TAPAN_A_CDC_COMP0_SHUT_DOWN_STATUS +
- (comp * 8)) & mask) == mask)
- break;
- } while (!(timedout = time_after(jiffies, timeout)));
- dev_dbg(codec->dev, "%s: Compander %d shutdown %s in %dms\n",
- __func__, comp, timedout ? "timedout" : "completed",
- jiffies_to_msecs(timeout - HZ - jiffies));
- break;
- case SND_SOC_DAPM_POST_PMD:
- /* Disable compander */
- snd_soc_update_bits(codec,
- TAPAN_A_CDC_COMP0_B1_CTL + (comp * 8),
- emask, 0x00);
+
/* Turn off the clock for compander in pair */
snd_soc_update_bits(codec, TAPAN_A_CDC_CLK_RX_B2_CTL,
mask << comp_shift[comp], 0);
+
/* Set gain source to register */
tapan_config_gain_compander(codec, comp, false);
break;
@@ -2267,6 +2357,7 @@
struct tapan_priv *tapan = snd_soc_codec_get_drvdata(codec);
enum wcd9xxx_notify_event e_pre_on, e_post_off;
u8 req_clsh_state;
+ u32 pa_settle_time = TAPAN_HPH_PA_SETTLE_COMP_OFF;
dev_dbg(codec->dev, "%s: %s event = %d\n", __func__, w->name, event);
if (w->shift == 5) {
@@ -2282,23 +2373,32 @@
return -EINVAL;
}
+ if (tapan->comp_enabled[COMPANDER_1])
+ pa_settle_time = TAPAN_HPH_PA_SETTLE_COMP_ON;
+
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
/* Let MBHC module know PA is turning on */
wcd9xxx_resmgr_notifier_call(&tapan->resmgr, e_pre_on);
break;
-
case SND_SOC_DAPM_POST_PMU:
+ dev_dbg(codec->dev, "%s: sleep %d ms after %s PA enable.\n",
+ __func__, pa_settle_time / 1000, w->name);
+ /* Time needed for PA to settle */
+ usleep_range(pa_settle_time, pa_settle_time + 1000);
+
wcd9xxx_clsh_fsm(codec, &tapan->clsh_d,
req_clsh_state,
WCD9XXX_CLSH_REQ_ENABLE,
WCD9XXX_CLSH_EVENT_POST_PA);
-
- usleep_range(5000, 5010);
break;
-
case SND_SOC_DAPM_POST_PMD:
+ dev_dbg(codec->dev, "%s: sleep %d ms after %s PA disable.\n",
+ __func__, pa_settle_time / 1000, w->name);
+ /* Time needed for PA to settle */
+ usleep_range(pa_settle_time, pa_settle_time + 1000);
+
/* Let MBHC module know PA turned off */
wcd9xxx_resmgr_notifier_call(&tapan->resmgr, e_post_off);
@@ -2306,10 +2406,6 @@
req_clsh_state,
WCD9XXX_CLSH_REQ_DISABLE,
WCD9XXX_CLSH_EVENT_POST_PA);
-
- dev_dbg(codec->dev, "%s: sleep 10 ms after %s PA disable.\n",
- __func__, w->name);
- usleep_range(5000, 5010);
break;
}
return 0;
@@ -2549,6 +2645,7 @@
{"RX1 MIX1", NULL, "COMP1_CLK"},
{"RX2 MIX1", NULL, "COMP1_CLK"},
{"RX3 MIX1", NULL, "COMP2_CLK"},
+ {"RX4 MIX1", NULL, "COMP0_CLK"},
{"RX1 MIX1", NULL, "RX1 MIX1 INP1"},
{"RX1 MIX1", NULL, "RX1 MIX1 INP2"},
@@ -3019,6 +3116,7 @@
u16 rx_mix_1_reg_1, rx_mix_1_reg_2;
u16 rx_fs_reg;
u8 rx_mix_1_reg_1_val, rx_mix_1_reg_2_val;
+ u8 rdac5_mux;
struct snd_soc_codec *codec = dai->codec;
struct wcd9xxx_ch *ch;
struct tapan_priv *tapan = snd_soc_codec_get_drvdata(codec);
@@ -3036,6 +3134,9 @@
rx_mix_1_reg_1 = TAPAN_A_CDC_CONN_RX1_B1_CTL;
+ rdac5_mux = snd_soc_read(codec, TAPAN_A_CDC_CONN_MISC);
+ rdac5_mux = (rdac5_mux & 0x04) >> 2;
+
for (j = 0; j < NUM_INTERPOLATORS; j++) {
rx_mix_1_reg_2 = rx_mix_1_reg_1 + 1;
@@ -3060,9 +3161,14 @@
snd_soc_update_bits(codec, rx_fs_reg,
0xE0, rx_fs_rate_reg_val);
- if (comp_rx_path[j] < COMPANDER_MAX)
- tapan->comp_fs[comp_rx_path[j]]
- = compander_fs;
+ if (comp_rx_path[j] < COMPANDER_MAX) {
+ if ((j == 3) && (rdac5_mux == 1))
+ tapan->comp_fs[COMPANDER_0] =
+ compander_fs;
+ else
+ tapan->comp_fs[comp_rx_path[j]]
+ = compander_fs;
+ }
}
if (j <= 1)
rx_mix_1_reg_1 += 3;
@@ -3893,13 +3999,13 @@
SND_SOC_DAPM_SUPPLY("COMP0_CLK", SND_SOC_NOPM, 0, 0,
tapan_config_compander, SND_SOC_DAPM_PRE_PMU |
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_POST_PMD),
+ SND_SOC_DAPM_PRE_PMD),
SND_SOC_DAPM_SUPPLY("COMP1_CLK", SND_SOC_NOPM, 1, 0,
tapan_config_compander, SND_SOC_DAPM_PRE_PMU |
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_POST_PMD),
+ SND_SOC_DAPM_PRE_PMD),
SND_SOC_DAPM_SUPPLY("COMP2_CLK", SND_SOC_NOPM, 2, 0,
tapan_config_compander, SND_SOC_DAPM_PRE_PMU |
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_POST_PMD),
+ SND_SOC_DAPM_PRE_PMD),
SND_SOC_DAPM_INPUT("AMIC1"),
SND_SOC_DAPM_MICBIAS_E("MIC BIAS1 External", TAPAN_A_MICB_1_CTL, 7, 0,
@@ -4239,12 +4345,11 @@
TAPAN_REG_VAL(TAPAN_A_RX_HPH_CHOP_CTL, 0xF4),
TAPAN_REG_VAL(TAPAN_A_BIAS_CURR_CTL_2, 0x08),
TAPAN_REG_VAL(WCD9XXX_A_BUCK_CTRL_CCL_1, 0x5B),
- TAPAN_REG_VAL(WCD9XXX_A_BUCK_CTRL_CCL_3, 0x60),
+ TAPAN_REG_VAL(WCD9XXX_A_BUCK_CTRL_CCL_3, 0x6F),
/* TODO: Check below reg writes conflict with above */
/* PROGRAM_THE_0P85V_VBG_REFERENCE = V_0P858V */
TAPAN_REG_VAL(TAPAN_A_BIAS_CURR_CTL_2, 0x04),
- TAPAN_REG_VAL(WCD9XXX_A_BUCK_CTRL_CCL_4, 0x54),
TAPAN_REG_VAL(TAPAN_A_RX_HPH_CHOP_CTL, 0x74),
TAPAN_REG_VAL(TAPAN_A_RX_BUCK_BIAS1, 0x62),
@@ -4414,6 +4519,15 @@
{TAPAN_A_CDC_COMP0_B5_CTL, 0x7F, 0x7F},
{TAPAN_A_CDC_COMP1_B5_CTL, 0x7F, 0x7F},
{TAPAN_A_CDC_COMP2_B5_CTL, 0x7F, 0x7F},
+
+ /*
+ * Setup wavegen timer to 20msec and disable chopper
+ * as default. This corresponds to Compander OFF
+ */
+ {TAPAN_A_RX_HPH_CNP_WG_CTL, 0xFF, 0xDB},
+ {TAPAN_A_RX_HPH_CNP_WG_TIME, 0xFF, 0x58},
+ {TAPAN_A_RX_HPH_BIAS_WG_OCP, 0xFF, 0x1A},
+ {TAPAN_A_RX_HPH_CHOP_CTL, 0xFF, 0x24},
};
static void tapan_codec_init_reg(struct snd_soc_codec *codec)
@@ -4596,30 +4710,6 @@
return 0;
}
-static enum wcd9xxx_buck_volt tapan_codec_get_buck_mv(
- struct snd_soc_codec *codec)
-{
- int buck_volt = WCD9XXX_CDC_BUCK_UNSUPPORTED;
- struct tapan_priv *tapan = snd_soc_codec_get_drvdata(codec);
- struct wcd9xxx_pdata *pdata = tapan->resmgr.pdata;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(pdata->regulator); i++) {
- if (!strncmp(pdata->regulator[i].name,
- WCD9XXX_SUPPLY_BUCK_NAME,
- sizeof(WCD9XXX_SUPPLY_BUCK_NAME))) {
- if ((pdata->regulator[i].min_uV ==
- WCD9XXX_CDC_BUCK_MV_1P8) ||
- (pdata->regulator[i].min_uV ==
- WCD9XXX_CDC_BUCK_MV_2P15))
- buck_volt = pdata->regulator[i].min_uV;
- break;
- }
- }
- pr_debug("%s: S4 voltage requested is %d\n", __func__, buck_volt);
- return buck_volt;
-}
-
static int tapan_codec_probe(struct snd_soc_codec *codec)
{
struct wcd9xxx *control;
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
index edb24fc..de60430 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
@@ -63,6 +63,7 @@
static int lsm_mux_slim_port;
static int slim0_rx_aanc_fb_port;
static int msm_route_ec_ref_rx = 3; /* NONE */
+static uint32_t voc_session_id = ALL_SESSION_VSID;
enum {
MADNONE,
@@ -572,7 +573,7 @@
}
if ((msm_bedais[reg].port_id == VOICE_RECORD_RX)
|| (msm_bedais[reg].port_id == VOICE_RECORD_TX))
- voc_start_record(msm_bedais[reg].port_id, set);
+ voc_start_record(msm_bedais[reg].port_id, set, voc_session_id);
mutex_unlock(&routing_lock);
}
@@ -2632,6 +2633,30 @@
msm_routing_put_rms_value_control),
};
+static int msm_voc_session_id_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ voc_session_id = ucontrol->value.integer.value[0];
+
+ pr_debug("%s: voc_session_id=%u\n", __func__, voc_session_id);
+
+ return 0;
+}
+
+static int msm_voc_session_id_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ ucontrol->value.integer.value[0] = voc_session_id;
+
+ return 0;
+}
+
+static struct snd_kcontrol_new msm_voc_session_controls[] = {
+ SOC_SINGLE_MULTI_EXT("Voc VSID", SND_SOC_NOPM, 0,
+ 0xFFFFFFFF, 0, 1, msm_voc_session_id_get,
+ msm_voc_session_id_put),
+};
+
static const struct snd_kcontrol_new eq_enable_mixer_controls[] = {
SOC_SINGLE_EXT("MultiMedia1 EQ Enable", SND_SOC_NOPM,
MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_eq_enable_mixer,
@@ -3910,6 +3935,10 @@
snd_soc_add_platform_controls(platform,
get_rms_controls,
ARRAY_SIZE(get_rms_controls));
+
+ snd_soc_add_platform_controls(platform, msm_voc_session_controls,
+ ARRAY_SIZE(msm_voc_session_controls));
+
return 0;
}
diff --git a/sound/soc/msm/qdsp6v2/q6voice.c b/sound/soc/msm/qdsp6v2/q6voice.c
index 7243f19..056e2dc 100644
--- a/sound/soc/msm/qdsp6v2/q6voice.c
+++ b/sound/soc/msm/qdsp6v2/q6voice.c
@@ -130,6 +130,28 @@
return ret;
}
+static bool voice_is_valid_session_id(uint32_t session_id)
+{
+ bool ret = false;
+
+ switch (session_id) {
+ case VOICE_SESSION_VSID:
+ case VOICE2_SESSION_VSID:
+ case VOLTE_SESSION_VSID:
+ case VOIP_SESSION_VSID:
+ case QCHAT_SESSION_VSID:
+ case ALL_SESSION_VSID:
+ ret = true;
+ break;
+ default:
+ pr_err("%s: Invalid session_id : %x\n", __func__, session_id);
+
+ break;
+ }
+
+ return ret;
+}
+
static u16 voice_get_mvm_handle(struct voice_data *v)
{
if (v == NULL) {
@@ -2989,6 +3011,22 @@
v->music_info.force = 1;
voice_cvs_stop_playback(v);
voice_cvs_stop_record(v);
+ /* If voice call is active during VoLTE, SRVCC happens.
+ Start recording on voice session if recording started during VoLTE.
+ */
+ if (is_volte_session(v->session_id) &&
+ ((common.voice[VOC_PATH_PASSIVE].voc_state == VOC_RUN) ||
+ (common.voice[VOC_PATH_PASSIVE].voc_state == VOC_CHANGE))) {
+ if (v->rec_info.rec_enable) {
+ voice_cvs_start_record(
+ &common.voice[VOC_PATH_PASSIVE],
+ v->rec_info.rec_mode);
+ common.srvcc_rec_flag = true;
+
+ pr_debug("%s: switch recording, srvcc_rec_flag %d\n",
+ __func__, common.srvcc_rec_flag);
+ }
+ }
/* send stop voice cmd */
voice_send_stop_voice_cmd(v);
@@ -3561,17 +3599,35 @@
return ret;
}
-int voc_start_record(uint32_t port_id, uint32_t set)
+int voc_start_record(uint32_t port_id, uint32_t set, uint32_t session_id)
{
int ret = 0;
int rec_mode = 0;
u16 cvs_handle;
- int i, rec_set = 0;
+ int rec_set = 0;
+ struct voice_session_itr itr;
+ struct voice_data *v = NULL;
- for (i = 0; i < MAX_VOC_SESSIONS; i++) {
- struct voice_data *v = &common.voice[i];
- pr_debug("%s: i:%d port_id: %d, set: %d\n",
- __func__, i, port_id, set);
+ /* check if session_id is valid */
+ if (!voice_is_valid_session_id(session_id)) {
+ pr_err("%s: Invalid session id:%u\n", __func__,
+ session_id);
+
+ return -EINVAL;
+ }
+
+ voice_itr_init(&itr, session_id);
+ pr_debug("%s: session_id:%u\n", __func__, session_id);
+
+ while (voice_itr_get_next_session(&itr, &v)) {
+ if (v == NULL) {
+ pr_err("%s: v is NULL, sessionid:%u\n", __func__,
+ session_id);
+
+ break;
+ }
+ pr_debug("%s: port_id: %d, set: %d, v: %p\n",
+ __func__, port_id, set, v);
mutex_lock(&v->lock);
rec_mode = v->rec_info.rec_mode;
@@ -3579,13 +3635,11 @@
if (set) {
if ((v->rec_route_state.ul_flag != 0) &&
(v->rec_route_state.dl_flag != 0)) {
- pr_debug("%s: i=%d, rec mode already set.\n",
- __func__, i);
+ pr_debug("%s: rec mode already set.\n",
+ __func__);
+
mutex_unlock(&v->lock);
- if (i < MAX_VOC_SESSIONS)
- continue;
- else
- return 0;
+ continue;
}
if (port_id == VOICE_RECORD_TX) {
@@ -3615,13 +3669,10 @@
} else {
if ((v->rec_route_state.ul_flag == 0) &&
(v->rec_route_state.dl_flag == 0)) {
- pr_debug("%s: i=%d, rec already stops.\n",
- __func__, i);
+ pr_debug("%s: rec already stops.\n",
+ __func__);
mutex_unlock(&v->lock);
- if (i < MAX_VOC_SESSIONS)
- continue;
- else
- return 0;
+ continue;
}
if (port_id == VOICE_RECORD_TX) {
@@ -3650,8 +3701,8 @@
}
}
}
- pr_debug("%s: i=%d, mode =%d, set =%d\n", __func__,
- i, rec_mode, rec_set);
+ pr_debug("%s: mode =%d, set =%d\n", __func__,
+ rec_mode, rec_set);
cvs_handle = voice_get_cvs_handle(v);
if (cvs_handle != 0) {
@@ -3661,6 +3712,18 @@
ret = voice_cvs_stop_record(v);
}
+ /* During SRVCC, recording will switch from VoLTE session to
+ voice session.
+ Then stop recording, need to stop recording on voice session.
+ */
+ if ((!rec_set) && common.srvcc_rec_flag) {
+ pr_debug("%s, srvcc_rec_flag:%d\n", __func__,
+ common.srvcc_rec_flag);
+
+ voice_cvs_stop_record(&common.voice[VOC_PATH_PASSIVE]);
+ common.srvcc_rec_flag = false;
+ }
+
/* Cache the value */
v->rec_info.rec_enable = rec_set;
v->rec_info.rec_mode = rec_mode;
@@ -4590,6 +4653,9 @@
c->voice[i].shmem_info.mem_handle = 0;
}
}
+ /* clean up srvcc rec flag */
+ c->srvcc_rec_flag = false;
+
return 0;
}
diff --git a/sound/soc/msm/qdsp6v2/q6voice.h b/sound/soc/msm/qdsp6v2/q6voice.h
index 1e9c813..20f2857 100644
--- a/sound/soc/msm/qdsp6v2/q6voice.h
+++ b/sound/soc/msm/qdsp6v2/q6voice.h
@@ -1338,6 +1338,8 @@
struct dtmf_driver_info dtmf_info;
struct voice_data voice[MAX_VOC_SESSIONS];
+
+ bool srvcc_rec_flag;
};
struct voice_session_itr {
@@ -1438,7 +1440,7 @@
uint32_t voc_get_session_id(char *name);
int voc_start_playback(uint32_t set, uint16_t port_id);
-int voc_start_record(uint32_t port_id, uint32_t set);
+int voc_start_record(uint32_t port_id, uint32_t set, uint32_t session_id);
int voice_get_idx_for_session(u32 session_id);
#endif