Merge "ASoC: msm: Add MultiMedia6 dai link"
diff --git a/Documentation/devicetree/bindings/arm/msm/core_sleep_status.txt b/Documentation/devicetree/bindings/arm/msm/core_sleep_status.txt
new file mode 100644
index 0000000..6ac80f1
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/msm/core_sleep_status.txt
@@ -0,0 +1,29 @@
+* MSM Sleep status
+
+MSM Sleep status device is used to check the power collapsed status of a
+offlined core. The core that initiates the hotplug would wait on the
+sleep status device before CPU_DEAD notifications are sent out. Some hardware
+devices require that the offlined core is power collapsed before turning off
+the resources that are used by the offlined core.
+
+This device is dependent on the pm-8x60 device, which configures the low power
+mode of respective cores. The sleep status is only valid when the core enters
+a low power mode. The device is a child node to pm-8x60 node which is documented
+in Documentation/devicetree/bindings/arm/msm/pm-8x60.txt
+
+The required properties of sleep status device are:
+
+- compatible: qcom,cpu-sleep-status
+- reg: physical address of the sleep status register for Core 0
+- qcom,cpu-alias-addr - On MSM chipset, the each cores registers are at a
+ fixed offset each other.
+- qcom,cpu-sleep-status-mask - The bit mask within the status register that
+ indicates the Core's sleep state.
+
+Example:
+ qcom,cpu-sleep-status@f9088008 {
+ compatible = "qcom,cpu-sleep-status";
+ reg = <0xf9088008 0x4>;
+ qcom,cpu-alias-addr = <0x10000>;
+ qcom,sleep-status-mask= <0x80000>;
+ };
diff --git a/Documentation/devicetree/bindings/input/touchscreen/synaptics_i2c_rmi4.txt b/Documentation/devicetree/bindings/input/touchscreen/synaptics_i2c_rmi4.txt
index b31ec30..d24139b 100644
--- a/Documentation/devicetree/bindings/input/touchscreen/synaptics_i2c_rmi4.txt
+++ b/Documentation/devicetree/bindings/input/touchscreen/synaptics_i2c_rmi4.txt
@@ -20,6 +20,7 @@
- synaptics,y-flip : modify orientation of the y axis
- synaptics,panel-x : panel x dimension
- synaptics,panel-y : panel y dimension
+ - synaptics,fw-image-name : name of firmware .img file in /etc/firmware
Example:
i2c@f9927000 { /* BLSP1 QUP5 */
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 221b898..d380dbb 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1785,7 +1785,7 @@
config OABI_COMPAT
bool "Allow old ABI binaries to run with this kernel (EXPERIMENTAL)"
depends on AEABI && EXPERIMENTAL && !THUMB2_KERNEL
- default y
+ default y if !SMP
help
This option preserves the old syscall interface along with the
new (ARM EABI) one. It also provides a compatibility layer to
diff --git a/arch/arm/configs/msm8960-perf_defconfig b/arch/arm/configs/msm8960-perf_defconfig
index 6f8a664..f95f074 100644
--- a/arch/arm/configs/msm8960-perf_defconfig
+++ b/arch/arm/configs/msm8960-perf_defconfig
@@ -302,6 +302,7 @@
CONFIG_TOUCHSCREEN_ATMEL_MXT=y
CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4=y
CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_RMI4_DEV=y
+CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE=y
CONFIG_TOUCHSCREEN_CYTTSP_I2C_QC=y
CONFIG_INPUT_MISC=y
CONFIG_INPUT_PMIC8XXX_PWRKEY=y
diff --git a/arch/arm/configs/msm8960_defconfig b/arch/arm/configs/msm8960_defconfig
index 38b438b..9fbe022 100644
--- a/arch/arm/configs/msm8960_defconfig
+++ b/arch/arm/configs/msm8960_defconfig
@@ -307,6 +307,7 @@
CONFIG_TOUCHSCREEN_CYTTSP_I2C_QC=y
CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4=y
CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_RMI4_DEV=y
+CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE=y
CONFIG_INPUT_MISC=y
CONFIG_INPUT_PMIC8XXX_PWRKEY=y
CONFIG_INPUT_UINPUT=y
diff --git a/arch/arm/mach-msm/acpuclock-8960ab.c b/arch/arm/mach-msm/acpuclock-8960ab.c
index c77a4c1..2e4ab5e 100644
--- a/arch/arm/mach-msm/acpuclock-8960ab.c
+++ b/arch/arm/mach-msm/acpuclock-8960ab.c
@@ -109,12 +109,12 @@
static struct acpu_level freq_tbl_PVS0[] __initdata = {
{ 1, { 384000, PLL_8, 0, 0x00 }, L2(0), 950000, AVS(0x70001F) },
- { 1, { 486000, HFPLL, 2, 0x24 }, L2(3), 950000, AVS(0x0) },
- { 1, { 594000, HFPLL, 1, 0x16 }, L2(3), 975000, AVS(0x0) },
- { 1, { 702000, HFPLL, 1, 0x1A }, L2(3), 1000000, AVS(0x0) },
- { 1, { 810000, HFPLL, 1, 0x1E }, L2(3), 1025000, AVS(0x0) },
- { 1, { 918000, HFPLL, 1, 0x22 }, L2(3), 1050000, AVS(0x0) },
- { 1, { 1026000, HFPLL, 1, 0x26 }, L2(3), 1075000, AVS(0x0) },
+ { 1, { 486000, HFPLL, 2, 0x24 }, L2(4), 950000, AVS(0x0) },
+ { 1, { 594000, HFPLL, 1, 0x16 }, L2(4), 975000, AVS(0x0) },
+ { 1, { 702000, HFPLL, 1, 0x1A }, L2(4), 1000000, AVS(0x0) },
+ { 1, { 810000, HFPLL, 1, 0x1E }, L2(4), 1025000, AVS(0x0) },
+ { 1, { 918000, HFPLL, 1, 0x22 }, L2(4), 1050000, AVS(0x0) },
+ { 1, { 1026000, HFPLL, 1, 0x26 }, L2(4), 1075000, AVS(0x0) },
{ 1, { 1134000, HFPLL, 1, 0x2A }, L2(9), 1100000, AVS(0x70000D) },
{ 1, { 1242000, HFPLL, 1, 0x2E }, L2(9), 1125000, AVS(0x0) },
{ 1, { 1350000, HFPLL, 1, 0x32 }, L2(9), 1150000, AVS(0x0) },
@@ -127,12 +127,12 @@
static struct acpu_level freq_tbl_PVS1[] __initdata = {
{ 1, { 384000, PLL_8, 0, 0x00 }, L2(0), 925000, AVS(0x70001F) },
- { 1, { 486000, HFPLL, 2, 0x24 }, L2(3), 925000, AVS(0x0) },
- { 1, { 594000, HFPLL, 1, 0x16 }, L2(3), 950000, AVS(0x0) },
- { 1, { 702000, HFPLL, 1, 0x1A }, L2(3), 975000, AVS(0x0) },
- { 1, { 810000, HFPLL, 1, 0x1E }, L2(3), 1000000, AVS(0x0) },
- { 1, { 918000, HFPLL, 1, 0x22 }, L2(3), 1025000, AVS(0x0) },
- { 1, { 1026000, HFPLL, 1, 0x26 }, L2(3), 1050000, AVS(0x0) },
+ { 1, { 486000, HFPLL, 2, 0x24 }, L2(4), 925000, AVS(0x0) },
+ { 1, { 594000, HFPLL, 1, 0x16 }, L2(4), 950000, AVS(0x0) },
+ { 1, { 702000, HFPLL, 1, 0x1A }, L2(4), 975000, AVS(0x0) },
+ { 1, { 810000, HFPLL, 1, 0x1E }, L2(4), 1000000, AVS(0x0) },
+ { 1, { 918000, HFPLL, 1, 0x22 }, L2(4), 1025000, AVS(0x0) },
+ { 1, { 1026000, HFPLL, 1, 0x26 }, L2(4), 1050000, AVS(0x0) },
{ 1, { 1134000, HFPLL, 1, 0x2A }, L2(9), 1075000, AVS(0x70000D) },
{ 1, { 1242000, HFPLL, 1, 0x2E }, L2(9), 1100000, AVS(0x0) },
{ 1, { 1350000, HFPLL, 1, 0x32 }, L2(9), 1125000, AVS(0x0) },
@@ -145,12 +145,12 @@
static struct acpu_level freq_tbl_PVS2[] __initdata = {
{ 1, { 384000, PLL_8, 0, 0x00 }, L2(0), 900000, AVS(0x70001F) },
- { 1, { 486000, HFPLL, 2, 0x24 }, L2(3), 900000, AVS(0x0) },
- { 1, { 594000, HFPLL, 1, 0x16 }, L2(3), 925000, AVS(0x0) },
- { 1, { 702000, HFPLL, 1, 0x1A }, L2(3), 950000, AVS(0x0) },
- { 1, { 810000, HFPLL, 1, 0x1E }, L2(3), 975000, AVS(0x0) },
- { 1, { 918000, HFPLL, 1, 0x22 }, L2(3), 1000000, AVS(0x0) },
- { 1, { 1026000, HFPLL, 1, 0x26 }, L2(3), 1025000, AVS(0x0) },
+ { 1, { 486000, HFPLL, 2, 0x24 }, L2(4), 900000, AVS(0x0) },
+ { 1, { 594000, HFPLL, 1, 0x16 }, L2(4), 925000, AVS(0x0) },
+ { 1, { 702000, HFPLL, 1, 0x1A }, L2(4), 950000, AVS(0x0) },
+ { 1, { 810000, HFPLL, 1, 0x1E }, L2(4), 975000, AVS(0x0) },
+ { 1, { 918000, HFPLL, 1, 0x22 }, L2(4), 1000000, AVS(0x0) },
+ { 1, { 1026000, HFPLL, 1, 0x26 }, L2(4), 1025000, AVS(0x0) },
{ 1, { 1134000, HFPLL, 1, 0x2A }, L2(9), 1050000, AVS(0x70000D) },
{ 1, { 1242000, HFPLL, 1, 0x2E }, L2(9), 1075000, AVS(0x0) },
{ 1, { 1350000, HFPLL, 1, 0x32 }, L2(9), 1100000, AVS(0x0) },
@@ -163,12 +163,12 @@
static struct acpu_level freq_tbl_PVS3[] __initdata = {
{ 1, { 384000, PLL_8, 0, 0x00 }, L2(0), 900000, AVS(0x70001F) },
- { 1, { 486000, HFPLL, 2, 0x24 }, L2(3), 900000, AVS(0x0) },
- { 1, { 594000, HFPLL, 1, 0x16 }, L2(3), 900000, AVS(0x0) },
- { 1, { 702000, HFPLL, 1, 0x1A }, L2(3), 925000, AVS(0x0) },
- { 1, { 810000, HFPLL, 1, 0x1E }, L2(3), 950000, AVS(0x0) },
- { 1, { 918000, HFPLL, 1, 0x22 }, L2(3), 975000, AVS(0x0) },
- { 1, { 1026000, HFPLL, 1, 0x26 }, L2(3), 1000000, AVS(0x0) },
+ { 1, { 486000, HFPLL, 2, 0x24 }, L2(4), 900000, AVS(0x0) },
+ { 1, { 594000, HFPLL, 1, 0x16 }, L2(4), 900000, AVS(0x0) },
+ { 1, { 702000, HFPLL, 1, 0x1A }, L2(4), 925000, AVS(0x0) },
+ { 1, { 810000, HFPLL, 1, 0x1E }, L2(4), 950000, AVS(0x0) },
+ { 1, { 918000, HFPLL, 1, 0x22 }, L2(4), 975000, AVS(0x0) },
+ { 1, { 1026000, HFPLL, 1, 0x26 }, L2(4), 1000000, AVS(0x0) },
{ 1, { 1134000, HFPLL, 1, 0x2A }, L2(9), 1025000, AVS(0x70000D) },
{ 1, { 1242000, HFPLL, 1, 0x2E }, L2(9), 1050000, AVS(0x0) },
{ 1, { 1350000, HFPLL, 1, 0x32 }, L2(9), 1075000, AVS(0x0) },
@@ -181,12 +181,12 @@
static struct acpu_level freq_tbl_PVS4[] __initdata = {
{ 1, { 384000, PLL_8, 0, 0x00 }, L2(0), 875000, AVS(0x70001F) },
- { 1, { 486000, HFPLL, 2, 0x24 }, L2(3), 875000, AVS(0x0) },
- { 1, { 594000, HFPLL, 1, 0x16 }, L2(3), 875000, AVS(0x0) },
- { 1, { 702000, HFPLL, 1, 0x1A }, L2(3), 900000, AVS(0x0) },
- { 1, { 810000, HFPLL, 1, 0x1E }, L2(3), 925000, AVS(0x0) },
- { 1, { 918000, HFPLL, 1, 0x22 }, L2(3), 950000, AVS(0x0) },
- { 1, { 1026000, HFPLL, 1, 0x26 }, L2(3), 975000, AVS(0x0) },
+ { 1, { 486000, HFPLL, 2, 0x24 }, L2(4), 875000, AVS(0x0) },
+ { 1, { 594000, HFPLL, 1, 0x16 }, L2(4), 875000, AVS(0x0) },
+ { 1, { 702000, HFPLL, 1, 0x1A }, L2(4), 900000, AVS(0x0) },
+ { 1, { 810000, HFPLL, 1, 0x1E }, L2(4), 925000, AVS(0x0) },
+ { 1, { 918000, HFPLL, 1, 0x22 }, L2(4), 950000, AVS(0x0) },
+ { 1, { 1026000, HFPLL, 1, 0x26 }, L2(4), 975000, AVS(0x0) },
{ 1, { 1134000, HFPLL, 1, 0x2A }, L2(9), 1000000, AVS(0x70000D) },
{ 1, { 1242000, HFPLL, 1, 0x2E }, L2(9), 1025000, AVS(0x0) },
{ 1, { 1350000, HFPLL, 1, 0x32 }, L2(9), 1050000, AVS(0x0) },
@@ -199,12 +199,12 @@
static struct acpu_level freq_tbl_PVS5[] __initdata = {
{ 1, { 384000, PLL_8, 0, 0x00 }, L2(0), 875000, AVS(0x70001F) },
- { 1, { 486000, HFPLL, 2, 0x24 }, L2(3), 875000, AVS(0x0) },
- { 1, { 594000, HFPLL, 1, 0x16 }, L2(3), 875000, AVS(0x0) },
- { 1, { 702000, HFPLL, 1, 0x1A }, L2(3), 875000, AVS(0x0) },
- { 1, { 810000, HFPLL, 1, 0x1E }, L2(3), 900000, AVS(0x0) },
- { 1, { 918000, HFPLL, 1, 0x22 }, L2(3), 925000, AVS(0x0) },
- { 1, { 1026000, HFPLL, 1, 0x26 }, L2(3), 950000, AVS(0x0) },
+ { 1, { 486000, HFPLL, 2, 0x24 }, L2(4), 875000, AVS(0x0) },
+ { 1, { 594000, HFPLL, 1, 0x16 }, L2(4), 875000, AVS(0x0) },
+ { 1, { 702000, HFPLL, 1, 0x1A }, L2(4), 875000, AVS(0x0) },
+ { 1, { 810000, HFPLL, 1, 0x1E }, L2(4), 900000, AVS(0x0) },
+ { 1, { 918000, HFPLL, 1, 0x22 }, L2(4), 925000, AVS(0x0) },
+ { 1, { 1026000, HFPLL, 1, 0x26 }, L2(4), 950000, AVS(0x0) },
{ 1, { 1134000, HFPLL, 1, 0x2A }, L2(9), 975000, AVS(0x70000D) },
{ 1, { 1242000, HFPLL, 1, 0x2E }, L2(9), 1000000, AVS(0x0) },
{ 1, { 1350000, HFPLL, 1, 0x32 }, L2(9), 1025000, AVS(0x0) },
@@ -217,12 +217,12 @@
static struct acpu_level freq_tbl_PVS6[] __initdata = {
{ 1, { 384000, PLL_8, 0, 0x00 }, L2(0), 850000, AVS(0x70001F) },
- { 1, { 486000, HFPLL, 2, 0x24 }, L2(3), 850000, AVS(0x0) },
- { 1, { 594000, HFPLL, 1, 0x16 }, L2(3), 850000, AVS(0x0) },
- { 1, { 702000, HFPLL, 1, 0x1A }, L2(3), 850000, AVS(0x0) },
- { 1, { 810000, HFPLL, 1, 0x1E }, L2(3), 875000, AVS(0x0) },
- { 1, { 918000, HFPLL, 1, 0x22 }, L2(3), 900000, AVS(0x0) },
- { 1, { 1026000, HFPLL, 1, 0x26 }, L2(3), 925000, AVS(0x0) },
+ { 1, { 486000, HFPLL, 2, 0x24 }, L2(4), 850000, AVS(0x0) },
+ { 1, { 594000, HFPLL, 1, 0x16 }, L2(4), 850000, AVS(0x0) },
+ { 1, { 702000, HFPLL, 1, 0x1A }, L2(4), 850000, AVS(0x0) },
+ { 1, { 810000, HFPLL, 1, 0x1E }, L2(4), 875000, AVS(0x0) },
+ { 1, { 918000, HFPLL, 1, 0x22 }, L2(4), 900000, AVS(0x0) },
+ { 1, { 1026000, HFPLL, 1, 0x26 }, L2(4), 925000, AVS(0x0) },
{ 1, { 1134000, HFPLL, 1, 0x2A }, L2(9), 950000, AVS(0x70000D) },
{ 1, { 1242000, HFPLL, 1, 0x2E }, L2(9), 975000, AVS(0x0) },
{ 1, { 1350000, HFPLL, 1, 0x32 }, L2(9), 1000000, AVS(0x0) },
diff --git a/arch/arm/mach-msm/board-8930-gpiomux.c b/arch/arm/mach-msm/board-8930-gpiomux.c
index 53432e1..dcae37c 100644
--- a/arch/arm/mach-msm/board-8930-gpiomux.c
+++ b/arch/arm/mach-msm/board-8930-gpiomux.c
@@ -18,6 +18,51 @@
#include "devices.h"
#include "board-8930.h"
+/* GSBI10 UART configurations */
+static struct gpiomux_setting gsbi10_uart_cfg = {
+ .func = GPIOMUX_FUNC_2,
+ .drv = GPIOMUX_DRV_8MA,
+ .pull = GPIOMUX_PULL_NONE,
+};
+
+static struct msm_gpiomux_config msm8930_gsbi10_uart_configs[] __initdata = {
+ {
+ .gpio = 71, /* GSBI10 UART TX */
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &gsbi10_uart_cfg,
+ },
+ },
+ {
+ .gpio = 72, /* GSBI10 UART RX */
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &gsbi10_uart_cfg,
+ },
+ },
+};
+
+/* GSBI11 UART configurations */
+static struct gpiomux_setting gsbi11_uart_cfg = {
+ .func = GPIOMUX_FUNC_1,
+ .drv = GPIOMUX_DRV_10MA,
+ .pull = GPIOMUX_PULL_NONE,
+};
+
+static struct msm_gpiomux_config msm8930_gsbi11_uart_configs[] __initdata = {
+ {
+ .gpio = 38, /* GSBI11 UART TX */
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &gsbi11_uart_cfg,
+ },
+ },
+ {
+ .gpio = 39, /* GSBI11 UART RX */
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &gsbi11_uart_cfg,
+ },
+ },
+};
+
+
/* The SPI configurations apply to GSBI 1*/
static struct gpiomux_setting spi_active = {
.func = GPIOMUX_FUNC_1,
@@ -1005,9 +1050,22 @@
int __init sglte8930_init_gpiomux(void)
{
+ int minor_ver = SOCINFO_VERSION_MINOR(socinfo_get_platform_version());
+ int major_ver = SOCINFO_VERSION_MAJOR(socinfo_get_platform_version());
+
/* For 8960 Fusion 2.2 Primary IPC */
msm_gpiomux_install(msm8930_fusion_gsbi_configs,
ARRAY_SIZE(msm8930_fusion_gsbi_configs));
+ /* For 8930 SGLTE Serial Console */
+ if (machine_is_msm8930_evt() && major_ver == 1) {
+ if (minor_ver == 0)
+ msm_gpiomux_install(msm8930_gsbi10_uart_configs,
+ ARRAY_SIZE(msm8930_gsbi10_uart_configs));
+ else if (minor_ver == 1)
+ msm_gpiomux_install(msm8930_gsbi11_uart_configs,
+ ARRAY_SIZE(msm8930_gsbi11_uart_configs));
+ }
+
/* For SGLTE 8960 Fusion External VFR */
msm_gpiomux_install(msm8930_external_vfr_configs,
ARRAY_SIZE(msm8930_external_vfr_configs));
diff --git a/arch/arm/mach-msm/board-8930-pmic.c b/arch/arm/mach-msm/board-8930-pmic.c
index 06e4ce4..42ed257 100644
--- a/arch/arm/mach-msm/board-8930-pmic.c
+++ b/arch/arm/mach-msm/board-8930-pmic.c
@@ -592,7 +592,7 @@
&msm8930_ssbi_pm8038_pdata;
pm8038_platform_data.num_regulators
= msm8930_pm8038_regulator_pdata_len;
- if (machine_is_msm8930_mtp())
+ if (machine_is_msm8930_mtp() || machine_is_msm8930_evt())
pm8921_bms_pdata.battery_type = BATT_PALLADIUM;
else if (machine_is_msm8930_cdp())
pm8921_chg_pdata.has_dc_supply = true;
@@ -612,6 +612,6 @@
pm8921_chg_pdata.has_dc_supply = true;
}
- if (!machine_is_msm8930_mtp())
+ if (!machine_is_msm8930_mtp() && !machine_is_msm8930_evt())
pm8921_chg_pdata.battery_less_hardware = 1;
}
diff --git a/arch/arm/mach-msm/board-8930-regulator-pm8038.c b/arch/arm/mach-msm/board-8930-regulator-pm8038.c
index 0ecb030..3e7719b 100644
--- a/arch/arm/mach-msm/board-8930-regulator-pm8038.c
+++ b/arch/arm/mach-msm/board-8930-regulator-pm8038.c
@@ -615,3 +615,19 @@
.consumer_map = msm_rpm_regulator_consumer_mapping,
.consumer_map_len = ARRAY_SIZE(msm_rpm_regulator_consumer_mapping),
};
+
+void __init configure_8930_sglte_regulator(void)
+{
+ int i;
+ struct rpm_regulator_init_data *rpm_data;
+
+ for (i = 0; i < ARRAY_SIZE(msm8930_rpm_regulator_init_data); i++) {
+ rpm_data = &msm8930_rpm_regulator_init_data[i];
+ if (rpm_data->id == RPM_VREG_ID_PM8038_L17) {
+ rpm_data->init_data.constraints.always_on = 1;
+ rpm_data->system_uA = 10000;
+ rpm_data->peak_uA = 10000;
+ break;
+ }
+ }
+}
diff --git a/arch/arm/mach-msm/board-8930.c b/arch/arm/mach-msm/board-8930.c
index c0a570e..fad45d8 100644
--- a/arch/arm/mach-msm/board-8930.c
+++ b/arch/arm/mach-msm/board-8930.c
@@ -2360,7 +2360,6 @@
static struct platform_device *early_common_devices[] __initdata = {
&msm8960_device_dmov,
&msm_device_smd,
- &msm8960_device_uart_gsbi5,
&msm_device_uart_dm6,
&msm_device_saw_core0,
&msm_device_saw_core1,
@@ -2511,8 +2510,27 @@
&msm_fm_loopback,
};
+#define GSBI_DUAL_MODE_CODE 0x60
+#define MSM_GSBI10_PHYS 0x1A200000
+
static void __init msm8930_i2c_init(void)
{
+ int minor_ver = SOCINFO_VERSION_MINOR(socinfo_get_platform_version());
+ int major_ver = SOCINFO_VERSION_MAJOR(socinfo_get_platform_version());
+ void __iomem *gsbi_mem;
+
+ if (machine_is_msm8930_evt() &&
+ (socinfo_get_platform_subtype() == PLATFORM_SUBTYPE_SGLTE)) {
+ if (major_ver == 1 && minor_ver == 0) {
+ gsbi_mem = ioremap_nocache(MSM_GSBI10_PHYS, 4);
+ writel_relaxed(GSBI_DUAL_MODE_CODE, gsbi_mem);
+ /* Ensure protocol code is written before proceeding */
+ wmb();
+ iounmap(gsbi_mem);
+ msm8960_i2c_qup_gsbi10_pdata.use_gsbi_shared_mode = 1;
+ }
+ }
+
msm8960_device_qup_i2c_gsbi4.dev.platform_data =
&msm8960_i2c_qup_gsbi4_pdata;
@@ -2931,6 +2949,8 @@
static void __init msm8930_cdp_init(void)
{
int i, reg_size = 0;
+ int minor_ver = SOCINFO_VERSION_MINOR(socinfo_get_platform_version());
+ int major_ver = SOCINFO_VERSION_MAJOR(socinfo_get_platform_version());
if (socinfo_get_pmic_model() == PMIC_MODEL_PM8917)
msm8930_pm8917_pdata_fixup();
if (meminfo_init(SYS_MEMORY, SZ_256M) < 0)
@@ -2947,6 +2967,9 @@
BUG_ON(msm_rpmrs_levels_init(&msm_rpmrs_data_pm8917));
}
+ if (machine_is_msm8930_evt())
+ configure_8930_sglte_regulator();
+
regulator_suppress_info_printing();
if (msm_xo_init())
pr_err("Failed to initialize XO votes\n");
@@ -2983,6 +3006,21 @@
msm_device_uart_dm9.dev.platform_data = &msm_uart_dm9_pdata;
#endif
platform_device_register(&msm_device_uart_dm9);
+
+ /* For 8930 SGLTE serial console */
+ if (major_ver == 1) {
+ if (minor_ver == 0)
+ /* Add UART Serial for EVT1 device */
+ platform_device_register(
+ &msm8930_device_uart_gsbi10);
+ else if (minor_ver == 1)
+ /* Add UART Serial for EVT2 device */
+ platform_device_register(
+ &msm8930_device_uart_gsbi11);
+ }
+ } else {
+ /* For 8930 Standalone serial console */
+ platform_device_register(&msm8960_device_uart_gsbi5);
}
msm_otg_pdata.phy_init_seq = hsusb_phy_init_seq;
diff --git a/arch/arm/mach-msm/board-8930.h b/arch/arm/mach-msm/board-8930.h
index cb9398c..31e5ad9 100644
--- a/arch/arm/mach-msm/board-8930.h
+++ b/arch/arm/mach-msm/board-8930.h
@@ -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
@@ -150,6 +150,7 @@
void msm8930_pm8917_gpio_mpp_init(void);
void msm8930_mdp_writeback(struct memtype_reserve *reserve_table);
void __init msm8930_init_gpu(void);
+void __init configure_8930_sglte_regulator(void);
#define PLATFORM_IS_CHARM25() \
(machine_is_msm8930_cdp() && \
diff --git a/arch/arm/mach-msm/clock-8960.c b/arch/arm/mach-msm/clock-8960.c
index e802bf2..a7f50cf 100755
--- a/arch/arm/mach-msm/clock-8960.c
+++ b/arch/arm/mach-msm/clock-8960.c
@@ -6044,8 +6044,9 @@
CLK_LOOKUP("core_clk", gsbi8_uart_clk.c, ""),
/* used on 8930 SGLTE for Primary IPC */
CLK_LOOKUP("core_clk", gsbi9_uart_clk.c, "msm_serial_hs.1"),
- CLK_LOOKUP("core_clk", gsbi10_uart_clk.c, ""),
- CLK_LOOKUP("core_clk", gsbi11_uart_clk.c, ""),
+ /* used on 8930 SGLTE for serial console */
+ CLK_LOOKUP("core_clk", gsbi10_uart_clk.c, "msm_serial_hsl.1"),
+ CLK_LOOKUP("core_clk", gsbi11_uart_clk.c, "msm_serial_hsl.2"),
CLK_LOOKUP("core_clk", gsbi12_uart_clk.c, ""),
CLK_LOOKUP("core_clk", gsbi1_qup_clk.c, "spi_qsd.0"),
CLK_LOOKUP("core_clk", gsbi2_qup_clk.c, ""),
@@ -6100,7 +6101,9 @@
CLK_LOOKUP("iface_clk", gsbi9_p_clk.c, "msm_serial_hs.1"),
CLK_LOOKUP("iface_clk", gsbi9_p_clk.c, "qup_i2c.0"),
CLK_LOOKUP("iface_clk", gsbi10_p_clk.c, "qup_i2c.10"),
- CLK_LOOKUP("iface_clk", gsbi11_p_clk.c, ""),
+ /* used on 8930 SGLTE for serial console */
+ CLK_LOOKUP("iface_clk", gsbi10_p_clk.c, "msm_serial_hsl.1"),
+ CLK_LOOKUP("iface_clk", gsbi11_p_clk.c, "msm_serial_hsl.2"),
CLK_LOOKUP("iface_clk", gsbi12_p_clk.c, "qup_i2c.12"),
CLK_LOOKUP("iface_clk", tsif_p_clk.c, ""),
CLK_LOOKUP("iface_clk", usb_fs1_p_clk.c, ""),
diff --git a/arch/arm/mach-msm/devices-8960.c b/arch/arm/mach-msm/devices-8960.c
index eaacbfa..968a25e 100644
--- a/arch/arm/mach-msm/devices-8960.c
+++ b/arch/arm/mach-msm/devices-8960.c
@@ -76,11 +76,14 @@
#define MSM_GSBI11_PHYS 0x12440000
#define MSM_GSBI12_PHYS 0x12480000
+/* GSBI UART devices */
#define MSM_UART2DM_PHYS (MSM_GSBI2_PHYS + 0x40000)
#define MSM_UART5DM_PHYS (MSM_GSBI5_PHYS + 0x40000)
#define MSM_UART6DM_PHYS (MSM_GSBI6_PHYS + 0x40000)
#define MSM_UART8DM_PHYS (MSM_GSBI8_PHYS + 0x40000)
#define MSM_UART9DM_PHYS (MSM_GSBI9_PHYS + 0x40000)
+#define MSM_UART10DM_PHYS (MSM_GSBI10_PHYS + 0x40000)
+#define MSM_UART11DM_PHYS (MSM_GSBI11_PHYS + 0x10000)
/* GSBI QUP devices */
#define MSM_GSBI1_QUP_PHYS (MSM_GSBI1_PHYS + 0x80000)
@@ -412,6 +415,67 @@
},
};
+/* GSBI10 used for serial console on 8930 SGLTE*/
+static struct msm_serial_hslite_platform_data uart_gsbi10_pdata;
+
+static struct resource resources_uart_gsbi10[] = {
+ {
+ .start = GSBI10_UARTDM_IRQ,
+ .end = GSBI10_UARTDM_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = MSM_UART10DM_PHYS,
+ .end = MSM_UART10DM_PHYS + PAGE_SIZE - 1,
+ .name = "uartdm_resource",
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = MSM_GSBI10_PHYS,
+ .end = MSM_GSBI10_PHYS + PAGE_SIZE - 1,
+ .name = "gsbi_resource",
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+struct platform_device msm8930_device_uart_gsbi10 = {
+ .name = "msm_serial_hsl",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(resources_uart_gsbi10),
+ .resource = resources_uart_gsbi10,
+ .dev.platform_data = &uart_gsbi10_pdata,
+};
+
+static struct msm_serial_hslite_platform_data uart_gsbi11_pdata;
+
+static struct resource resources_uart_gsbi11[] = {
+ {
+ .start = GSBI11_UARTDM_IRQ,
+ .end = GSBI11_UARTDM_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = MSM_UART11DM_PHYS,
+ .end = MSM_UART11DM_PHYS + PAGE_SIZE - 1,
+ .name = "uartdm_resource",
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = MSM_GSBI11_PHYS,
+ .end = MSM_GSBI11_PHYS + PAGE_SIZE - 1,
+ .name = "gsbi_resource",
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+struct platform_device msm8930_device_uart_gsbi11 = {
+ .name = "msm_serial_hsl",
+ .id = 2,
+ .num_resources = ARRAY_SIZE(resources_uart_gsbi11),
+ .resource = resources_uart_gsbi11,
+ .dev.platform_data = &uart_gsbi11_pdata,
+};
+
static struct resource resources_uart_gsbi5[] = {
{
.start = GSBI5_UARTDM_IRQ,
diff --git a/arch/arm/mach-msm/devices.h b/arch/arm/mach-msm/devices.h
index 1879e2d..5eb71ee 100644
--- a/arch/arm/mach-msm/devices.h
+++ b/arch/arm/mach-msm/devices.h
@@ -60,6 +60,8 @@
extern struct platform_device msm8960_device_uart_gsbi2;
extern struct platform_device msm8960_device_uart_gsbi5;
extern struct platform_device msm8960_device_uart_gsbi8;
+extern struct platform_device msm8930_device_uart_gsbi10;
+extern struct platform_device msm8930_device_uart_gsbi11;
extern struct platform_device msm8960_device_ssbi_pmic;
extern struct platform_device msm8960_device_qup_i2c_gsbi3;
extern struct platform_device msm8960_device_qup_i2c_gsbi4;
diff --git a/arch/arm/mach-msm/hotplug.c b/arch/arm/mach-msm/hotplug.c
index 5cd5057..0e97c27 100644
--- a/arch/arm/mach-msm/hotplug.c
+++ b/arch/arm/mach-msm/hotplug.c
@@ -70,6 +70,11 @@
int platform_cpu_kill(unsigned int cpu)
{
+ int ret;
+
+ ret = msm_pm_wait_cpu_shutdown(cpu);
+ if (ret)
+ return 0;
return 1;
}
diff --git a/arch/arm/mach-msm/mdm_common.c b/arch/arm/mach-msm/mdm_common.c
index 9e53002..a2f1699 100644
--- a/arch/arm/mach-msm/mdm_common.c
+++ b/arch/arm/mach-msm/mdm_common.c
@@ -367,6 +367,7 @@
int status, ret = 0;
struct mdm_device *mdev = filp->private_data;
struct mdm_modem_drv *mdm_drv;
+ struct mdm_device *l_mdev;
if (_IOC_TYPE(cmd) != CHARM_CODE) {
pr_err("%s: invalid ioctl code to mdm id %d\n",
@@ -452,6 +453,14 @@
pr_debug("%s Image upgrade ioctl recieved\n", __func__);
if (mdm_drv->pdata->image_upgrade_supported &&
mdm_ops->image_upgrade_cb) {
+ list_for_each_entry(l_mdev, &mdm_devices, link) {
+ if (l_mdev != mdev) {
+ pr_debug("%s:setting mdm_rdy to false",
+ __func__);
+ atomic_set(&l_mdev->mdm_data.mdm_ready,
+ 0);
+ }
+ }
get_user(status, (unsigned long __user *) arg);
mdm_ops->image_upgrade_cb(mdm_drv, status);
} else
diff --git a/arch/arm/mach-msm/pm-8x60.c b/arch/arm/mach-msm/pm-8x60.c
index c931ac7..c1b3023 100644
--- a/arch/arm/mach-msm/pm-8x60.c
+++ b/arch/arm/mach-msm/pm-8x60.c
@@ -24,7 +24,9 @@
#include <linux/smp.h>
#include <linux/suspend.h>
#include <linux/tick.h>
+#include <linux/delay.h>
#include <linux/platform_device.h>
+#include <linux/of_platform.h>
#include <mach/msm_iomap.h>
#include <mach/socinfo.h>
#include <mach/system.h>
@@ -117,6 +119,7 @@
static struct hrtimer pm_hrtimer;
static struct msm_pm_sleep_ops pm_sleep_ops;
+static struct msm_pm_sleep_status_data *msm_pm_slp_sts;
/*
* Write out the attribute.
*/
@@ -940,6 +943,32 @@
return 0;
}
+int msm_pm_wait_cpu_shutdown(unsigned int cpu)
+{
+ int timeout = 10;
+
+ if (!msm_pm_slp_sts)
+ return 0;
+ if (!msm_pm_slp_sts[cpu].base_addr)
+ return 0;
+ while (timeout--) {
+ /*
+ * Check for the SPM of the core being hotplugged to set
+ * its sleep state.The SPM sleep state indicates that the
+ * core has been power collapsed.
+ */
+ int acc_sts = __raw_readl(msm_pm_slp_sts[cpu].base_addr);
+
+ if (acc_sts & msm_pm_slp_sts[cpu].mask)
+ return 0;
+ udelay(100);
+ }
+
+ pr_info("%s(): Timed out waiting for CPU %u SPM to enter sleep state",
+ __func__, cpu);
+ return -EBUSY;
+}
+
void msm_pm_cpu_enter_lowpower(unsigned int cpu)
{
int i;
@@ -1104,6 +1133,93 @@
{.compatible = "qcom,pc-cntr"},
{},
};
+static int __devinit msm_cpu_status_probe(struct platform_device *pdev)
+{
+ struct msm_pm_sleep_status_data *pdata;
+ char *key;
+ u32 cpu;
+
+ if (!pdev)
+ return -EFAULT;
+
+ msm_pm_slp_sts =
+ kzalloc(sizeof(*msm_pm_slp_sts) * num_possible_cpus(),
+ GFP_KERNEL);
+
+ if (!msm_pm_slp_sts)
+ return -ENOMEM;
+
+ if (pdev->dev.of_node) {
+ struct resource *res;
+ u32 offset;
+ int rc;
+ u32 mask;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res)
+ goto fail_free_mem;
+
+ key = "qcom,cpu-alias-addr";
+ rc = of_property_read_u32(pdev->dev.of_node, key, &offset);
+
+ if (rc)
+ goto fail_free_mem;
+
+ key = "qcom,sleep-status-mask";
+ rc = of_property_read_u32(pdev->dev.of_node, key,
+ &mask);
+ if (rc)
+ goto fail_free_mem;
+
+ for_each_possible_cpu(cpu) {
+ msm_pm_slp_sts[cpu].base_addr =
+ ioremap(res->start + cpu * offset,
+ resource_size(res));
+ msm_pm_slp_sts[cpu].mask = mask;
+
+ if (!msm_pm_slp_sts[cpu].base_addr)
+ goto failed_of_node;
+ }
+
+ } else {
+ pdata = pdev->dev.platform_data;
+ if (!pdev->dev.platform_data)
+ goto fail_free_mem;
+
+ for_each_possible_cpu(cpu) {
+ msm_pm_slp_sts[cpu].base_addr =
+ pdata->base_addr + cpu * pdata->cpu_offset;
+ msm_pm_slp_sts[cpu].mask = pdata->mask;
+ }
+ }
+
+ return 0;
+
+failed_of_node:
+ pr_info("%s(): Failed to key=%s\n", __func__, key);
+ for_each_possible_cpu(cpu) {
+ if (msm_pm_slp_sts[cpu].base_addr)
+ iounmap(msm_pm_slp_sts[cpu].base_addr);
+ }
+fail_free_mem:
+ kfree(msm_pm_slp_sts);
+ return -EINVAL;
+
+};
+
+static struct of_device_id msm_slp_sts_match_tbl[] = {
+ {.compatible = "qcom,cpu-sleep-status"},
+ {},
+};
+
+static struct platform_driver msm_cpu_status_driver = {
+ .probe = msm_cpu_status_probe,
+ .driver = {
+ .name = "cpu_slp_status",
+ .owner = THIS_MODULE,
+ .of_match_table = msm_slp_sts_match_tbl,
+ },
+};
static struct platform_driver msm_pc_counter_driver = {
.probe = msm_pc_debug_probe,
@@ -1165,6 +1281,8 @@
static int __init msm_pm_init(void)
{
+ int rc;
+
enum msm_pm_time_stats_id enable_stats[] = {
MSM_PM_STAT_IDLE_WFI,
MSM_PM_STAT_RETENTION,
@@ -1181,6 +1299,14 @@
hrtimer_init(&pm_hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
msm_cpuidle_init();
platform_driver_register(&msm_pc_counter_driver);
+ rc = platform_driver_register(&msm_cpu_status_driver);
+
+ if (rc) {
+ pr_err("%s(): failed to register driver %s\n", __func__,
+ msm_cpu_status_driver.driver.name);
+ return rc;
+ }
+
return 0;
}
diff --git a/arch/arm/mach-msm/subsystem_restart.c b/arch/arm/mach-msm/subsystem_restart.c
index f2e969a..747276c 100644
--- a/arch/arm/mach-msm/subsystem_restart.c
+++ b/arch/arm/mach-msm/subsystem_restart.c
@@ -52,6 +52,18 @@
struct list_head list;
};
+enum subsys_state {
+ SUBSYS_OFFLINE,
+ SUBSYS_ONLINE,
+ SUBSYS_CRASHED,
+};
+
+static const char * const subsys_states[] = {
+ [SUBSYS_OFFLINE] = "OFFLINE",
+ [SUBSYS_ONLINE] = "ONLINE",
+ [SUBSYS_CRASHED] = "CRASHED",
+};
+
struct subsys_device {
struct subsys_desc *desc;
struct list_head list;
@@ -59,7 +71,8 @@
char wlname[64];
struct work_struct work;
spinlock_t restart_lock;
- int restart_count;
+ bool restarting;
+ enum subsys_state state;
void *notify;
@@ -180,6 +193,20 @@
module_param_call(restart_level, restart_level_set, param_get_int,
&restart_level, 0644);
+static void subsys_set_state(struct subsys_device *subsys,
+ enum subsys_state state)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&subsys->restart_lock, flags);
+ if (subsys->state != state) {
+ subsys->state = state;
+ spin_unlock_irqrestore(&subsys->restart_lock, flags);
+ return;
+ }
+ spin_unlock_irqrestore(&subsys->restart_lock, flags);
+}
+
static struct subsys_soc_restart_order *
update_restart_order(struct subsys_device *dev)
{
@@ -303,6 +330,7 @@
panic("subsys-restart: [%p]: Failed to shutdown %s!",
current, name);
}
+ subsys_set_state(dev, SUBSYS_OFFLINE);
}
static void subsystem_ramdump(struct subsys_device *dev, void *data)
@@ -322,6 +350,7 @@
if (dev->desc->powerup(dev->desc) < 0) {
panic("[%p]: Failed to powerup %s!", current, name);
}
+ subsys_set_state(dev, SUBSYS_ONLINE);
}
static void subsystem_restart_wq_func(struct work_struct *work)
@@ -371,7 +400,10 @@
* Now that we've acquired the shutdown lock, either we're the first to
* restart these subsystems or some other thread is doing the powerup
* sequence for these subsystems. In the latter case, panic and bail
- * out, since a subsystem died in its powerup sequence.
+ * out, since a subsystem died in its powerup sequence. This catches
+ * the case where a subsystem in a restart order isn't the one
+ * who initiated the original restart but has crashed while the restart
+ * order is being rebooted.
*/
if (!mutex_trylock(powerup_lock)) {
panic("%s[%p]: Subsystem died during powerup!",
@@ -419,32 +451,36 @@
out:
spin_lock_irqsave(&dev->restart_lock, flags);
- dev->restart_count--;
- if (!dev->restart_count)
- wake_unlock(&dev->wake_lock);
+ dev->restarting = false;
+ wake_unlock(&dev->wake_lock);
spin_unlock_irqrestore(&dev->restart_lock, flags);
}
static void __subsystem_restart_dev(struct subsys_device *dev)
{
struct subsys_desc *desc = dev->desc;
+ const char *name = dev->desc->name;
unsigned long flags;
pr_debug("Restarting %s [level=%d]!\n", desc->name, restart_level);
+ /*
+ * We want to allow drivers to call subsystem_restart{_dev}() as many
+ * times as they want up until the point where the subsystem is
+ * shutdown.
+ */
spin_lock_irqsave(&dev->restart_lock, flags);
- if (!dev->restart_count)
- wake_lock(&dev->wake_lock);
- dev->restart_count++;
- spin_unlock_irqrestore(&dev->restart_lock, flags);
-
- if (!queue_work(ssr_wq, &dev->work)) {
- spin_lock_irqsave(&dev->restart_lock, flags);
- dev->restart_count--;
- if (!dev->restart_count)
- wake_unlock(&dev->wake_lock);
- spin_unlock_irqrestore(&dev->restart_lock, flags);
+ if (dev->state != SUBSYS_CRASHED) {
+ if (dev->state == SUBSYS_ONLINE && !dev->restarting) {
+ dev->restarting = true;
+ dev->state = SUBSYS_CRASHED;
+ wake_lock(&dev->wake_lock);
+ queue_work(ssr_wq, &dev->work);
+ } else {
+ panic("Subsystem %s crashed during SSR!", name);
+ }
}
+ spin_unlock_irqrestore(&dev->restart_lock, flags);
}
int subsystem_restart_dev(struct subsys_device *dev)
@@ -511,6 +547,7 @@
dev->desc = desc;
dev->notify = subsys_notif_add_subsys(desc->name);
dev->restart_order = update_restart_order(dev);
+ dev->state = SUBSYS_ONLINE; /* Until proper refcounting appears */
snprintf(dev->wlname, sizeof(dev->wlname), "ssr(%s)", desc->name);
wake_lock_init(&dev->wake_lock, WAKE_LOCK_SUSPEND, dev->wlname);
diff --git a/drivers/char/diag/diagchar.h b/drivers/char/diag/diagchar.h
index 6f37608..d630ab2 100644
--- a/drivers/char/diag/diagchar.h
+++ b/drivers/char/diag/diagchar.h
@@ -276,6 +276,8 @@
struct usb_diag_ch *legacy_ch;
struct work_struct diag_proc_hdlc_work;
struct work_struct diag_read_work;
+ struct work_struct diag_usb_connect_work;
+ struct work_struct diag_usb_disconnect_work;
#endif
struct workqueue_struct *diag_wq;
struct work_struct diag_drain_work;
@@ -312,6 +314,7 @@
#ifdef CONFIG_DIAGFWD_BRIDGE_CODE
spinlock_t hsic_ready_spinlock;
/* common for all bridges */
+ struct work_struct diag_connect_work;
struct work_struct diag_disconnect_work;
/* SGLTE variables */
int lcid;
diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c
index a0c32f5..c17fbc0 100644
--- a/drivers/char/diag/diagchar_core.c
+++ b/drivers/char/diag/diagchar_core.c
@@ -1885,6 +1885,11 @@
}
#ifdef CONFIG_DIAGFWD_BRIDGE_CODE
+static void diag_connect_work_fn(struct work_struct *w)
+{
+ diagfwd_connect_bridge(1);
+}
+
static void diag_disconnect_work_fn(struct work_struct *w)
{
diagfwd_disconnect_bridge(1);
@@ -1969,6 +1974,8 @@
pr_err("diag: could not register HSIC device, ret: %d\n",
ret);
diagfwd_bridge_init(SMUX);
+ INIT_WORK(&(driver->diag_connect_work),
+ diag_connect_work_fn);
INIT_WORK(&(driver->diag_disconnect_work),
diag_disconnect_work_fn);
#endif
diff --git a/drivers/char/diag/diagfwd.c b/drivers/char/diag/diagfwd.c
index a4003ff..540bea4 100644
--- a/drivers/char/diag/diagfwd.c
+++ b/drivers/char/diag/diagfwd.c
@@ -1282,6 +1282,16 @@
#define N_LEGACY_WRITE (driver->poolsize + 6)
#define N_LEGACY_READ 1
+static void diag_usb_connect_work_fn(struct work_struct *w)
+{
+ diagfwd_connect();
+}
+
+static void diag_usb_disconnect_work_fn(struct work_struct *w)
+{
+ diagfwd_disconnect();
+}
+
int diagfwd_connect(void)
{
int err;
@@ -1448,10 +1458,12 @@
{
switch (event) {
case USB_DIAG_CONNECT:
- diagfwd_connect();
+ queue_work(driver->diag_wq,
+ &driver->diag_usb_connect_work);
break;
case USB_DIAG_DISCONNECT:
- diagfwd_disconnect();
+ queue_work(driver->diag_wq,
+ &driver->diag_usb_disconnect_work);
break;
case USB_DIAG_READ_DONE:
diagfwd_read_complete(d_req);
@@ -1832,6 +1844,10 @@
}
driver->diag_wq = create_singlethread_workqueue("diag_wq");
#ifdef CONFIG_DIAG_OVER_USB
+ INIT_WORK(&(driver->diag_usb_connect_work),
+ diag_usb_connect_work_fn);
+ INIT_WORK(&(driver->diag_usb_disconnect_work),
+ diag_usb_disconnect_work_fn);
INIT_WORK(&(driver->diag_proc_hdlc_work), diag_process_hdlc_fn);
INIT_WORK(&(driver->diag_read_work), diag_read_work_fn);
driver->legacy_ch = usb_diag_open(DIAG_LEGACY, driver,
diff --git a/drivers/char/diag/diagfwd_bridge.c b/drivers/char/diag/diagfwd_bridge.c
index 475f5ba..8c07219b 100644
--- a/drivers/char/diag/diagfwd_bridge.c
+++ b/drivers/char/diag/diagfwd_bridge.c
@@ -233,7 +233,8 @@
switch (event) {
case USB_DIAG_CONNECT:
- diagfwd_connect_bridge(1);
+ queue_work(driver->diag_wq,
+ &driver->diag_connect_work);
break;
case USB_DIAG_DISCONNECT:
queue_work(driver->diag_wq,
diff --git a/drivers/input/touchscreen/synaptics_fw_update.c b/drivers/input/touchscreen/synaptics_fw_update.c
index 7f94716..99b7f73 100644
--- a/drivers/input/touchscreen/synaptics_fw_update.c
+++ b/drivers/input/touchscreen/synaptics_fw_update.c
@@ -30,7 +30,6 @@
#define DEBUG_FW_UPDATE
#define SHOW_PROGRESS
-#define FW_IMAGE_NAME "PR1063486-s7301_00000000.img"
#define MAX_FIRMWARE_ID_LEN 10
#define FORCE_UPDATE false
#define INSIDE_FIRMWARE_UPDATE
@@ -561,8 +560,6 @@
goto exit;
}
- imagePR = kzalloc(sizeof(MAX_FIRMWARE_ID_LEN), GFP_KERNEL);
-
/* Force update firmware when device is in bootloader mode */
if (f01_device_status.flash_prog) {
dev_info(&i2c_client->dev,
@@ -587,7 +584,8 @@
deviceFirmwareID = extract_uint(firmware_id);
/* .img firmware id */
- strptr = strstr(FW_IMAGE_NAME, "PR");
+ strptr = strnstr(fwu->rmi4_data->fw_image_name, "PR",
+ sizeof(fwu->rmi4_data->fw_image_name));
if (!strptr) {
dev_err(&i2c_client->dev,
"No valid PR number (PRxxxxxxx)" \
@@ -602,7 +600,7 @@
}
imagePR[index] = 0;
- retval = sstrtoul(imagePR, 10, &imageFirmwareID);
+ retval = kstrtoul(imagePR, 10, &imageFirmwareID);
if (retval == -EINVAL) {
dev_err(&i2c_client->dev,
"invalid image firmware id...\n");
@@ -616,6 +614,11 @@
if (imageFirmwareID > deviceFirmwareID) {
flash_area = UI_FIRMWARE;
goto exit;
+ } else if (imageFirmwareID < deviceFirmwareID) {
+ flash_area = NONE;
+ dev_info(&i2c_client->dev,
+ "Img fw is older than device fw. Skip fw update.\n");
+ goto exit;
}
/* device config id */
@@ -1216,19 +1219,28 @@
pr_notice("%s: Start of reflash process\n", __func__);
+ if (!fwu->rmi4_data->fw_image_name) {
+ retval = 0;
+ dev_err(&fwu->rmi4_data->i2c_client->dev,
+ "Firmware image name not given, skipping update\n");
+ goto exit;
+ }
+
if (fwu->ext_data_source)
fw_image = fwu->ext_data_source;
else {
dev_dbg(&fwu->rmi4_data->i2c_client->dev,
"%s: Requesting firmware image %s\n",
- __func__, FW_IMAGE_NAME);
+ __func__, fwu->rmi4_data->fw_image_name);
- retval = request_firmware(&fw_entry, FW_IMAGE_NAME,
+ retval = request_firmware(&fw_entry,
+ fwu->rmi4_data->fw_image_name,
&fwu->rmi4_data->i2c_client->dev);
if (retval != 0) {
dev_err(&fwu->rmi4_data->i2c_client->dev,
"%s: Firmware image %s not available\n",
- __func__, FW_IMAGE_NAME);
+ __func__,
+ fwu->rmi4_data->fw_image_name);
retval = -EINVAL;
goto exit;
}
@@ -1650,6 +1662,9 @@
&fwu->fwu_work,
msecs_to_jiffies(1000));
#endif
+
+ init_completion(&remove_complete);
+
return 0;
exit_remove_attrs:
@@ -1700,7 +1715,6 @@
static void __exit rmi4_fw_update_module_exit(void)
{
- init_completion(&remove_complete);
synaptics_rmi4_new_function(RMI_FW_UPDATER, false,
synaptics_rmi4_fwu_init,
synaptics_rmi4_fwu_remove,
diff --git a/drivers/input/touchscreen/synaptics_i2c_rmi4.c b/drivers/input/touchscreen/synaptics_i2c_rmi4.c
index 775d62a..685e39d 100644
--- a/drivers/input/touchscreen/synaptics_i2c_rmi4.c
+++ b/drivers/input/touchscreen/synaptics_i2c_rmi4.c
@@ -34,6 +34,9 @@
#define DRIVER_NAME "synaptics_rmi4_i2c"
#define INPUT_PHYS_NAME "synaptics_rmi4_i2c/input0"
+
+#define RESET_DELAY 100
+
#define TYPE_B_PROTOCOL
#define NO_0D_WHILE_2D
@@ -65,8 +68,18 @@
#define NORMAL_OPERATION (0 << 0)
#define SENSOR_SLEEP (1 << 0)
-#define NO_SLEEP_OFF (0 << 3)
-#define NO_SLEEP_ON (1 << 3)
+#define NO_SLEEP_OFF (0 << 2)
+#define NO_SLEEP_ON (1 << 2)
+
+enum device_status {
+ STATUS_NO_ERROR = 0x00,
+ STATUS_RESET_OCCURED = 0x01,
+ STATUS_INVALID_CONFIG = 0x02,
+ STATUS_DEVICE_FAILURE = 0x03,
+ STATUS_CONFIG_CRC_FAILURE = 0x04,
+ STATUS_FIRMWARE_CRC_FAILURE = 0x05,
+ STATUS_CRC_IN_PROGRESS = 0x06
+};
#define RMI4_VTG_MIN_UV 2700000
#define RMI4_VTG_MAX_UV 3300000
@@ -79,7 +92,6 @@
#define RMI4_I2C_LPM_LOAD_UA 10
#define RMI4_GPIO_SLEEP_LOW_US 10000
-#define RMI4_GPIO_WAIT_HIGH_MS 25
static int synaptics_rmi4_i2c_read(struct synaptics_rmi4_data *rmi4_data,
unsigned short addr, unsigned char *data,
@@ -125,6 +137,19 @@
static ssize_t synaptics_rmi4_0dbutton_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count);
+static ssize_t synaptics_rmi4_flipx_show(struct device *dev,
+ struct device_attribute *attr, char *buf);
+
+static ssize_t synaptics_rmi4_flipx_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count);
+
+static ssize_t synaptics_rmi4_flipy_show(struct device *dev,
+ struct device_attribute *attr, char *buf);
+
+static ssize_t synaptics_rmi4_flipy_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count);
+
+
struct synaptics_rmi4_f01_device_status {
union {
struct {
@@ -223,6 +248,12 @@
__ATTR(0dbutton, (S_IRUGO | S_IWUGO),
synaptics_rmi4_0dbutton_show,
synaptics_rmi4_0dbutton_store),
+ __ATTR(flipx, (S_IRUGO | S_IWUGO),
+ synaptics_rmi4_flipx_show,
+ synaptics_rmi4_flipx_store),
+ __ATTR(flipy, (S_IRUGO | S_IWUGO),
+ synaptics_rmi4_flipy_show,
+ synaptics_rmi4_flipy_store),
};
static bool exp_fn_inited;
@@ -391,6 +422,52 @@
return count;
}
+static ssize_t synaptics_rmi4_flipx_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev);
+
+ return snprintf(buf, PAGE_SIZE, "%u\n",
+ rmi4_data->flip_x);
+}
+
+static ssize_t synaptics_rmi4_flipx_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ unsigned int input;
+ struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev);
+
+ if (sscanf(buf, "%u", &input) != 1)
+ return -EINVAL;
+
+ rmi4_data->flip_x = input > 0 ? 1 : 0;
+
+ return count;
+}
+
+static ssize_t synaptics_rmi4_flipy_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev);
+
+ return snprintf(buf, PAGE_SIZE, "%u\n",
+ rmi4_data->flip_y);
+}
+
+static ssize_t synaptics_rmi4_flipy_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ unsigned int input;
+ struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev);
+
+ if (sscanf(buf, "%u", &input) != 1)
+ return -EINVAL;
+
+ rmi4_data->flip_y = input > 0 ? 1 : 0;
+
+ return count;
+}
+
/**
* synaptics_rmi4_set_page()
*
@@ -581,6 +658,7 @@
int y;
int wx;
int wy;
+ int z;
/*
* The number of finger status registers is determined by the
@@ -634,10 +712,11 @@
y = (data[1] << 4) | ((data[2] >> 4) & MASK_4BIT);
wx = (data[3] & MASK_4BIT);
wy = (data[3] >> 4) & MASK_4BIT;
+ z = data[4];
- if (rmi4_data->board->x_flip)
+ if (rmi4_data->flip_x)
x = rmi4_data->sensor_max_x - x;
- if (rmi4_data->board->y_flip)
+ if (rmi4_data->flip_y)
y = rmi4_data->sensor_max_y - y;
dev_dbg(&rmi4_data->i2c_client->dev,
@@ -655,6 +734,8 @@
ABS_MT_POSITION_X, x);
input_report_abs(rmi4_data->input_dev,
ABS_MT_POSITION_Y, y);
+ input_report_abs(rmi4_data->input_dev,
+ ABS_MT_PRESSURE, z);
#ifdef REPORT_2D_W
input_report_abs(rmi4_data->input_dev,
@@ -937,6 +1018,13 @@
rmi4_pdata->panel_y = temp_val;
}
+ rc = of_property_read_string(np, "synaptics,fw-image-name",
+ &rmi4_pdata->fw_image_name);
+ if (rc && (rc != -EINVAL)) {
+ dev_err(dev, "Unable to read fw image name\n");
+ return rc;
+ }
+
/* reset, irq gpio info */
rmi4_pdata->reset_gpio = of_get_named_gpio_flags(np,
"synaptics,reset-gpio", 0, &rmi4_pdata->reset_flags);
@@ -1007,22 +1095,12 @@
if (retval < 0)
return retval;
- retval = request_threaded_irq(rmi4_data->irq, NULL,
- synaptics_rmi4_irq,
- rmi4_data->board->irq_flags,
- DRIVER_NAME, rmi4_data);
- if (retval < 0) {
- dev_err(&rmi4_data->i2c_client->dev,
- "%s: Failed to create irq thread\n",
- __func__);
- return retval;
- }
+ enable_irq(rmi4_data->irq);
rmi4_data->irq_enabled = true;
} else {
if (rmi4_data->irq_enabled) {
disable_irq(rmi4_data->irq);
- free_irq(rmi4_data->irq, rmi4_data);
rmi4_data->irq_enabled = false;
}
}
@@ -1257,7 +1335,7 @@
static int synaptics_rmi4_alloc_fh(struct synaptics_rmi4_fn **fhandler,
struct synaptics_rmi4_fn_desc *rmi_fd, int page_number)
{
- *fhandler = kmalloc(sizeof(**fhandler), GFP_KERNEL);
+ *fhandler = kzalloc(sizeof(**fhandler), GFP_KERNEL);
if (!(*fhandler))
return -ENOMEM;
@@ -1273,6 +1351,7 @@
(*fhandler)->full_addr.query_base =
(rmi_fd->query_base_addr |
(page_number << 8));
+ (*fhandler)->fn_number = rmi_fd->fn_number;
return 0;
}
@@ -1331,7 +1410,7 @@
__func__, retval);
return retval;
}
- return retval;
+ return 0;
}
/**
@@ -1415,8 +1494,21 @@
if (retval < 0)
return retval;
+ while (status.status_code ==
+ STATUS_CRC_IN_PROGRESS) {
+ msleep(1);
+ retval = synaptics_rmi4_i2c_read(
+ rmi4_data,
+ rmi4_data->f01_data_base_addr,
+ status.data,
+ sizeof(status.data));
+ if (retval < 0)
+ return retval;
+ }
+
if (status.flash_prog == 1) {
- pr_notice("%s: In flash prog mode, status = 0x%02x\n",
+ pr_notice("%s: In flash prog mode," \
+ "status = 0x%02x\n",
__func__,
status.status_code);
goto flash_prog_mode;
@@ -1424,6 +1516,18 @@
break;
case SYNAPTICS_RMI4_F34:
+ if (rmi_fd.intr_src_count == 0)
+ break;
+
+ retval = synaptics_rmi4_alloc_fh(&fhandler,
+ &rmi_fd, page_number);
+ if (retval < 0) {
+ dev_err(&rmi4_data->i2c_client->dev,
+ "%s: Failed to alloc for F%d\n",
+ __func__,
+ rmi_fd.fn_number);
+ return retval;
+ }
retval = synaptics_rmi4_i2c_read(rmi4_data,
rmi_fd.ctrl_base_addr,
rmi->config_id,
@@ -1530,14 +1634,51 @@
return 0;
}
-static int synaptics_rmi4_reset_device(struct synaptics_rmi4_data *rmi4_data)
+static int synaptics_rmi4_reset_command(struct synaptics_rmi4_data *rmi4_data)
{
int retval;
+ int page_number;
unsigned char command = 0x01;
- struct synaptics_rmi4_fn *fhandler;
- struct synaptics_rmi4_device_info *rmi;
+ unsigned short pdt_entry_addr;
+ struct synaptics_rmi4_fn_desc rmi_fd;
+ bool done = false;
- rmi = &(rmi4_data->rmi4_mod_info);
+ /* Scan the page description tables of the pages to service */
+ for (page_number = 0; page_number < PAGES_TO_SERVICE; page_number++) {
+ for (pdt_entry_addr = PDT_START; pdt_entry_addr > PDT_END;
+ pdt_entry_addr -= PDT_ENTRY_SIZE) {
+ retval = synaptics_rmi4_i2c_read(rmi4_data,
+ pdt_entry_addr,
+ (unsigned char *)&rmi_fd,
+ sizeof(rmi_fd));
+ if (retval < 0)
+ return retval;
+
+ if (rmi_fd.fn_number == 0)
+ break;
+
+ switch (rmi_fd.fn_number) {
+ case SYNAPTICS_RMI4_F01:
+ rmi4_data->f01_cmd_base_addr =
+ rmi_fd.cmd_base_addr;
+ done = true;
+ break;
+ }
+ }
+ if (done) {
+ dev_info(&rmi4_data->i2c_client->dev,
+ "%s: Find F01 in page description table 0x%x\n",
+ __func__, rmi4_data->f01_cmd_base_addr);
+ break;
+ }
+ }
+
+ if (!done) {
+ dev_err(&rmi4_data->i2c_client->dev,
+ "%s: Cannot find F01 in page description table\n",
+ __func__);
+ return -EINVAL;
+ }
retval = synaptics_rmi4_i2c_write(rmi4_data,
rmi4_data->f01_cmd_base_addr,
@@ -1550,7 +1691,25 @@
return retval;
}
- msleep(100);
+ msleep(RESET_DELAY);
+ return retval;
+};
+
+static int synaptics_rmi4_reset_device(struct synaptics_rmi4_data *rmi4_data)
+{
+ int retval;
+ struct synaptics_rmi4_fn *fhandler;
+ struct synaptics_rmi4_device_info *rmi;
+
+ rmi = &(rmi4_data->rmi4_mod_info);
+
+ retval = synaptics_rmi4_reset_command(rmi4_data);
+ if (retval < 0) {
+ dev_err(&rmi4_data->i2c_client->dev,
+ "%s: Failed to send command reset\n",
+ __func__);
+ return retval;
+ }
if (!list_empty(&rmi->support_fn_list)) {
list_for_each_entry(fhandler, &rmi->support_fn_list, link) {
@@ -1921,6 +2080,11 @@
rmi4_data->irq_enable = synaptics_rmi4_irq_enable;
rmi4_data->reset_device = synaptics_rmi4_reset_device;
+ rmi4_data->flip_x = rmi4_data->board->x_flip;
+ rmi4_data->flip_y = rmi4_data->board->y_flip;
+
+ rmi4_data->fw_image_name = rmi4_data->board->fw_image_name;
+
rmi4_data->input_dev->name = DRIVER_NAME;
rmi4_data->input_dev->phys = INPUT_PHYS_NAME;
rmi4_data->input_dev->id.bustype = BUS_I2C;
@@ -1992,8 +2156,9 @@
gpio_set_value(platform_data->reset_gpio, 0);
usleep(RMI4_GPIO_SLEEP_LOW_US);
gpio_set_value(platform_data->reset_gpio, 1);
- msleep(RMI4_GPIO_WAIT_HIGH_MS);
- }
+ msleep(RESET_DELAY);
+ } else
+ synaptics_rmi4_reset_command(rmi4_data);
init_waitqueue_head(&rmi4_data->wait);
@@ -2013,6 +2178,8 @@
input_set_abs_params(rmi4_data->input_dev,
ABS_MT_POSITION_Y, 0,
rmi4_data->sensor_max_y, 0, 0);
+ input_set_abs_params(rmi4_data->input_dev,
+ ABS_PRESSURE, 0, 255, 0, 0);
#ifdef REPORT_2D_W
input_set_abs_params(rmi4_data->input_dev,
ABS_MT_TOUCH_MAJOR, 0,
@@ -2074,10 +2241,14 @@
rmi4_data->irq = gpio_to_irq(platform_data->irq_gpio);
- retval = synaptics_rmi4_irq_enable(rmi4_data, true);
+ retval = request_threaded_irq(rmi4_data->irq, NULL,
+ synaptics_rmi4_irq, platform_data->irq_flags,
+ DRIVER_NAME, rmi4_data);
+ rmi4_data->irq_enabled = true;
+
if (retval < 0) {
dev_err(&client->dev,
- "%s: Failed to enable attention interrupt\n",
+ "%s: Failed to create irq thread\n",
__func__);
goto err_enable_irq;
}
@@ -2092,6 +2263,13 @@
goto err_sysfs;
}
}
+ retval = synaptics_rmi4_irq_enable(rmi4_data, true);
+ if (retval < 0) {
+ dev_err(&client->dev,
+ "%s: Failed to enable attention interrupt\n",
+ __func__);
+ goto err_sysfs;
+ }
return retval;
@@ -2162,7 +2340,7 @@
rmi4_data->touch_stopped = true;
wake_up(&rmi4_data->wait);
- synaptics_rmi4_irq_enable(rmi4_data, false);
+ free_irq(rmi4_data->irq, rmi4_data);
for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) {
sysfs_remove_file(&rmi4_data->input_dev->dev.kobj,
diff --git a/drivers/input/touchscreen/synaptics_i2c_rmi4.h b/drivers/input/touchscreen/synaptics_i2c_rmi4.h
index d13f172..16b1f8f 100644
--- a/drivers/input/touchscreen/synaptics_i2c_rmi4.h
+++ b/drivers/input/touchscreen/synaptics_i2c_rmi4.h
@@ -24,7 +24,7 @@
#define SYNAPTICS_DS4 (1 << 0)
#define SYNAPTICS_DS5 (1 << 1)
#define SYNAPTICS_DSX_DRIVER_PRODUCT SYNAPTICS_DS4
-#define SYNAPTICS_DSX_DRIVER_VERSION 0x1002
+#define SYNAPTICS_DSX_DRIVER_VERSION 0x1004
#include <linux/version.h>
#ifdef CONFIG_HAS_EARLYSUSPEND
@@ -177,6 +177,8 @@
* @irq_enabled: flag for indicating interrupt enable status
* @touch_stopped: flag to stop interrupt thread processing
* @fingers_on_2d: flag to indicate presence of fingers in 2d area
+ * @flip_x: set to TRUE if desired to flip direction on x-axis
+ * @flip_y: set to TRUE if desired to flip direction on y-axis
* @sensor_sleep: flag to indicate sleep state of sensor
* @wait: wait queue for touch data polling in interrupt thread
* @i2c_read: pointer to i2c read function
@@ -193,7 +195,10 @@
struct mutex rmi4_io_ctrl_mutex;
struct delayed_work det_work;
struct workqueue_struct *det_workqueue;
+#ifdef CONFIG_HAS_EARLYSUSPEND
struct early_suspend early_suspend;
+#endif
+ const char *fw_image_name;
unsigned char current_page;
unsigned char button_0d_enabled;
unsigned char full_pm_cycle;
@@ -213,6 +218,8 @@
bool touch_stopped;
bool fingers_on_2d;
bool sensor_sleep;
+ bool flip_x;
+ bool flip_y;
wait_queue_head_t wait;
int (*i2c_read)(struct synaptics_rmi4_data *pdata, unsigned short addr,
unsigned char *data, unsigned short length);
diff --git a/drivers/input/touchscreen/synaptics_rmi_dev.c b/drivers/input/touchscreen/synaptics_rmi_dev.c
index 7f1aac5..c6b8a1c 100644
--- a/drivers/input/touchscreen/synaptics_rmi_dev.c
+++ b/drivers/input/touchscreen/synaptics_rmi_dev.c
@@ -619,6 +619,8 @@
}
}
+ init_completion(&remove_complete);
+
return 0;
err_sysfs_attrs:
diff --git a/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_common.c b/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_common.c
index 20db2fe..224b56c 100644
--- a/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_common.c
+++ b/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_common.c
@@ -4609,7 +4609,7 @@
}
MPQ_DVB_DBG_PRINT(
- "\n\n%s: Before SDMX_process: input read_offset=%u, fill count=%u\n",
+ "%s: Before SDMX_process: input read_offset=%u, fill count=%u\n",
__func__, read_offset, fill_count);
process_start_time = current_kernel_time();
@@ -4652,14 +4652,19 @@
int mpq_sdmx_process(struct mpq_demux *mpq_demux,
struct sdmx_buff_descr *input,
u32 fill_count,
- u32 read_offset)
+ u32 read_offset,
+ size_t tsp_size)
{
int ret;
int todo;
int total_bytes_read = 0;
- int limit = mpq_sdmx_proc_limit * mpq_demux->demux.ts_packet_size;
+ int limit = mpq_sdmx_proc_limit * tsp_size;
- while (fill_count >= mpq_demux->demux.ts_packet_size) {
+ MPQ_DVB_DBG_PRINT(
+ "\n\n%s: read_offset=%u, fill_count=%u, tsp_size=%u\n",
+ __func__, read_offset, fill_count, tsp_size);
+
+ while (fill_count >= tsp_size) {
todo = fill_count > limit ? limit : fill_count;
ret = mpq_sdmx_process_buffer(mpq_demux, input, todo,
read_offset);
@@ -4715,7 +4720,8 @@
buf_desc.size = rbuf->size;
read_offset = rbuf->pread;
- return mpq_sdmx_process(mpq_demux, &buf_desc, count, read_offset);
+ return mpq_sdmx_process(mpq_demux, &buf_desc, count,
+ read_offset, mpq_demux->demux.ts_packet_size);
}
int mpq_dmx_write(struct dmx_demux *demux, const char *buf, size_t count)
diff --git a/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_common.h b/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_common.h
index 8d2010b..8d6f52e 100644
--- a/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_common.h
+++ b/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_common.h
@@ -712,13 +712,15 @@
* @input: input buffer descriptor
* @fill_count: number of data bytes in input buffer that can be read
* @read_offset: offset in buffer for reading
+ * @tsp_size: size of single TS packet
*
* Return number of bytes read or error code
*/
int mpq_sdmx_process(struct mpq_demux *mpq_demux,
struct sdmx_buff_descr *input,
u32 fill_count,
- u32 read_offset);
+ u32 read_offset,
+ size_t tsp_size);
/**
* mpq_sdmx_loaded - Returns 1 if secure demux application is loaded,
diff --git a/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_tspp_v1.c b/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_tspp_v1.c
index 8ff3a85..4943bfb 100644
--- a/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_tspp_v1.c
+++ b/drivers/media/dvb/mpq/demux/mpq_dmx_plugin_tspp_v1.c
@@ -382,7 +382,8 @@
buff_current_addr_phys - buff_start_addr_phys);
mpq_sdmx_process(mpq_demux, &input, aggregate_len,
- buff_current_addr_phys - buff_start_addr_phys);
+ buff_current_addr_phys - buff_start_addr_phys,
+ TSPP_RAW_TTS_SIZE);
}
for (i = 0; i < aggregate_count; i++)
diff --git a/drivers/media/video/msm/msm_vpe.c b/drivers/media/video/msm/msm_vpe.c
index 41a4463..7427ae3 100644
--- a/drivers/media/video/msm/msm_vpe.c
+++ b/drivers/media/video/msm/msm_vpe.c
@@ -1015,6 +1015,7 @@
msm_mctl_unmap_user_frame(&frame_info->dest_frame,
frame_info->p_mctl->client, mctl->domain_num);
}
+ vpe_ctrl->pp_frame_info = NULL;
/* Drain the payload queue. */
msm_queue_drain(&vpe_ctrl->eventData_q, list_eventdata);
atomic_dec(&vpe_ctrl->active);
diff --git a/drivers/media/video/msm/sensors/ov8825_v4l2.c b/drivers/media/video/msm/sensors/ov8825_v4l2.c
index 9cff6a0..ab29530 100755
--- a/drivers/media/video/msm/sensors/ov8825_v4l2.c
+++ b/drivers/media/video/msm/sensors/ov8825_v4l2.c
@@ -248,6 +248,194 @@
{0x6900, 0x61}, /*CADC CTRL00*/
};
+static struct msm_camera_i2c_reg_conf ov8825_VGA_60fps_settings[] = {
+ {0x3003, 0xce},
+ {0x3004, 0xbf},
+ {0x3005, 0x10},
+ {0x3006, 0x00},
+ {0x3007, 0x3b},
+ {0x3012, 0x80},
+ {0x3013, 0x39},
+ {0x3106, 0x15},
+ {0x3600, 0x06},
+ {0x3601, 0x34},
+ {0x3602, 0x42},
+ {0x3700, 0x20},
+ {0x3702, 0x50},
+ {0x3703, 0xcc},
+ {0x3704, 0x19},
+ {0x3705, 0x32},
+ {0x3706, 0x4b},
+ {0x3708, 0x84},
+ {0x3709, 0x40},
+ {0x370a, 0xb2},
+ {0x370e, 0x08},
+ {0x3711, 0x0f},
+ {0x3712, 0x9c},
+ {0x3724, 0x01},
+ {0x3725, 0x92},
+ {0x3726, 0x01},
+ {0x3727, 0xc7},
+ {0x3800, 0x00},
+ {0x3801, 0x08},
+ {0x3802, 0x00},
+ {0x3803, 0x00},
+ {0x3804, 0x0c},
+ {0x3805, 0xd7},
+ {0x3806, 0x09},
+ {0x3807, 0x97},
+ {0x3808, 0x02},
+ {0x3809, 0x80},
+ {0x380a, 0x01},
+ {0x380b, 0xe0},
+ {0x380c, 0x14},
+ {0x380d, 0x88},
+ {0x380e, 0x02},
+ {0x380f, 0x7a},
+ {0x3810, 0x00},
+ {0x3811, 0x04},
+ {0x3812, 0x00},
+ {0x3813, 0x02},
+ {0x3814, 0x71},
+ {0x3815, 0x35},
+ {0x3820, 0x86},
+ {0x3821, 0x11},
+ {0x3f00, 0x00},
+ {0x4005, 0x18},
+ {0x404f, 0x8f},
+ {0x4600, 0x14},
+ {0x4601, 0x14},
+ {0x4602, 0x00},
+ {0x4837, 0x1e},
+ {0x5068, 0x59},
+ {0x506a, 0x5a},
+};
+
+static struct msm_camera_i2c_reg_conf ov8825_VGA_90fps_settings[] = {
+ {0x3003, 0xce},
+ {0x3004, 0xbf},
+ {0x3005, 0x10},
+ {0x3006, 0x00},
+ {0x3007, 0x3b},
+ {0x3012, 0x80},
+ {0x3013, 0x39},
+ {0x3106, 0x15},
+ {0x3600, 0x06},
+ {0x3601, 0x34},
+ {0x3602, 0x42},
+ {0x3700, 0x20},
+ {0x3702, 0x50},
+ {0x3703, 0xcc},
+ {0x3704, 0x19},
+ {0x3705, 0x32},
+ {0x3706, 0x4b},
+ {0x3708, 0x84},
+ {0x3709, 0x40},
+ {0x370a, 0xb2},
+ {0x370e, 0x08},
+ {0x3711, 0x0f},
+ {0x3712, 0x9c},
+ {0x3724, 0x01},
+ {0x3725, 0x92},
+ {0x3726, 0x01},
+ {0x3727, 0xc7},
+ {0x3800, 0x00},
+ {0x3801, 0x08},
+ {0x3802, 0x00},
+ {0x3803, 0x00},
+ {0x3804, 0x0c},
+ {0x3805, 0xd7},
+ {0x3806, 0x09},
+ {0x3807, 0x97},
+ {0x3808, 0x02},
+ {0x3809, 0x80},
+ {0x380a, 0x01},
+ {0x380b, 0xe0},
+ {0x380c, 0x0d},
+ {0x380d, 0xb0},
+ {0x380e, 0x02},
+ {0x380f, 0x7a},
+ {0x3810, 0x00},
+ {0x3811, 0x04},
+ {0x3812, 0x00},
+ {0x3813, 0x02},
+ {0x3814, 0x71},
+ {0x3815, 0x35},
+ {0x3820, 0x86},
+ {0x3821, 0x11},
+ {0x3f00, 0x00},
+ {0x4005, 0x18},
+ {0x404f, 0x8F},
+ {0x4600, 0x14},
+ {0x4601, 0x14},
+ {0x4602, 0x00},
+ {0x4837, 0x1e},
+ {0x5068, 0x59},
+ {0x506a, 0x5a},
+};
+
+static struct msm_camera_i2c_reg_conf ov8825_VGA_120fps_settings[] = {
+ {0x3003, 0xce},
+ {0x3004, 0xbf},
+ {0x3005, 0x10},
+ {0x3006, 0x00},
+ {0x3007, 0x3b},
+ {0x3012, 0x80},
+ {0x3013, 0x39},
+ {0x3106, 0x15},
+ {0x3600, 0x06},
+ {0x3601, 0x34},
+ {0x3602, 0x42},
+ {0x3700, 0x20},
+ {0x3702, 0x50},
+ {0x3703, 0xcc},
+ {0x3704, 0x19},
+ {0x3705, 0x32},
+ {0x3706, 0x4b},
+ {0x3708, 0x84},
+ {0x3709, 0x40},
+ {0x370a, 0xb2},
+ {0x370e, 0x08},
+ {0x3711, 0x0f},
+ {0x3712, 0x9c},
+ {0x3724, 0x01},
+ {0x3725, 0x92},
+ {0x3726, 0x01},
+ {0x3727, 0xc7},
+ {0x3800, 0x00},
+ {0x3801, 0x08},
+ {0x3802, 0x00},
+ {0x3803, 0x00},
+ {0x3804, 0x0c},
+ {0x3805, 0xd7},
+ {0x3806, 0x09},
+ {0x3807, 0x97},
+ {0x3808, 0x02},
+ {0x3809, 0x80},
+ {0x380a, 0x01},
+ {0x380b, 0xe0},
+ {0x380c, 0x0a},
+ {0x380d, 0x44},
+ {0x380e, 0x02},
+ {0x380f, 0x7a},
+ {0x3810, 0x00},
+ {0x3811, 0x04},
+ {0x3812, 0x00},
+ {0x3813, 0x02},
+ {0x3814, 0x71},
+ {0x3815, 0x35},
+ {0x3820, 0x86},
+ {0x3821, 0x11},
+ {0x3f00, 0x00},
+ {0x4005, 0x18},
+ {0x404f, 0x8F},
+ {0x4600, 0x14},
+ {0x4601, 0x14},
+ {0x4602, 0x00},
+ {0x4837, 0x1e},
+ {0x5068, 0x59},
+ {0x506a, 0x5a},
+};
static struct msm_camera_i2c_reg_conf ov8825_recommend_settings[] = {
{0x3000, 0x16},
@@ -527,9 +715,23 @@
static struct msm_camera_i2c_conf_array ov8825_confs[] = {
{&ov8825_snap_settings[0],
- ARRAY_SIZE(ov8825_snap_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
+ ARRAY_SIZE(ov8825_snap_settings),
+ 0, MSM_CAMERA_I2C_BYTE_DATA},
{&ov8825_prev_settings[0],
- ARRAY_SIZE(ov8825_prev_settings), 0, MSM_CAMERA_I2C_BYTE_DATA},
+ ARRAY_SIZE(ov8825_prev_settings),
+ 0, MSM_CAMERA_I2C_BYTE_DATA},
+ {&ov8825_VGA_60fps_settings[0],
+ ARRAY_SIZE(ov8825_VGA_60fps_settings),
+ 0, MSM_CAMERA_I2C_BYTE_DATA},
+ {&ov8825_VGA_90fps_settings[0],
+ ARRAY_SIZE(ov8825_VGA_90fps_settings),
+ 0, MSM_CAMERA_I2C_BYTE_DATA},
+ {&ov8825_VGA_120fps_settings[0],
+ ARRAY_SIZE(ov8825_VGA_120fps_settings),
+ 0, MSM_CAMERA_I2C_BYTE_DATA},
+ {&ov8825_snap_settings[0],
+ ARRAY_SIZE(ov8825_snap_settings),
+ 0, MSM_CAMERA_I2C_BYTE_DATA},
};
static struct msm_sensor_output_info_t ov8825_dimensions[] = {
@@ -560,6 +762,36 @@
.binning_factor = 2,
},
+ /* VGA 60fps */
+ {
+ .x_output = 640,
+ .y_output = 480,
+ .line_length_pclk = 0x1488,
+ .frame_length_lines = 0x27a,
+ .vt_pixel_clk = 200000000,
+ .op_pixel_clk = 211200000,
+ .binning_factor = 0,
+ },
+ /* VGA 90fps */
+ {
+ .x_output = 640,
+ .y_output = 480,
+ .line_length_pclk = 0xdb0,
+ .frame_length_lines = 0x27a,
+ .vt_pixel_clk = 200000000,
+ .op_pixel_clk = 211200000,
+ .binning_factor = 0,
+ },
+ /* VGA 120fps */
+ {
+ .x_output = 640,
+ .y_output = 480,
+ .line_length_pclk = 0xa44,
+ .frame_length_lines = 0x27a,
+ .vt_pixel_clk = 200000000,
+ .op_pixel_clk = 211200000,
+ .binning_factor = 0,
+ },
};
static struct msm_sensor_output_reg_addr_t ov8825_reg_addr = {
diff --git a/drivers/media/video/msm/sensors/ov9724_v4l2.c b/drivers/media/video/msm/sensors/ov9724_v4l2.c
index 8988197..d015972 100644
--- a/drivers/media/video/msm/sensors/ov9724_v4l2.c
+++ b/drivers/media/video/msm/sensors/ov9724_v4l2.c
@@ -79,6 +79,7 @@
{0x5000, 0x06},
{0x5001, 0x73},
{0x0205, 0x3f},
+ {0x0101, 0x02}, /*Flip*/
{0x0100, 0x01},
};
diff --git a/drivers/media/video/msm/server/msm_cam_server.c b/drivers/media/video/msm/server/msm_cam_server.c
index 47cd7b0..e1f111f 100644
--- a/drivers/media/video/msm/server/msm_cam_server.c
+++ b/drivers/media/video/msm/server/msm_cam_server.c
@@ -448,8 +448,11 @@
} while (1);
D("Waiting is over for config status\n");
if (list_empty_careful(&queue->list)) {
- if (!rc)
+ if (!rc) {
rc = -ETIMEDOUT;
+ msm_drain_eventq(
+ &server_dev->server_queue[out->queue_idx].eventData_q);
+ }
if (rc < 0) {
if (++server_dev->server_evt_id == 0)
server_dev->server_evt_id++;
@@ -486,6 +489,7 @@
return rc;
ctrlcmd_alloc_fail:
+ mutex_unlock(&server_dev->server_queue_lock);
kfree(isp_event);
isp_event_alloc_fail:
kfree(event_qcmd);
@@ -2737,6 +2741,7 @@
return rc;
ctrlcmd_alloc_fail:
+ mutex_unlock(&server_dev->server_queue_lock);
kfree(isp_event);
isp_event_alloc_fail:
kfree(event_qcmd);
diff --git a/drivers/media/video/msm_wfd/enc-mfc-subdev.c b/drivers/media/video/msm_wfd/enc-mfc-subdev.c
index 9c91690..b271aa4 100644
--- a/drivers/media/video/msm_wfd/enc-mfc-subdev.c
+++ b/drivers/media/video/msm_wfd/enc-mfc-subdev.c
@@ -1420,7 +1420,7 @@
if (!client_ctx)
return -EINVAL;
if (inst->framerate_mode == VENC_MODE_VFR) {
- WFD_MSG_ERR("VUI timing info not suported in VFR mode ");
+ WFD_MSG_INFO("VUI timing info not suported in VFR mode ");
return -EINVAL;
}
vcd_property_hdr.prop_id = VCD_I_ENABLE_VUI_TIMING_INFO;
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index 56d5d9f..ce2ea5f 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -57,7 +57,7 @@
#define INAND_CMD38_ARG_SECERASE 0x80
#define INAND_CMD38_ARG_SECTRIM1 0x81
#define INAND_CMD38_ARG_SECTRIM2 0x88
-#define MMC_BLK_TIMEOUT_MS (10 * 60 * 1000) /* 10 minute timeout */
+#define MMC_BLK_TIMEOUT_MS (30 * 1000) /* 30 sec timeout */
#define MMC_SANITIZE_REQ_TIMEOUT 240000 /* msec */
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 881c7f2..4abe684 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -2657,10 +2657,6 @@
if (mmc_bus_needs_resume(host))
return 0;
- if (cancel_delayed_work(&host->detect))
- wake_unlock(&host->detect_wake_lock);
- mmc_flush_scheduled_work();
-
mmc_bus_get(host);
if (host->bus_ops && !host->bus_dead) {
/*
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c
index 9a7af35..fbd12b8 100644
--- a/drivers/mmc/host/msm_sdcc.c
+++ b/drivers/mmc/host/msm_sdcc.c
@@ -1140,9 +1140,16 @@
data_cnt = SPS_MAX_DESC_SIZE;
} else {
data_cnt = len;
- if (i == data->sg_len - 1)
+ if ((i == data->sg_len - 1) &&
+ (sps_pipe_handle ==
+ host->sps.cons.pipe_handle)) {
+ /*
+ * set EOT only for consumer pipe, for
+ * producer pipe h/w will set it.
+ */
flags = SPS_IOVEC_FLAG_INT |
SPS_IOVEC_FLAG_EOT;
+ }
}
rc = sps_transfer_one(sps_pipe_handle, addr,
data_cnt, host, flags);
diff --git a/drivers/power/pm8921-charger.c b/drivers/power/pm8921-charger.c
index a3b7bbf..e00e1c3 100644
--- a/drivers/power/pm8921-charger.c
+++ b/drivers/power/pm8921-charger.c
@@ -4603,12 +4603,12 @@
int rc;
struct pm8921_chg_chip *chip = dev_get_drvdata(dev);
- pm8921_chg_force_19p2mhz_clk(chip);
-
rc = pm8921_chg_set_lpm(chip, 0);
if (rc)
pr_err("Failed to set lpm rc=%d\n", rc);
+ pm8921_chg_force_19p2mhz_clk(chip);
+
rc = pm_chg_masked_write(chip, CHG_CNTRL, VREF_BATT_THERM_FORCE_ON,
VREF_BATT_THERM_FORCE_ON);
if (rc)
diff --git a/drivers/spi/spi_qsd.c b/drivers/spi/spi_qsd.c
index 5ba244f..5347add 100644
--- a/drivers/spi/spi_qsd.c
+++ b/drivers/spi/spi_qsd.c
@@ -126,13 +126,72 @@
}
}
+/**
+ * msm_spi_clk_max_rate: finds the nearest lower rate for a clk
+ * @clk the clock for which to find nearest lower rate
+ * @rate clock frequency in Hz
+ * @return nearest lower rate or negative error value
+ *
+ * Public clock API extends clk_round_rate which is a ceiling function. This
+ * function is a floor function implemented as a binary search using the
+ * ceiling function.
+ */
+static long msm_spi_clk_max_rate(struct clk *clk, unsigned long rate)
+{
+ long lowest_available, nearest_low, step_size, cur;
+ long step_direction = -1;
+ long guess = rate;
+ int max_steps = 10;
+
+ cur = clk_round_rate(clk, rate);
+ if (cur == rate)
+ return rate;
+
+ /* if we got here then: cur > rate */
+ lowest_available = clk_round_rate(clk, 0);
+ if (lowest_available > rate)
+ return -EINVAL;
+
+ step_size = (rate - lowest_available) >> 1;
+ nearest_low = lowest_available;
+
+ while (max_steps-- && step_size) {
+ guess += step_size * step_direction;
+
+ cur = clk_round_rate(clk, guess);
+
+ if ((cur < rate) && (cur > nearest_low))
+ nearest_low = cur;
+
+ /*
+ * if we stepped too far, then start stepping in the other
+ * direction with half the step size
+ */
+ if (((cur > rate) && (step_direction > 0))
+ || ((cur < rate) && (step_direction < 0))) {
+ step_direction = -step_direction;
+ step_size >>= 1;
+ }
+ }
+ return nearest_low;
+}
+
static void msm_spi_clock_set(struct msm_spi *dd, int speed)
{
+ long rate;
int rc;
- rc = clk_set_rate(dd->clk, speed);
+ rate = msm_spi_clk_max_rate(dd->clk, speed);
+ if (rate < 0) {
+ dev_err(dd->dev,
+ "%s: no match found for requested clock frequency:%d",
+ __func__, speed);
+ return;
+ }
+
+ rc = clk_set_rate(dd->clk, rate);
if (!rc)
- dd->clock_speed = speed;
+ dd->clock_speed = rate;
}
static int msm_spi_calculate_size(int *fifo_size,
@@ -970,7 +1029,7 @@
}
if (tr->cs_change &&
- ((bpw != 8) || (bpw != 16) || (bpw != 32)))
+ ((bpw != 8) && (bpw != 16) && (bpw != 32)))
return 0;
return 1;
}
diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c
index 85ed6cf..b89799a 100644
--- a/drivers/staging/android/binder.c
+++ b/drivers/staging/android/binder.c
@@ -2548,14 +2548,38 @@
struct binder_transaction *t;
t = container_of(w, struct binder_transaction, work);
- if (t->buffer->target_node && !(t->flags & TF_ONE_WAY))
+ if (t->buffer->target_node &&
+ !(t->flags & TF_ONE_WAY)) {
binder_send_failed_reply(t, BR_DEAD_REPLY);
+ } else {
+ binder_debug(BINDER_DEBUG_DEAD_TRANSACTION,
+ "binder: undelivered transaction %d\n",
+ t->debug_id);
+ t->buffer->transaction = NULL;
+ kfree(t);
+ binder_stats_deleted(BINDER_STAT_TRANSACTION);
+ }
} break;
case BINDER_WORK_TRANSACTION_COMPLETE: {
+ binder_debug(BINDER_DEBUG_DEAD_TRANSACTION,
+ "binder: undelivered TRANSACTION_COMPLETE\n");
kfree(w);
binder_stats_deleted(BINDER_STAT_TRANSACTION_COMPLETE);
} break;
+ case BINDER_WORK_DEAD_BINDER_AND_CLEAR:
+ case BINDER_WORK_CLEAR_DEATH_NOTIFICATION: {
+ struct binder_ref_death *death;
+
+ death = container_of(w, struct binder_ref_death, work);
+ binder_debug(BINDER_DEBUG_DEAD_TRANSACTION,
+ "binder: undelivered death notification, %p\n",
+ death->cookie);
+ kfree(death);
+ binder_stats_deleted(BINDER_STAT_DEATH);
+ } break;
default:
+ pr_err("binder: unexpected work type, %d, not freed\n",
+ w->type);
break;
}
}
@@ -3036,6 +3060,7 @@
nodes++;
rb_erase(&node->rb_node, &proc->nodes);
list_del_init(&node->work.entry);
+ binder_release_work(&node->async_todo);
if (hlist_empty(&node->refs)) {
kfree(node);
binder_stats_deleted(BINDER_STAT_NODE);
@@ -3074,6 +3099,7 @@
binder_delete_ref(ref);
}
binder_release_work(&proc->todo);
+ binder_release_work(&proc->delivered_death);
buffers = 0;
while ((n = rb_first(&proc->allocated_buffers))) {
diff --git a/drivers/staging/ste_rmi4/Kconfig b/drivers/staging/ste_rmi4/Kconfig
index e867950..6570368 100644
--- a/drivers/staging/ste_rmi4/Kconfig
+++ b/drivers/staging/ste_rmi4/Kconfig
@@ -1,9 +1,12 @@
-config TOUCHSCREEN_SYNAPTICS_I2C_RMI4
- tristate "Synaptics i2c rmi4 touchscreen"
+config TOUCHSCREEN_SYNAPTICS_I2C_RMI4_STAGING
+ tristate "Synaptics i2c rmi4 touchscreen staging"
depends on I2C && INPUT
help
Say Y here if you have a Synaptics RMI4 and
- want to enable support for the built-in touchscreen.
+ want to enable support for the built-in touchscreen
+ through staging driver. Not to be confused with
+ TOUCHSCREEN_SYNAPTICS_I2C_RMI4 in
+ drivers/input/touchscreen directory.
To compile this driver as a module, choose M here: the
module will be called synaptics_rmi4_ts.
diff --git a/drivers/staging/ste_rmi4/Makefile b/drivers/staging/ste_rmi4/Makefile
index e4c0335..ee9a53e 100644
--- a/drivers/staging/ste_rmi4/Makefile
+++ b/drivers/staging/ste_rmi4/Makefile
@@ -1,5 +1,6 @@
#
# Makefile for the RMI4 touchscreen driver.
#
-obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4) += synaptics_i2c_rmi4.o
+obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4_STAGING) \
+ += synaptics_i2c_rmi4_staging.o
obj-$(CONFIG_MACH_MOP500) += board-mop500-u8500uib-rmi4.o
diff --git a/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c b/drivers/staging/ste_rmi4/synaptics_i2c_rmi4_staging.c
similarity index 99%
rename from drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c
rename to drivers/staging/ste_rmi4/synaptics_i2c_rmi4_staging.c
index 11728a0..43115c3 100644
--- a/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c
+++ b/drivers/staging/ste_rmi4/synaptics_i2c_rmi4_staging.c
@@ -31,7 +31,7 @@
#include <linux/interrupt.h>
#include <linux/regulator/consumer.h>
#include <linux/module.h>
-#include "synaptics_i2c_rmi4.h"
+#include "synaptics_i2c_rmi4_staging.h"
/* TODO: for multiple device support will need a per-device mutex */
#define DRIVER_NAME "synaptics_rmi4_i2c"
diff --git a/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.h b/drivers/staging/ste_rmi4/synaptics_i2c_rmi4_staging.h
similarity index 100%
rename from drivers/staging/ste_rmi4/synaptics_i2c_rmi4.h
rename to drivers/staging/ste_rmi4/synaptics_i2c_rmi4_staging.h
diff --git a/drivers/tty/serial/msm_serial_hs.c b/drivers/tty/serial/msm_serial_hs.c
index 7d58e3f..be56a0c 100644
--- a/drivers/tty/serial/msm_serial_hs.c
+++ b/drivers/tty/serial/msm_serial_hs.c
@@ -42,6 +42,7 @@
#include <linux/ioport.h>
#include <linux/kernel.h>
#include <linux/timer.h>
+#include <linux/delay.h>
#include <linux/clk.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
@@ -181,6 +182,7 @@
bool tty_flush_receive;
bool rx_discard_flush_issued;
enum uart_func_mode func_mode;
+ bool is_shutdown;
};
#define MSM_UARTDM_BURST_SIZE 16 /* DM burst size (in bytes) */
@@ -195,6 +197,7 @@
static struct platform_driver msm_serial_hs_platform_driver;
static struct uart_driver msm_hs_driver;
static struct uart_ops msm_hs_ops;
+static void msm_hs_start_rx_locked(struct uart_port *uport);
#define UARTDM_TO_MSM(uart_port) \
container_of((uart_port), struct msm_hs_port, uport)
@@ -734,13 +737,6 @@
data |= UARTDM_IPR_STALE_TIMEOUT_MSB_BMSK & (rxstale << 2);
msm_hs_write(uport, UARTDM_IPR_ADDR, data);
- /*
- * It is suggested to do reset of transmitter and receiver after
- * changing any protocol configuration. Here Baud rate and stale
- * timeout are getting updated. Hence reset transmitter and receiver.
- */
- msm_hs_write(uport, UARTDM_CR_ADDR, RESET_TX);
- msm_hs_write(uport, UARTDM_CR_ADDR, RESET_RX);
return flags;
}
@@ -904,9 +900,6 @@
/* Set Transmit software time out */
uart_update_timeout(uport, c_cflag, bps);
- msm_hs_write(uport, UARTDM_CR_ADDR, RESET_RX);
- msm_hs_write(uport, UARTDM_CR_ADDR, RESET_TX);
-
if (msm_uport->rx.flush == FLUSH_NONE) {
wake_lock(&msm_uport->rx.wake_lock);
msm_uport->rx.flush = FLUSH_IGNORE;
@@ -920,18 +913,26 @@
/* do discard flush */
msm_dmov_flush(msm_uport->dma_rx_channel, 0);
spin_unlock_irqrestore(&uport->lock, flags);
- pr_debug("%s(): wainting for flush completion.\n",
- __func__);
ret = wait_event_timeout(msm_uport->rx.wait,
msm_uport->rx_discard_flush_issued == false,
RX_FLUSH_COMPLETE_TIMEOUT);
if (!ret)
- pr_err("%s(): Discard flush completion pending.\n",
- __func__);
+ pr_err("%s(): dmov flush callback timed out\n",
+ __func__);
spin_lock_irqsave(&uport->lock, flags);
}
- msm_hs_write(uport, UARTDM_IMR_ADDR, msm_uport->imr_reg);
+ /* After baudrate changes, should perform RX and TX reset */
+ msm_hs_write(uport, UARTDM_CR_ADDR, (RESET_RX | RESET_TX));
+ /*
+ * Rx and Tx reset operation takes few clock cycles, hence as
+ * safe side adding 10us delay.
+ */
+ udelay(10);
+
+ /* Initiate new Rx transfer */
+ msm_hs_start_rx_locked(&msm_uport->uport);
+
mb();
spin_unlock_irqrestore(&uport->lock, flags);
mutex_unlock(&msm_uport->clk_mutex);
@@ -1008,6 +1009,9 @@
struct msm_hs_tx *tx = &msm_uport->tx;
struct circ_buf *tx_buf = &msm_uport->uport.state->xmit;
+ if (tx->dma_in_flight || msm_uport->is_shutdown)
+ return;
+
if (uart_circ_empty(tx_buf) || uport->state->port.tty->stopped) {
msm_hs_stop_tx_locked(uport);
return;
@@ -1214,14 +1218,26 @@
if (msm_uport->clk_req_off_state == CLK_REQ_OFF_FLUSH_ISSUED)
msm_uport->clk_req_off_state = CLK_REQ_OFF_RXSTALE_FLUSHED;
flush = msm_uport->rx.flush;
- if (flush == FLUSH_IGNORE)
- if (!msm_uport->rx.buffer_pending)
- msm_hs_start_rx_locked(uport);
+ /* Part of set_termios sets the flush as FLUSH_IGNORE */
+ if (flush == FLUSH_IGNORE) {
+ if (!msm_uport->rx_discard_flush_issued &&
+ !msm_uport->rx.buffer_pending) {
+ msm_hs_start_rx_locked(uport);
+ } else {
+ msm_uport->rx_discard_flush_issued = false;
+ wake_up(&msm_uport->rx.wait);
+ }
+ }
+
+ /* Part of stop_rx sets the flush as FLUSH_STOP */
if (flush == FLUSH_STOP) {
+ if (msm_uport->rx_discard_flush_issued)
+ msm_uport->rx_discard_flush_issued = false;
msm_uport->rx.flush = FLUSH_SHUTDOWN;
wake_up(&msm_uport->rx.wait);
}
+
if (flush >= FLUSH_DATA_INVALID)
goto out;
@@ -1269,6 +1285,9 @@
{
struct msm_hs_port *msm_uport = UARTDM_TO_MSM(uport);
+ if (msm_uport->is_shutdown)
+ return;
+
if (msm_uport->tx.tx_ready_int_en == 0) {
msm_uport->tx.tx_ready_int_en = 1;
if (msm_uport->tx.dma_in_flight == 0)
@@ -1305,8 +1324,11 @@
unsigned long flags;
struct msm_hs_port *msm_uport = container_of((struct tasklet_struct *)
tlet_ptr, struct msm_hs_port, tx.tlet);
+ struct msm_hs_tx *tx = &msm_uport->tx;
spin_lock_irqsave(&(msm_uport->uport.lock), flags);
+
+ tx->dma_in_flight = 0;
if (msm_uport->tx.flush == FLUSH_STOP) {
msm_uport->tx.flush = FLUSH_SHUTDOWN;
wake_up(&msm_uport->tx.wait);
@@ -1334,23 +1356,11 @@
struct msm_dmov_errdata *err)
{
struct msm_hs_port *msm_uport;
- struct uart_port *uport;
- unsigned long flags;
+
+ if (result & DMOV_RSLT_ERROR)
+ pr_err("%s(): DMOV_RSLT_ERROR\n", __func__);
msm_uport = container_of(cmd_ptr, struct msm_hs_port, rx.xfer);
- uport = &(msm_uport->uport);
-
- pr_debug("%s(): called result:%x\n", __func__, result);
- if (!(result & DMOV_RSLT_ERROR)) {
- if (result & DMOV_RSLT_FLUSH) {
- if (msm_uport->rx_discard_flush_issued) {
- spin_lock_irqsave(&uport->lock, flags);
- msm_uport->rx_discard_flush_issued = false;
- spin_unlock_irqrestore(&uport->lock, flags);
- wake_up(&msm_uport->rx.wait);
- }
- }
- }
tasklet_schedule(&msm_uport->rx.tlet);
}
@@ -1620,6 +1630,11 @@
spin_lock_irqsave(&uport->lock, flags);
+ if (msm_uport->is_shutdown) {
+ spin_unlock_irqrestore(&uport->lock, flags);
+ return IRQ_HANDLED;
+ }
+
isr_status = msm_hs_read(uport, UARTDM_MISR_ADDR);
/* Uart RX starting */
@@ -1674,8 +1689,6 @@
else
msm_uport->tty_flush_receive = false;
- tx->dma_in_flight = 0;
-
uport->icount.tx += tx->tx_count;
if (tx->tx_ready_int_en)
msm_hs_submit_tx_locked(uport);
@@ -1844,6 +1857,8 @@
struct circ_buf *tx_buf = &uport->state->xmit;
struct msm_hs_tx *tx = &msm_uport->tx;
+ msm_uport->is_shutdown = false;
+
rfr_level = uport->fifosize;
if (rfr_level > 16)
rfr_level -= 16;
@@ -1887,9 +1902,15 @@
data = UARTDM_TX_DM_EN_BMSK | UARTDM_RX_DM_EN_BMSK;
msm_hs_write(uport, UARTDM_DMEN_ADDR, data);
- /* Reset TX */
- msm_hs_write(uport, UARTDM_CR_ADDR, RESET_TX);
- msm_hs_write(uport, UARTDM_CR_ADDR, RESET_RX);
+
+ /* Reset both RX and TX HW state machine */
+ msm_hs_write(uport, UARTDM_CR_ADDR, (RESET_RX | RESET_TX));
+ /*
+ * Rx and Tx reset operation takes few clock cycles, hence as
+ * safe side adding 10us delay.
+ */
+ udelay(10);
+
msm_hs_write(uport, UARTDM_CR_ADDR, RESET_ERROR_STATUS);
msm_hs_write(uport, UARTDM_CR_ADDR, RESET_BREAK_INT);
msm_hs_write(uport, UARTDM_CR_ADDR, RESET_STALE_INT);
@@ -1962,9 +1983,7 @@
msm_hs_start_rx_locked(uport);
spin_unlock_irqrestore(&uport->lock, flags);
- ret = pm_runtime_set_active(uport->dev);
- if (ret)
- dev_err(uport->dev, "set active error:%d\n", ret);
+
pm_runtime_enable(uport->dev);
return 0;
@@ -2324,27 +2343,31 @@
const struct msm_serial_hs_platform_data *pdata =
pdev->dev.platform_data;
+
+ spin_lock_irqsave(&uport->lock, flags);
+ /* Disable all UART interrupts */
+ msm_uport->imr_reg = 0;
+ msm_hs_write(uport, UARTDM_IMR_ADDR, msm_uport->imr_reg);
+ msm_uport->is_shutdown = true;
+ /* disable UART TX interface to DM */
+ data = msm_hs_read(uport, UARTDM_DMEN_ADDR);
+ data &= ~UARTDM_TX_DM_EN_BMSK;
+ msm_hs_write(uport, UARTDM_DMEN_ADDR, data);
+ mb();
+
if (msm_uport->tx.dma_in_flight) {
- spin_lock_irqsave(&uport->lock, flags);
- /* disable UART TX interface to DM */
- data = msm_hs_read(uport, UARTDM_DMEN_ADDR);
- data &= ~UARTDM_TX_DM_EN_BMSK;
- msm_hs_write(uport, UARTDM_DMEN_ADDR, data);
- /* turn OFF UART Transmitter */
- msm_hs_write(uport, UARTDM_CR_ADDR, UARTDM_CR_TX_DISABLE_BMSK);
- /* reset UART TX */
- msm_hs_write(uport, UARTDM_CR_ADDR, RESET_TX);
- /* reset UART TX Error */
- msm_hs_write(uport, UARTDM_CR_ADDR, RESET_TX_ERROR);
msm_uport->tx.flush = FLUSH_STOP;
- spin_unlock_irqrestore(&uport->lock, flags);
/* discard flush */
msm_dmov_flush(msm_uport->dma_tx_channel, 0);
+ spin_unlock_irqrestore(&uport->lock, flags);
ret = wait_event_timeout(msm_uport->tx.wait,
msm_uport->tx.flush == FLUSH_SHUTDOWN, 100);
if (!ret)
pr_err("%s():HSUART TX Stalls.\n", __func__);
+ } else {
+ spin_unlock_irqrestore(&uport->lock, flags);
}
+
tasklet_kill(&msm_uport->tx.tlet);
BUG_ON(msm_uport->rx.flush < FLUSH_STOP);
wait_event(msm_uport->rx.wait, msm_uport->rx.flush == FLUSH_SHUTDOWN);
@@ -2352,15 +2375,12 @@
cancel_delayed_work_sync(&msm_uport->rx.flip_insert_work);
flush_workqueue(msm_uport->hsuart_wq);
pm_runtime_disable(uport->dev);
- pm_runtime_set_suspended(uport->dev);
/* Disable the transmitter */
msm_hs_write(uport, UARTDM_CR_ADDR, UARTDM_CR_TX_DISABLE_BMSK);
/* Disable the receiver */
msm_hs_write(uport, UARTDM_CR_ADDR, UARTDM_CR_RX_DISABLE_BMSK);
- msm_uport->imr_reg = 0;
- msm_hs_write(uport, UARTDM_IMR_ADDR, msm_uport->imr_reg);
/*
* Complete all device write before actually disabling uartclk.
* Hence mb() requires here.
diff --git a/drivers/usb/gadget/android.c b/drivers/usb/gadget/android.c
index 52ea9e1..6fe4426 100644
--- a/drivers/usb/gadget/android.c
+++ b/drivers/usb/gadget/android.c
@@ -949,8 +949,24 @@
}
static DEVICE_ATTR(acm_transports, S_IWUSR, NULL, acm_transports_store);
+
+/*enabled ACM transport names - "serial_hsic[,serial_hsusb]"*/
+static char acm_xport_names[32];
+static ssize_t acm_xport_names_store(
+ struct device *device, struct device_attribute *attr,
+ const char *buff, size_t size)
+{
+ strlcpy(acm_xport_names, buff, sizeof(acm_xport_names));
+
+ return size;
+}
+
+static DEVICE_ATTR(acm_transport_names, S_IWUSR, NULL, acm_xport_names_store);
+
static struct device_attribute *acm_function_attributes[] = {
- &dev_attr_acm_transports, NULL };
+ &dev_attr_acm_transports,
+ &dev_attr_acm_transport_names,
+ NULL };
static void acm_function_cleanup(struct android_usb_function *f)
{
@@ -960,8 +976,8 @@
static int acm_function_bind_config(struct android_usb_function *f,
struct usb_configuration *c)
{
- char *name;
- char buf[32], *b;
+ char *name, *xport_name = NULL;
+ char buf[32], *b, xport_name_buf[32], *tb;
int err = -1, i;
static int acm_initialized, ports;
@@ -972,11 +988,16 @@
strlcpy(buf, acm_transports, sizeof(buf));
b = strim(buf);
+ strlcpy(xport_name_buf, acm_xport_names, sizeof(xport_name_buf));
+ tb = strim(xport_name_buf);
+
while (b) {
name = strsep(&b, ",");
if (name) {
- err = acm_init_port(ports, name);
+ if (tb)
+ xport_name = strsep(&tb, ",");
+ err = acm_init_port(ports, name, xport_name);
if (err) {
pr_err("acm: Cannot open port '%s'", name);
goto out;
diff --git a/drivers/usb/gadget/f_acm.c b/drivers/usb/gadget/f_acm.c
index ea6d0bd..e4e81fa 100644
--- a/drivers/usb/gadget/f_acm.c
+++ b/drivers/usb/gadget/f_acm.c
@@ -986,7 +986,7 @@
/**
* acm_init_port - bind a acm_port to its transport
*/
-static int acm_init_port(int port_num, const char *name)
+static int acm_init_port(int port_num, const char *name, const char *port_name)
{
enum transport_type transport;
@@ -1014,6 +1014,9 @@
no_acm_smd_ports++;
break;
case USB_GADGET_XPORT_HSIC:
+ ghsic_ctrl_set_port_name(port_name, name);
+ ghsic_data_set_port_name(port_name, name);
+
/*client port number will be updated in acm_port_setup*/
no_acm_hsic_sports++;
break;
diff --git a/drivers/usb/gadget/f_diag.c b/drivers/usb/gadget/f_diag.c
index a2ee182..3ba5916 100644
--- a/drivers/usb/gadget/f_diag.c
+++ b/drivers/usb/gadget/f_diag.c
@@ -96,9 +96,6 @@
* @out_desc: USB OUT endpoint descriptor struct
* @read_pool: List of requests used for Rx (OUT ep)
* @write_pool: List of requests used for Tx (IN ep)
- * @config_work: Work item schedule after interface is configured to notify
- * CONNECT event to diag char driver and updating product id
- * and serial number to MODEM/IMEM.
* @lock: Spinlock to proctect read_pool, write_pool lists
* @cdev: USB composite device struct
* @ch: USB diag channel
@@ -110,7 +107,6 @@
struct usb_ep *in;
struct list_head read_pool;
struct list_head write_pool;
- struct work_struct config_work;
spinlock_t lock;
unsigned configured;
struct usb_composite_dev *cdev;
@@ -128,17 +124,12 @@
return container_of(f, struct diag_context, function);
}
-static void usb_config_work_func(struct work_struct *work)
+static void diag_update_pid_and_serial_num(struct diag_context *ctxt)
{
- struct diag_context *ctxt = container_of(work,
- struct diag_context, config_work);
struct usb_composite_dev *cdev = ctxt->cdev;
struct usb_gadget_strings *table;
struct usb_string *s;
- if (ctxt->ch.notify)
- ctxt->ch.notify(ctxt->ch.priv, USB_DIAG_CONNECT, NULL);
-
if (!ctxt->update_pid_and_serial_num)
return;
@@ -553,7 +544,6 @@
usb_ep_disable(dev->in);
return rc;
}
- schedule_work(&dev->config_work);
dev->dpkts_tolaptop = 0;
dev->dpkts_tomodem = 0;
@@ -563,6 +553,9 @@
dev->configured = 1;
spin_unlock_irqrestore(&dev->lock, flags);
+ if (dev->ch.notify)
+ dev->ch.notify(dev->ch.priv, USB_DIAG_CONNECT, NULL);
+
return rc;
}
@@ -614,6 +607,7 @@
/* copy descriptors, and track endpoint copies */
f->hs_descriptors = usb_copy_descriptors(hs_diag_desc);
}
+ diag_update_pid_and_serial_num(ctxt);
return 0;
fail:
if (ctxt->out)
@@ -660,7 +654,6 @@
spin_lock_init(&dev->lock);
INIT_LIST_HEAD(&dev->read_pool);
INIT_LIST_HEAD(&dev->write_pool);
- INIT_WORK(&dev->config_work, usb_config_work_func);
ret = usb_add_function(c, &dev->function);
if (ret) {
diff --git a/drivers/video/msm/mdp4_overlay.c b/drivers/video/msm/mdp4_overlay.c
index 9735f83..4369691 100644
--- a/drivers/video/msm/mdp4_overlay.c
+++ b/drivers/video/msm/mdp4_overlay.c
@@ -3057,6 +3057,7 @@
u64 ab_quota_total = 0, ib_quota_total = 0;
u64 ab_quota_port0 = 0, ib_quota_port0 = 0;
u64 ab_quota_port1 = 0, ib_quota_port1 = 0;
+ u64 ib_quota_min = 0;
if (!mfd) {
pr_err("%s: mfd is null!\n", __func__);
@@ -3095,6 +3096,12 @@
ab_quota_port0 += pipe->bw_ab_quota;
ib_quota_port0 += pipe->bw_ib_quota;
}
+ } else {
+ if (ib_quota_min == 0)
+ ib_quota_min = pipe->bw_ib_quota;
+ else
+ ib_quota_min = min(ib_quota_min,
+ pipe->bw_ib_quota);
}
if (mfd->mdp_rev == MDP_REV_41) {
/*
@@ -3144,6 +3151,8 @@
}
}
+ ib_quota_total = max(ib_quota_total, ib_quota_min);
+
perf_req->mdp_ab_bw = roundup(ab_quota_total, MDP_BUS_SCALE_AB_STEP);
perf_req->mdp_ib_bw = roundup(ib_quota_total, MDP_BUS_SCALE_AB_STEP);
diff --git a/drivers/video/msm/mdp4_overlay_dsi_video.c b/drivers/video/msm/mdp4_overlay_dsi_video.c
index 4311a6d..2fe2ba7 100644
--- a/drivers/video/msm/mdp4_overlay_dsi_video.c
+++ b/drivers/video/msm/mdp4_overlay_dsi_video.c
@@ -217,18 +217,6 @@
}
spin_unlock_irqrestore(&vctrl->spin_lock, flags);
- if (vctrl->blt_change) {
- pipe = vctrl->base_pipe;
- spin_lock_irqsave(&vctrl->spin_lock, flags);
- INIT_COMPLETION(vctrl->dmap_comp);
- INIT_COMPLETION(vctrl->ov_comp);
- vsync_irq_enable(INTR_DMA_P_DONE, MDP_DMAP_TERM);
- spin_unlock_irqrestore(&vctrl->spin_lock, flags);
- mdp4_dsi_video_wait4dmap(0);
- if (pipe->ov_blt_addr)
- mdp4_dsi_video_wait4ov(0);
- }
-
pipe = vp->plist;
for (i = 0; i < OVERLAY_PIPE_MAX; i++, pipe++) {
@@ -1096,17 +1084,6 @@
if (vctrl->blt_change) {
mdp4_overlayproc_cfg(pipe);
mdp4_overlay_dmap_xy(pipe);
- if (pipe->ov_blt_addr) {
- mdp4_dsi_video_blt_ov_update(pipe);
- pipe->ov_cnt++;
- /* Prefill one frame */
- vsync_irq_enable(INTR_OVERLAY0_DONE,
- MDP_OVERLAY0_TERM);
- /* kickoff overlay0 engine */
- mdp4_stat.kickoff_ov0++;
- vctrl->ov_koff++; /* make up for prefill */
- outpdw(MDP_BASE + 0x0004, 0);
- }
vctrl->blt_change = 0;
}
@@ -1207,6 +1184,17 @@
}
mdp4_overlayproc_cfg(pipe);
mdp4_overlay_dmap_xy(pipe);
+ if (pipe->ov_blt_addr) {
+ mdp4_dsi_video_blt_ov_update(pipe);
+ pipe->ov_cnt++;
+ /* Prefill one frame */
+ vsync_irq_enable(INTR_OVERLAY0_DONE,
+ MDP_OVERLAY0_TERM);
+ /* kickoff overlay0 engine */
+ mdp4_stat.kickoff_ov0++;
+ vctrl->ov_koff++; /* make up for prefill */
+ outpdw(MDP_BASE + 0x0004, 0);
+ }
if (tg_enabled) {
/*
* need wait for more than 1 ms to
diff --git a/drivers/video/msm/mdp4_overlay_lcdc.c b/drivers/video/msm/mdp4_overlay_lcdc.c
index 96fc68a..31153bf 100644
--- a/drivers/video/msm/mdp4_overlay_lcdc.c
+++ b/drivers/video/msm/mdp4_overlay_lcdc.c
@@ -210,9 +210,6 @@
}
mutex_unlock(&vctrl->update_lock);
- /* free previous committed iommu back to pool */
- mdp4_overlay_iommu_unmap_freelist(mixer);
-
spin_lock_irqsave(&vctrl->spin_lock, flags);
if (vctrl->ov_koff != vctrl->ov_done) {
spin_unlock_irqrestore(&vctrl->spin_lock, flags);
diff --git a/drivers/video/msm/mdp4_overlay_writeback.c b/drivers/video/msm/mdp4_overlay_writeback.c
index 7092a2a..91f6e7f 100644
--- a/drivers/video/msm/mdp4_overlay_writeback.c
+++ b/drivers/video/msm/mdp4_overlay_writeback.c
@@ -418,8 +418,6 @@
}
}
- mdp_clk_ctrl(1);
-
mdp4_mixer_stage_commit(mixer);
pipe = vctrl->base_pipe;
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_helper.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_helper.c
index 360a85a..4ac5c38b 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_helper.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_helper.c
@@ -1063,6 +1063,23 @@
decoder->progressive_only)
need_reconfig = false;
}
+ DDL_MSG_HIGH("%s(): need_reconfig = %u, cont_mode = %u\n"\
+ "Actual: WxH = %ux%u, SxSH = %ux%u, sz = %u, min = %u, act = %u\n"\
+ "Client: WxH = %ux%u, SxSH = %ux%u, sz = %u, min = %u, act = %u\n",
+ __func__, need_reconfig, decoder->cont_mode,
+ decoder->frame_size.width, decoder->frame_size.height,
+ decoder->frame_size.stride, decoder->frame_size.scan_lines,
+ decoder->actual_output_buf_req.sz,
+ decoder->actual_output_buf_req.min_count,
+ decoder->actual_output_buf_req.actual_count,
+ decoder->client_frame_size.width,
+ decoder->client_frame_size.height,
+ decoder->client_frame_size.stride,
+ decoder->client_frame_size.scan_lines,
+ decoder->client_output_buf_req.sz,
+ decoder->client_output_buf_req.min_count,
+ decoder->client_output_buf_req.actual_count);
+
return need_reconfig;
}
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c
index aef9ff5..095b5df 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_properties.c
@@ -219,6 +219,13 @@
(ddl_valid_buffer_requirement(
&decoder->min_input_buf_req, buffer_req))) {
decoder->client_input_buf_req = *buffer_req;
+ DDL_MSG_HIGH("set DDL_IN_BUF_REQ: min = %u, "\
+ "max = %u, act = %u, size = %u, align = %u, "\
+ "buf_pool_id = %u, meta_buf_size = %u",
+ buffer_req->min_count, buffer_req->max_count,
+ buffer_req->actual_count, buffer_req->sz,
+ buffer_req->align, buffer_req->buf_pool_id,
+ buffer_req->meta_buffer_size);
vcd_status = VCD_S_SUCCESS;
}
}
@@ -236,9 +243,15 @@
DDLCLIENT_STATE_IS(ddl, DDL_CLIENT_OPEN)) &&
(ddl_valid_buffer_requirement(
&decoder->min_output_buf_req, buffer_req))) {
- decoder->client_output_buf_req =
- *buffer_req;
- vcd_status = VCD_S_SUCCESS;
+ decoder->client_output_buf_req = *buffer_req;
+ DDL_MSG_HIGH("set DDL_OUT_BUF_REQ: min = %u, "\
+ "max = %u, act = %u, size = %u, align = %u, "\
+ "buf_pool_id = %u, meta_buf_size = %u",
+ buffer_req->min_count, buffer_req->max_count,
+ buffer_req->actual_count, buffer_req->sz,
+ buffer_req->align, buffer_req->buf_pool_id,
+ buffer_req->meta_buffer_size);
+ vcd_status = VCD_S_SUCCESS;
}
}
break;
@@ -288,7 +301,7 @@
ddl_set_default_decoder_buffer_req(decoder,
true);
}
- DDL_MSG_LOW("set VCD_I_FRAME_SIZE width = %d"
+ DDL_MSG_HIGH("set VCD_I_FRAME_SIZE width = %d"
" height = %d\n",
frame_size->width, frame_size->height);
vcd_status = VCD_S_SUCCESS;
@@ -1172,6 +1185,9 @@
*(struct vcd_property_frame_size *)
property_value =
decoder->client_frame_size;
+ DDL_MSG_HIGH("get VCD_I_FRAME_SIZE WxH = %ux%u, "\
+ "SxSH = %ux%u", fz_size->width, fz_size->height,
+ fz_size->stride, fz_size->scan_lines);
vcd_status = VCD_S_SUCCESS;
}
break;
@@ -1204,6 +1220,17 @@
*(struct vcd_buffer_requirement *)
property_value =
decoder->client_input_buf_req;
+ DDL_MSG_HIGH("get DDL_IN_BUF_REQ: min = %u, "\
+ "max = %u, act = %u, size = %u, "\
+ "align = %u, buf_pool_id = %u, "\
+ "meta_buf_size = %u",
+ decoder->client_input_buf_req.min_count,
+ decoder->client_input_buf_req.max_count,
+ decoder->client_input_buf_req.actual_count,
+ decoder->client_input_buf_req.sz,
+ decoder->client_input_buf_req.align,
+ decoder->client_input_buf_req.buf_pool_id,
+ decoder->client_input_buf_req.meta_buffer_size);
vcd_status = VCD_S_SUCCESS;
}
break;
@@ -1212,7 +1239,17 @@
property_hdr->sz) {
*(struct vcd_buffer_requirement *)
property_value = decoder->client_output_buf_req;
- vcd_status = VCD_S_SUCCESS;
+ DDL_MSG_HIGH("get DDL_OUT_BUF_REQ: min = %u, "\
+ "max = %u, act = %u, size = %u, align = %u, "\
+ "buf_pool_id = %u, meta_buf_size = %u",
+ decoder->client_output_buf_req.min_count,
+ decoder->client_output_buf_req.max_count,
+ decoder->client_output_buf_req.actual_count,
+ decoder->client_output_buf_req.sz,
+ decoder->client_output_buf_req.align,
+ decoder->client_output_buf_req.buf_pool_id,
+ decoder->client_output_buf_req.meta_buffer_size);
+ vcd_status = VCD_S_SUCCESS;
}
break;
case VCD_I_CODEC:
@@ -1297,7 +1334,7 @@
break;
case VCD_I_METADATA_ENABLE:
case VCD_I_METADATA_HEADER:
- DDL_MSG_ERROR("Meta Data Interface is Requested");
+ DDL_MSG_HIGH("Meta Data Interface is Requested");
vcd_status = ddl_get_metadata_params(ddl, property_hdr,
property_value);
vcd_status = VCD_S_SUCCESS;
@@ -1982,14 +2019,19 @@
struct vcd_buffer_requirement *output_buf_req;
u32 min_dpb, y_cb_cr_size;
u32 frame_height_actual = 0;
+ u32 min_dpb_from_res_trk = 0;
- if (!decoder->codec.codec)
+ if (!decoder->codec.codec) {
+ DDL_MSG_ERROR("%s: codec not set", __func__);
return false;
+ }
if (estimate) {
- if (!decoder->cont_mode)
- min_dpb = ddl_decoder_min_num_dpb(decoder);
- else
+ if (decoder->cont_mode &&
+ decoder->codec.codec == VCD_CODEC_H264) {
min_dpb = res_trk_get_min_dpb_count();
+ min_dpb_from_res_trk = 1;
+ } else
+ min_dpb = ddl_decoder_min_num_dpb(decoder);
frame_size = &decoder->client_frame_size;
output_buf_req = &decoder->client_output_buf_req;
input_buf_req = &decoder->client_input_buf_req;
@@ -2020,14 +2062,13 @@
}
memset(output_buf_req, 0,
sizeof(struct vcd_buffer_requirement));
- if (!decoder->idr_only_decoding && !decoder->cont_mode)
+ if (!decoder->idr_only_decoding && !min_dpb_from_res_trk)
output_buf_req->actual_count = min_dpb + 4;
else
output_buf_req->actual_count = min_dpb;
output_buf_req->min_count = min_dpb;
output_buf_req->max_count = DDL_MAX_BUFFER_COUNT;
output_buf_req->sz = y_cb_cr_size;
- DDL_MSG_LOW("output_buf_req->sz : %d", output_buf_req->sz);
if (decoder->buf_format.buffer_format != VCD_BUFFER_FORMAT_NV12)
output_buf_req->align = DDL_TILE_BUFFER_ALIGN_BYTES;
else
@@ -2036,6 +2077,14 @@
output_buf_req);
decoder->min_output_buf_req = *output_buf_req;
+ DDL_MSG_HIGH("out_buf_req: estimate = %u, WxH = %ux%u, "\
+ "min_dpb = %u, sz = %d, act = %u, min = %u, max = %u, "\
+ "align = %u, meta_buf_size = %d", estimate,
+ frame_size->width, frame_size->height, min_dpb,
+ output_buf_req->sz, output_buf_req->actual_count,
+ output_buf_req->min_count, output_buf_req->max_count,
+ output_buf_req->align, output_buf_req->meta_buffer_size);
+
memset(input_buf_req, 0,
sizeof(struct vcd_buffer_requirement));
input_buf_req->min_count = 1;
@@ -2152,8 +2201,8 @@
case VCD_CODEC_H264:
{
u32 yuv_size_in_mb = DDL_MIN(DDL_NO_OF_MB(
- decoder->client_frame_size.stride,
- decoder->client_frame_size.scan_lines),
+ decoder->client_frame_size.width,
+ decoder->client_frame_size.height),
MAX_FRAME_SIZE_L4PT0_MBS);
min_dpb = DDL_MIN((MAX_DPB_SIZE_L4PT0_MBS /
yuv_size_in_mb), 16);
diff --git a/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.c b/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.c
index ff0de80..50518fb 100644
--- a/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.c
+++ b/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.c
@@ -383,7 +383,8 @@
mutex_lock(&resource_context.lock);
if (clk_set_rate(resource_context.vcodec_clk,
hclk_rate)) {
- VCDRES_MSG_ERROR("vidc hclk set rate failed\n");
+ VCDRES_MSG_INFO("clk_rate = %u not supported\n",
+ (u32)hclk_rate);
status = false;
} else
resource_context.vcodec_clk_rate = hclk_rate;
diff --git a/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.h b/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.h
index 2fa82ac..9ba99e1 100644
--- a/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.h
+++ b/drivers/video/msm/vidc/1080p/resource_tracker/vcd_res_tracker.h
@@ -76,6 +76,7 @@
#define VCDRES_MSG_HIGH(xx_fmt...) printk(KERN_WARNING "\n" xx_fmt)
#define VCDRES_MSG_ERROR(xx_fmt...) printk(KERN_ERR "\n err: " xx_fmt)
#define VCDRES_MSG_FATAL(xx_fmt...) printk(KERN_ERR "\n<FATAL> " xx_fmt)
+#define VCDRES_MSG_INFO(xx_fmt...) printk(KERN_INFO "\n * " xx_fmt)
#ifdef CONFIG_MSM_BUS_SCALING
int res_trk_update_bus_perf_level(struct vcd_dev_ctxt *dev_ctxt,
diff --git a/drivers/video/msm/vidc/common/dec/vdec.c b/drivers/video/msm/vidc/common/dec/vdec.c
index 92fa3ed..3443e2f 100644
--- a/drivers/video/msm/vidc/common/dec/vdec.c
+++ b/drivers/video/msm/vidc/common/dec/vdec.c
@@ -1940,6 +1940,19 @@
buffer_req.max_count = vdec_buf_req.maxcount;
buffer_req.min_count = vdec_buf_req.mincount;
buffer_req.sz = vdec_buf_req.buffer_size;
+ buffer_req.buf_pool_id = vdec_buf_req.buf_poolid;
+ buffer_req.meta_buffer_size = vdec_buf_req.meta_buffer_size;
+ DBG("SET_BUF_REQ: port = %u, min = %u, max = %u, "\
+ "act = %u, size = %u, align = %u, pool = %u, "\
+ "meta_buf_size = %u",
+ (u32)vdec_buf_req.buffer_type,
+ (u32)buffer_req.min_count,
+ (u32)buffer_req.max_count,
+ (u32)buffer_req.actual_count,
+ (u32)buffer_req.sz,
+ (u32)buffer_req.align,
+ (u32)buffer_req.buf_pool_id,
+ (u32)buffer_req.meta_buffer_size);
switch (vdec_buf_req.buffer_type) {
case VDEC_BUFFER_TYPE_INPUT:
@@ -1972,8 +1985,19 @@
return -EFAULT;
result = vid_dec_get_buffer_req(client_ctx, &vdec_buf_req);
-
if (result) {
+ DBG("GET_BUF_REQ: port = %u, min = %u, "\
+ "max = %u, act = %u, size = %u, "\
+ "align = %u, pool = %u, "\
+ "meta_buf_size = %u",
+ (u32)vdec_buf_req.buffer_type,
+ (u32)vdec_buf_req.mincount,
+ (u32)vdec_buf_req.maxcount,
+ (u32)vdec_buf_req.actualcount,
+ (u32)vdec_buf_req.buffer_size,
+ (u32)vdec_buf_req.alignment,
+ (u32)vdec_buf_req.buf_poolid,
+ (u32)vdec_buf_req.meta_buffer_size);
if (copy_to_user(vdec_msg.out, &vdec_buf_req,
sizeof(vdec_buf_req)))
return -EFAULT;
diff --git a/drivers/video/msm/vidc/common/enc/venc_internal.c b/drivers/video/msm/vidc/common/enc/venc_internal.c
index e60fc46..cdfd693 100644
--- a/drivers/video/msm/vidc/common/enc/venc_internal.c
+++ b/drivers/video/msm/vidc/common/enc/venc_internal.c
@@ -1622,31 +1622,51 @@
{
enum vcd_buffer_type buffer_vcd = VCD_BUFFER_INPUT;
enum buffer_dir dir_buffer = BUFFER_TYPE_INPUT;
- u32 vcd_status = VCD_ERR_FAIL;
- unsigned long kernel_vaddr;
+ unsigned long kernel_vaddr = 0;
+ unsigned long user_vaddr = 0;
+ unsigned long phy_addr = 0;
+ int pmem_fd = 0;
+ struct file *file;
+ s32 buffer_index = -1;
- if (!client_ctx || !buffer_info)
+ if (!client_ctx || !buffer_info) {
+ ERR("%s(): wrong buffer, 0x%x, 0x%x", __func__,
+ (u32)client_ctx, (u32)buffer_info);
return false;
+ }
if (buffer == VEN_BUFFER_TYPE_OUTPUT) {
dir_buffer = BUFFER_TYPE_OUTPUT;
buffer_vcd = VCD_BUFFER_OUTPUT;
}
+
+ user_vaddr = (unsigned long)buffer_info->pbuffer;
+ if (!vidc_lookup_addr_table(client_ctx, dir_buffer,
+ true, &user_vaddr, &kernel_vaddr,
+ &phy_addr, &pmem_fd, &file,
+ &buffer_index)) {
+ ERR("%s(): WNG: user_virt_addr = %p has not been set",
+ __func__, buffer_info->pbuffer);
+ return true;
+ }
+
+ if (vcd_free_buffer(client_ctx->vcd_handle, buffer_vcd,
+ (u8 *)kernel_vaddr)) {
+ ERR("%s(): WNG: vcd_free_buffer(0x%x, %u, 0x%x) failed.",
+ __func__, (u32)client_ctx->vcd_handle,
+ (u32)buffer_vcd, (u32)kernel_vaddr);
+ }
+
/*If buffer NOT set, ignore */
if (!vidc_delete_addr_table(client_ctx, dir_buffer,
(unsigned long)buffer_info->pbuffer,
&kernel_vaddr)) {
- DBG("%s() : user_virt_addr = %p has not been set.",
+ ERR("%s(): WNG: user_virt_addr = %p has not been set.",
__func__, buffer_info->pbuffer);
return true;
}
- vcd_status = vcd_free_buffer(client_ctx->vcd_handle, buffer_vcd,
- (u8 *)kernel_vaddr);
- if (!vcd_status)
- return true;
- else
- return false;
+ return true;
}
u32 vid_enc_encode_frame(struct video_client_ctx *client_ctx,
diff --git a/include/linux/input/synaptics_dsx.h b/include/linux/input/synaptics_dsx.h
index 56616d7..f90f59e 100644
--- a/include/linux/input/synaptics_dsx.h
+++ b/include/linux/input/synaptics_dsx.h
@@ -55,6 +55,7 @@
unsigned reset_gpio;
unsigned panel_x;
unsigned panel_y;
+ const char *fw_image_name;
int (*gpio_config)(unsigned gpio, bool configure);
struct synaptics_rmi4_capacitance_button_map *capacitance_button_map;
};
diff --git a/include/media/msm_camera.h b/include/media/msm_camera.h
index 121d8de..66ecf2f 100644
--- a/include/media/msm_camera.h
+++ b/include/media/msm_camera.h
@@ -1,5 +1,5 @@
/* Copyright (c) 2009-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.
@@ -1018,7 +1018,9 @@
#define CFG_SET_VISION_MODE 55
#define CFG_SET_VISION_AE 56
#define CFG_HDR_UPDATE 57
-#define CFG_MAX 58
+#define CFG_ACTUAOTOR_REG_INIT 58
+#define CFG_MAX 59
+
#define MOVE_NEAR 0
#define MOVE_FAR 1
@@ -1705,6 +1707,7 @@
enum actuator_type {
ACTUATOR_VCM,
ACTUATOR_PIEZO,
+ ACTUATOR_HALL_EFFECT,
};
enum msm_actuator_data_type {
diff --git a/include/sound/q6asm.h b/include/sound/q6asm.h
index cf7136a..6420e96 100644
--- a/include/sound/q6asm.h
+++ b/include/sound/q6asm.h
@@ -71,10 +71,12 @@
/* Enable Sample_Rate/Channel_Mode notification event from Decoder */
#define SR_CM_NOTIFY_ENABLE 0x0004
-#define ASYNC_IO_MODE 0x0002
-#define SYNC_IO_MODE 0x0001
-#define NO_TIMESTAMP 0xFF00
-#define SET_TIMESTAMP 0x0000
+#define TUN_WRITE_IO_MODE 0x0008 /* tunnel read write mode */
+#define TUN_READ_IO_MODE 0x0004 /* tunnel read write mode */
+#define ASYNC_IO_MODE 0x0002
+#define SYNC_IO_MODE 0x0001
+#define NO_TIMESTAMP 0xFF00
+#define SET_TIMESTAMP 0x0000
#define SOFT_PAUSE_ENABLE 1
#define SOFT_PAUSE_DISABLE 0
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c
index ae34bf5..d1e73a4 100644
--- a/kernel/hrtimer.c
+++ b/kernel/hrtimer.c
@@ -61,6 +61,7 @@
DEFINE_PER_CPU(struct hrtimer_cpu_base, hrtimer_bases) =
{
+ .lock = __RAW_SPIN_LOCK_UNLOCKED(hrtimer_bases.lock),
.clock_base =
{
{
@@ -1619,8 +1620,6 @@
struct hrtimer_cpu_base *cpu_base = &per_cpu(hrtimer_bases, cpu);
int i;
- raw_spin_lock_init(&cpu_base->lock);
-
for (i = 0; i < HRTIMER_MAX_CLOCK_BASES; i++) {
cpu_base->clock_base[i].cpu_base = cpu_base;
timerqueue_init_head(&cpu_base->clock_base[i].active);
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 7bc1d40..5318889 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -1891,7 +1891,8 @@
} else {
conn->state = BT_CONNECTED;
hci_proto_connect_cfm(conn, ev->status);
- conn->disc_timeout = HCI_DISCONN_AUTH_FAILED_TIMEOUT;
+ if (ev->status)
+ conn->disc_timeout = HCI_DISCONN_AUTH_FAILED_TIMEOUT;
hci_conn_put(conn);
}
} else {
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index 75a74ac..200637e 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -715,6 +715,10 @@
invalid_key:
hcon->sec_req = FALSE;
+ /* Switch to Pairing Connection Parameters */
+ hci_le_conn_update(hcon, SMP_MIN_CONN_INTERVAL, SMP_MAX_CONN_INTERVAL,
+ SMP_MAX_CONN_LATENCY, SMP_SUPERVISION_TIMEOUT);
+
skb_pull(skb, sizeof(*rp));
memset(&cp, 0, sizeof(cp));
@@ -775,6 +779,11 @@
if (hcon->link_mode & HCI_LM_MASTER) {
struct smp_cmd_pairing cp;
+ /* Switch to Pairing Connection Parameters */
+ hci_le_conn_update(hcon, SMP_MIN_CONN_INTERVAL,
+ SMP_MAX_CONN_INTERVAL, SMP_MAX_CONN_LATENCY,
+ SMP_SUPERVISION_TIMEOUT);
+
build_pairing_cmd(conn, &cp, NULL, authreq);
hcon->preq[0] = SMP_CMD_PAIRING_REQ;
memcpy(&hcon->preq[1], &cp, sizeof(cp));
diff --git a/sound/soc/msm/msm-pcm-loopback.c b/sound/soc/msm/msm-pcm-loopback.c
index 16b6f09..84ea9c6 100644
--- a/sound/soc/msm/msm-pcm-loopback.c
+++ b/sound/soc/msm/msm-pcm-loopback.c
@@ -61,6 +61,25 @@
.periods_max = 128,
};
+static void msm_pcm_route_event_handler(enum msm_pcm_routing_event event,
+ void *priv_data)
+{
+ struct msm_pcm_loopback *pcm = priv_data;
+
+ BUG_ON(!pcm);
+
+ pr_debug("%s: event %x\n", __func__, event);
+
+ switch (event) {
+ case MSM_PCM_RT_EVT_DEVSWITCH:
+ q6asm_cmd(pcm->audio_client, CMD_PAUSE);
+ q6asm_cmd(pcm->audio_client, CMD_FLUSH);
+ q6asm_run(pcm->audio_client, 0, 0, 0);
+ default:
+ break;
+ }
+}
+
static void msm_pcm_loopback_event_handler(uint32_t opcode,
uint32_t token, uint32_t *payload, void *priv)
{
@@ -86,6 +105,7 @@
struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
struct msm_pcm_loopback *pcm;
int ret = 0;
+ struct msm_pcm_routing_evt event;
pcm = dev_get_drvdata(rtd->platform->dev);
mutex_lock(&pcm->lock);
@@ -126,12 +146,15 @@
mutex_unlock(&pcm->lock);
return -ENOMEM;
}
+ event.event_func = msm_pcm_route_event_handler;
+ event.priv_data = (void *) pcm;
msm_pcm_routing_reg_phy_stream(soc_pcm_tx->dai_link->be_id,
pcm->audio_client->perf_mode,
pcm->session_id, pcm->capture_substream->stream);
- msm_pcm_routing_reg_phy_stream(soc_pcm_rx->dai_link->be_id,
+ msm_pcm_routing_reg_phy_stream_v2(soc_pcm_rx->dai_link->be_id,
pcm->audio_client->perf_mode,
- pcm->session_id, pcm->playback_substream->stream);
+ pcm->session_id, pcm->playback_substream->stream,
+ event);
}
dev_info(rtd->platform->dev, "%s: Instance = %d, Stream ID = %s\n",
__func__ , pcm->instance, substream->pcm->id);
diff --git a/sound/soc/msm/msm-pcm-q6.c b/sound/soc/msm/msm-pcm-q6.c
index 62deb63..2a31dd0 100644
--- a/sound/soc/msm/msm-pcm-q6.c
+++ b/sound/soc/msm/msm-pcm-q6.c
@@ -100,6 +100,25 @@
.mask = 0,
};
+static void msm_pcm_route_event_handler(enum msm_pcm_routing_event event,
+ void *priv_data)
+{
+ struct msm_audio *prtd = priv_data;
+
+ BUG_ON(!prtd);
+
+ pr_debug("%s: event %x\n", __func__, event);
+
+ switch (event) {
+ case MSM_PCM_RT_EVT_BUF_RECFG:
+ q6asm_cmd(prtd->audio_client, CMD_PAUSE);
+ q6asm_cmd(prtd->audio_client, CMD_FLUSH);
+ q6asm_run(prtd->audio_client, 0, 0, 0);
+ default:
+ break;
+ }
+}
+
static void event_handler(uint32_t opcode,
uint32_t token, uint32_t *payload, void *priv)
{
@@ -146,18 +165,33 @@
pr_debug("cmd[%d]=0x%08x\n", i, *ptrmem);
in_frame_info[token][0] = payload[2];
in_frame_info[token][1] = payload[3];
- prtd->pcm_irq_pos += in_frame_info[token][0];
- pr_debug("pcm_irq_pos=%d\n", prtd->pcm_irq_pos);
- if (atomic_read(&prtd->start))
- snd_pcm_period_elapsed(substream);
- if (atomic_read(&prtd->in_count) <= prtd->periods)
- atomic_inc(&prtd->in_count);
- wake_up(&the_locks.read_wait);
- if (prtd->mmap_flag
- && q6asm_is_cpu_buf_avail_nolock(OUT,
+
+ /* assume data size = 0 during flushing */
+ if (in_frame_info[token][0]) {
+ prtd->pcm_irq_pos += in_frame_info[token][0];
+ pr_debug("pcm_irq_pos=%d\n", prtd->pcm_irq_pos);
+ if (atomic_read(&prtd->start))
+ snd_pcm_period_elapsed(substream);
+ if (atomic_read(&prtd->in_count) <= prtd->periods)
+ atomic_inc(&prtd->in_count);
+ wake_up(&the_locks.read_wait);
+ if (prtd->mmap_flag &&
+ q6asm_is_cpu_buf_avail_nolock(OUT,
prtd->audio_client,
&size, &idx))
- q6asm_read_nolock(prtd->audio_client);
+ q6asm_read_nolock(prtd->audio_client);
+ } else {
+ pr_debug("%s: reclaim flushed buf in_count %x\n",
+ __func__, atomic_read(&prtd->in_count));
+ atomic_inc(&prtd->in_count);
+ if (atomic_read(&prtd->in_count) == prtd->periods) {
+ pr_info("%s: reclaimed all bufs\n", __func__);
+ if (atomic_read(&prtd->start))
+ snd_pcm_period_elapsed(substream);
+ wake_up(&the_locks.read_wait);
+ }
+ }
+
break;
}
case APR_BASIC_RSP_RESULT: {
@@ -642,6 +676,7 @@
struct audio_buffer *buf;
int dir, ret;
int format = FORMAT_LINEAR_PCM;
+ struct msm_pcm_routing_evt event;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
dir = IN;
@@ -665,10 +700,13 @@
pr_debug("%s: session ID %d\n", __func__,
prtd->audio_client->session);
prtd->session_id = prtd->audio_client->session;
- msm_pcm_routing_reg_phy_stream(soc_prtd->dai_link->be_id,
- prtd->audio_client->perf_mode,
- prtd->session_id, substream->stream);
- }
+ event.event_func = msm_pcm_route_event_handler;
+ event.priv_data = (void *) prtd;
+ msm_pcm_routing_reg_phy_stream_v2(soc_prtd->dai_link->be_id,
+ prtd->audio_client->perf_mode,
+ prtd->session_id,
+ substream->stream, event);
+ }
if (dir == OUT) {
ret = q6asm_audio_client_buf_alloc_contiguous(dir,
diff --git a/sound/soc/msm/msm-pcm-routing.c b/sound/soc/msm/msm-pcm-routing.c
index 984b0c3..75e54df 100644
--- a/sound/soc/msm/msm-pcm-routing.c
+++ b/sound/soc/msm/msm-pcm-routing.c
@@ -41,6 +41,12 @@
bool perf_mode;
};
+struct msm_pcm_routing_fdai_data {
+ u16 be_srate; /* track prior backend sample rate for flushing purpose */
+ int strm_id; /* ASM stream ID */
+ struct msm_pcm_routing_evt event_info;
+};
+
#define INVALID_SESSION -1
#define SESSION_TYPE_RX 0
#define SESSION_TYPE_TX 1
@@ -195,24 +201,32 @@
/* Track ASM playback & capture sessions of DAI */
-static int fe_dai_map[MSM_FRONTEND_DAI_MM_SIZE][2] = {
+static struct msm_pcm_routing_fdai_data
+ fe_dai_map[MSM_FRONTEND_DAI_MM_SIZE][2] = {
/* MULTIMEDIA1 */
- {INVALID_SESSION, INVALID_SESSION},
+ {{0, INVALID_SESSION, {NULL, NULL} },
+ {0, INVALID_SESSION, {NULL, NULL} } },
/* MULTIMEDIA2 */
- {INVALID_SESSION, INVALID_SESSION},
+ {{0, INVALID_SESSION, {NULL, NULL} },
+ {0, INVALID_SESSION, {NULL, NULL} } },
/* MULTIMEDIA3 */
- {INVALID_SESSION, INVALID_SESSION},
+ {{0, INVALID_SESSION, {NULL, NULL} },
+ {0, INVALID_SESSION, {NULL, NULL} } },
/* MULTIMEDIA4 */
- {INVALID_SESSION, INVALID_SESSION},
+ {{0, INVALID_SESSION, {NULL, NULL} },
+ {0, INVALID_SESSION, {NULL, NULL} } },
/* MULTIMEDIA5 */
- {INVALID_SESSION, INVALID_SESSION},
+ {{0, INVALID_SESSION, {NULL, NULL} },
+ {0, INVALID_SESSION, {NULL, NULL} } },
/* MULTIMEDIA6 */
- {INVALID_SESSION, INVALID_SESSION},
+ {{0, INVALID_SESSION, {NULL, NULL} },
+ {0, INVALID_SESSION, {NULL, NULL} } },
/* MULTIMEDIA7*/
- {INVALID_SESSION, INVALID_SESSION},
+ {{0, INVALID_SESSION, {NULL, NULL} },
+ {0, INVALID_SESSION, {NULL, NULL} } },
/* MULTIMEDIA8 */
- {INVALID_SESSION, INVALID_SESSION},
-
+ {{0, INVALID_SESSION, {NULL, NULL} },
+ {0, INVALID_SESSION, {NULL, NULL} } },
};
static uint8_t is_be_dai_extproc(int be_dai)
@@ -273,7 +287,7 @@
mutex_lock(&routing_lock);
- fe_dai_map[fedai_id][session_type] = dspst_id;
+ fe_dai_map[fedai_id][session_type].strm_id = dspst_id;
for (i = 0; i < MSM_BACKEND_DAI_MAX; i++) {
if (!is_be_dai_extproc(i) &&
(afe_get_port_type(msm_bedais[i].port_id) == port_type) &&
@@ -319,7 +333,7 @@
mutex_lock(&routing_lock);
payload.num_copps = 0; /* only RX needs to use payload */
- fe_dai_map[fedai_id][session_type] = dspst_id;
+ fe_dai_map[fedai_id][session_type].strm_id = dspst_id;
/* re-enable EQ if active */
if (eq_data[fedai_id].enable)
msm_send_eq_values(fedai_id);
@@ -369,6 +383,19 @@
mutex_unlock(&routing_lock);
}
+void msm_pcm_routing_reg_phy_stream_v2(int fedai_id, bool perf_mode,
+ int dspst_id, int stream_type,
+ struct msm_pcm_routing_evt event_info)
+{
+ msm_pcm_routing_reg_phy_stream(fedai_id, perf_mode, dspst_id,
+ stream_type);
+
+ if (stream_type == SNDRV_PCM_STREAM_PLAYBACK)
+ fe_dai_map[fedai_id][SESSION_TYPE_RX].event_info = event_info;
+ else
+ fe_dai_map[fedai_id][SESSION_TYPE_TX].event_info = event_info;
+
+}
void msm_pcm_routing_dereg_phy_stream(int fedai_id, int stream_type)
{
@@ -398,8 +425,8 @@
adm_close(msm_bedais[i].port_id);
}
- fe_dai_map[fedai_id][session_type] = INVALID_SESSION;
-
+ fe_dai_map[fedai_id][session_type].strm_id = INVALID_SESSION;
+ fe_dai_map[fedai_id][session_type].be_srate = 0;
mutex_unlock(&routing_lock);
}
@@ -424,6 +451,7 @@
{
int session_type, path_type;
u32 channels;
+ struct msm_pcm_routing_fdai_data *fdai;
pr_debug("%s: reg %x val %x set %x\n", __func__, reg, val, set);
@@ -450,11 +478,24 @@
voc_start_playback(set);
set_bit(val, &msm_bedais[reg].fe_sessions);
- if (msm_bedais[reg].active && fe_dai_map[val][session_type] !=
+ fdai = &fe_dai_map[val][session_type];
+ if (msm_bedais[reg].active && fdai->strm_id !=
INVALID_SESSION) {
channels = msm_bedais[reg].channel;
+ if (session_type == SESSION_TYPE_TX && fdai->be_srate &&
+ (fdai->be_srate != msm_bedais[reg].sample_rate)) {
+ pr_debug("%s: flush strm %d due diff BE rates\n",
+ __func__, fdai->strm_id);
+
+ if (fdai->event_info.event_func)
+ fdai->event_info.event_func(
+ MSM_PCM_RT_EVT_BUF_RECFG,
+ fdai->event_info.priv_data);
+ fdai->be_srate = 0; /* might not need it */
+ }
+
if ((session_type == SESSION_TYPE_RX) &&
((channels == 1) || (channels == 2))
&& msm_bedais[reg].perf_mode) {
@@ -480,9 +521,14 @@
msm_bedais[reg].sample_rate, channels,
DEFAULT_COPP_TOPOLOGY);
+ if (session_type == SESSION_TYPE_RX &&
+ fdai->event_info.event_func)
+ fdai->event_info.event_func(
+ MSM_PCM_RT_EVT_DEVSWITCH,
+ fdai->event_info.priv_data);
msm_pcm_routing_build_matrix(val,
- fe_dai_map[val][session_type], path_type);
+ fdai->strm_id, path_type);
srs_port_id = msm_bedais[reg].port_id;
srs_send_params(srs_port_id, 1, 0);
}
@@ -491,11 +537,13 @@
(msm_bedais[reg].port_id == VOICE_PLAYBACK_TX))
voc_start_playback(set);
clear_bit(val, &msm_bedais[reg].fe_sessions);
- if (msm_bedais[reg].active && fe_dai_map[val][session_type] !=
+ fdai = &fe_dai_map[val][session_type];
+ if (msm_bedais[reg].active && fdai->strm_id !=
INVALID_SESSION) {
+ fdai->be_srate = msm_bedais[reg].sample_rate;
adm_close(msm_bedais[reg].port_id);
msm_pcm_routing_build_matrix(val,
- fe_dai_map[val][session_type], path_type);
+ fdai->strm_id, path_type);
}
}
if ((msm_bedais[reg].port_id == VOICE_RECORD_RX)
@@ -969,12 +1017,12 @@
static void msm_send_eq_values(int eq_idx)
{
int result;
- struct audio_client *ac =
- q6asm_get_audio_client(fe_dai_map[eq_idx][SESSION_TYPE_RX]);
+ struct audio_client *ac = q6asm_get_audio_client(
+ fe_dai_map[eq_idx][SESSION_TYPE_RX].strm_id);
if (ac == NULL) {
pr_err("%s: Could not get audio client for session: %d\n",
- __func__, fe_dai_map[eq_idx][SESSION_TYPE_RX]);
+ __func__, fe_dai_map[eq_idx][SESSION_TYPE_RX].strm_id);
goto done;
}
@@ -2863,7 +2911,9 @@
mutex_lock(&routing_lock);
for_each_set_bit(i, &bedai->fe_sessions, MSM_FRONTEND_DAI_MM_SIZE) {
- if (fe_dai_map[i][session_type] != INVALID_SESSION) {
+ if (fe_dai_map[i][session_type].strm_id != INVALID_SESSION) {
+ fe_dai_map[i][session_type].be_srate =
+ bedai->sample_rate;
adm_close(bedai->port_id);
srs_port_id = -1;
}
@@ -2886,6 +2936,7 @@
struct msm_pcm_routing_bdai_data *bedai;
u32 channels;
bool playback, capture;
+ struct msm_pcm_routing_fdai_data *fdai;
if (be_id >= MSM_BACKEND_DAI_MAX) {
pr_err("%s: unexpected be_id %d\n", __func__, be_id);
@@ -2917,7 +2968,21 @@
capture = substream->stream == SNDRV_PCM_STREAM_CAPTURE;
for_each_set_bit(i, &bedai->fe_sessions, MSM_FRONTEND_DAI_MM_SIZE) {
- if (fe_dai_map[i][session_type] != INVALID_SESSION) {
+ fdai = &fe_dai_map[i][session_type];
+ if (fdai->strm_id != INVALID_SESSION) {
+ if (session_type == SESSION_TYPE_TX && fdai->be_srate &&
+ (fdai->be_srate != bedai->sample_rate)) {
+ pr_debug("%s: flush strm %d due diff BE rates\n",
+ __func__,
+ fdai->strm_id);
+
+ if (fdai->event_info.event_func)
+ fdai->event_info.event_func(
+ MSM_PCM_RT_EVT_BUF_RECFG,
+ fdai->event_info.priv_data);
+ fdai->be_srate = 0; /* might not need it */
+ }
+
channels = bedai->channel;
if ((playback || capture)
&& ((channels == 2) || (channels == 1)) &&
@@ -2944,7 +3009,7 @@
DEFAULT_COPP_TOPOLOGY);
msm_pcm_routing_build_matrix(i,
- fe_dai_map[i][session_type], path_type);
+ fdai->strm_id, path_type);
srs_port_id = bedai->port_id;
srs_send_params(srs_port_id, 1, 0);
}
diff --git a/sound/soc/msm/msm-pcm-routing.h b/sound/soc/msm/msm-pcm-routing.h
index 48d70b9..ad63c12 100644
--- a/sound/soc/msm/msm-pcm-routing.h
+++ b/sound/soc/msm/msm-pcm-routing.h
@@ -109,6 +109,11 @@
MSM_BACKEND_DAI_MAX,
};
+enum msm_pcm_routing_event {
+ MSM_PCM_RT_EVT_BUF_RECFG,
+ MSM_PCM_RT_EVT_DEVSWITCH,
+ MSM_PCM_RT_EVT_MAX,
+};
/* dai_id: front-end ID,
* dspst_id: DSP audio stream ID
* stream_type: playback or capture
@@ -118,6 +123,15 @@
void msm_pcm_routing_reg_psthr_stream(int fedai_id, int dspst_id,
int stream_type, int enable);
+struct msm_pcm_routing_evt {
+ void (*event_func)(enum msm_pcm_routing_event, void *);
+ void *priv_data;
+};
+
+void msm_pcm_routing_reg_phy_stream_v2(int fedai_id, bool perf_mode,
+ int dspst_id, int stream_type,
+ struct msm_pcm_routing_evt event_info);
+
void msm_pcm_routing_dereg_phy_stream(int fedai_id, int stream_type);
int lpa_set_volume(unsigned volume);
diff --git a/sound/soc/msm/qdsp6/q6asm.c b/sound/soc/msm/qdsp6/q6asm.c
index 2280fd1..512127c 100644
--- a/sound/soc/msm/qdsp6/q6asm.c
+++ b/sound/soc/msm/qdsp6/q6asm.c
@@ -220,7 +220,7 @@
int rc = 0;
pr_debug("%s: Session id %d\n", __func__, ac->session);
mutex_lock(&ac->cmd_lock);
- if (ac->io_mode == SYNC_IO_MODE) {
+ if (ac->io_mode & SYNC_IO_MODE) {
port = &ac->port[dir];
if (!port->buf) {
mutex_unlock(&ac->cmd_lock);
@@ -351,7 +351,7 @@
if (!ac || !ac->session)
return;
pr_debug("%s: Session id %d\n", __func__, ac->session);
- if (ac->io_mode == SYNC_IO_MODE) {
+ if (ac->io_mode & SYNC_IO_MODE) {
for (loopcnt = 0; loopcnt <= OUT; loopcnt++) {
port = &ac->port[loopcnt];
if (!port->buf)
@@ -386,14 +386,20 @@
pr_err("%s APR handle NULL\n", __func__);
return -EINVAL;
}
- if ((mode == ASYNC_IO_MODE) || (mode == SYNC_IO_MODE)) {
- ac->io_mode = mode;
- pr_debug("%s:Set Mode to %d\n", __func__, ac->io_mode);
- return 0;
+
+ if (mode == ASYNC_IO_MODE) {
+ ac->io_mode &= ~SYNC_IO_MODE;
+ ac->io_mode |= ASYNC_IO_MODE;
+ } else if (mode == SYNC_IO_MODE) {
+ ac->io_mode &= ~ASYNC_IO_MODE;
+ ac->io_mode |= SYNC_IO_MODE;
} else {
pr_err("%s:Not an valid IO Mode:%d\n", __func__, ac->io_mode);
return -EINVAL;
}
+
+ pr_debug("%s:Set Mode to %d\n", __func__, ac->io_mode);
+ return 0;
}
struct audio_client *q6asm_audio_client_alloc(app_cb cb, void *priv)
@@ -497,7 +503,7 @@
if (ac->session <= 0 || ac->session > 8)
goto fail;
- if (ac->io_mode == SYNC_IO_MODE) {
+ if (ac->io_mode & SYNC_IO_MODE) {
if (ac->port[dir].buf) {
pr_debug("%s: buffer already allocated\n", __func__);
return 0;
@@ -927,7 +933,7 @@
pr_debug("%s: Rxed opcode[0x%x] status[0x%x] token[%d]",
__func__, payload[0], payload[1],
data->token);
- if (ac->io_mode == SYNC_IO_MODE) {
+ if (ac->io_mode & SYNC_IO_MODE) {
if (port->buf == NULL) {
pr_err("%s: Unexpected Write Done\n",
__func__);
@@ -1009,7 +1015,7 @@
if (in_enable_flag)
in_cont_index++;
#endif
- if (ac->io_mode == SYNC_IO_MODE) {
+ if (ac->io_mode & SYNC_IO_MODE) {
if (port->buf == NULL) {
pr_err("%s: Unexpected Write Done\n", __func__);
return -EINVAL;
@@ -1078,7 +1084,7 @@
if (!ac || ((dir != IN) && (dir != OUT)))
return NULL;
- if (ac->io_mode == SYNC_IO_MODE) {
+ if (ac->io_mode & SYNC_IO_MODE) {
port = &ac->port[dir];
mutex_lock(&port->lock);
@@ -1172,7 +1178,7 @@
if (!ac || (dir != OUT))
return ret;
- if (ac->io_mode == SYNC_IO_MODE) {
+ if (ac->io_mode & SYNC_IO_MODE) {
port = &ac->port[dir];
mutex_lock(&port->lock);
@@ -1303,6 +1309,9 @@
rc);
goto fail_cmd;
}
+
+ ac->io_mode |= TUN_READ_IO_MODE;
+
return 0;
fail_cmd:
return -EINVAL;
@@ -1579,6 +1588,9 @@
pr_err("%s: format = %x not supported\n", __func__, format);
goto fail_cmd;
}
+
+ ac->io_mode |= TUN_WRITE_IO_MODE;
+
return 0;
fail_cmd:
return -EINVAL;
@@ -3366,7 +3378,7 @@
pr_err("APR handle NULL\n");
return -EINVAL;
}
- if (ac->io_mode == SYNC_IO_MODE) {
+ if (ac->io_mode & SYNC_IO_MODE) {
port = &ac->port[OUT];
q6asm_add_hdr(ac, &read.hdr, sizeof(read), FALSE);
@@ -3418,7 +3430,7 @@
pr_err("APR handle NULL\n");
return -EINVAL;
}
- if (ac->io_mode == SYNC_IO_MODE) {
+ if (ac->io_mode & SYNC_IO_MODE) {
port = &ac->port[OUT];
q6asm_add_hdr_async(ac, &read.hdr, sizeof(read), FALSE);
@@ -3442,7 +3454,7 @@
read.hdr.token = port->dsp_buf;
port->dsp_buf = (port->dsp_buf + 1) & (port->max_buf_cnt - 1);
- pr_debug("%s:buf add[0x%x] token[%d] uid[%d]\n", __func__,
+ pr_info("%s:buf add[0x%x] token[%d] uid[%d]\n", __func__,
read.buf_add,
read.hdr.token,
read.uid);
@@ -3603,7 +3615,7 @@
return -EINVAL;
}
pr_debug("%s: session[%d] len=%d", __func__, ac->session, len);
- if (ac->io_mode == SYNC_IO_MODE) {
+ if (ac->io_mode & SYNC_IO_MODE) {
port = &ac->port[IN];
q6asm_add_hdr(ac, &write.hdr, sizeof(write),
@@ -3685,7 +3697,7 @@
return -EINVAL;
}
pr_debug("%s: session[%d] len=%d", __func__, ac->session, len);
- if (ac->io_mode == SYNC_IO_MODE) {
+ if (ac->io_mode & SYNC_IO_MODE) {
port = &ac->port[IN];
q6asm_add_hdr_async(ac, &write.hdr, sizeof(write),
@@ -3890,9 +3902,11 @@
{
int cnt = 0;
int loopcnt = 0;
+ int used;
struct audio_port_data *port = NULL;
- if (ac->io_mode == SYNC_IO_MODE) {
+ if (ac->io_mode & SYNC_IO_MODE) {
+ used = (ac->io_mode & TUN_WRITE_IO_MODE ? 1 : 0);
mutex_lock(&ac->cmd_lock);
for (loopcnt = 0; loopcnt <= OUT; loopcnt++) {
port = &ac->port[loopcnt];
@@ -3902,7 +3916,7 @@
while (cnt >= 0) {
if (!port->buf)
continue;
- port->buf[cnt].used = 1;
+ port->buf[cnt].used = used;
cnt--;
}
}