Merge "Merge usb dwc3 changes backported from v3.7-rc1"
diff --git a/Documentation/devicetree/bindings/power/qpnp-charger.txt b/Documentation/devicetree/bindings/power/qpnp-charger.txt
index 244e622..2103bbc 100644
--- a/Documentation/devicetree/bindings/power/qpnp-charger.txt
+++ b/Documentation/devicetree/bindings/power/qpnp-charger.txt
@@ -29,6 +29,12 @@
- qcom,chg-ibatmax-ma: Maximum battery charge current in mA
- qcom,chg-ibatterm-ma: Current at which charging is terminated in mA.
+Parent node optional properties:
+- qcom,chg-charging-disabled: Set this property to disable charging
+ by default. This can then be overriden
+ writing the the module parameter
+ "charging_disabled".
+
Sub node required structure:
- A qcom,chg node must be a child of an SPMI node that has specified
the spmi-dev-container property. Each subnode reflects
diff --git a/arch/arm/boot/dts/msm-pm8019.dtsi b/arch/arm/boot/dts/msm-pm8019.dtsi
index e70eb36..2105e8a 100755
--- a/arch/arm/boot/dts/msm-pm8019.dtsi
+++ b/arch/arm/boot/dts/msm-pm8019.dtsi
@@ -152,6 +152,47 @@
qcom,pin-num = <6>;
};
};
+
+ pm8019_vadc: vadc@3100 {
+ compatible = "qcom,qpnp-vadc";
+ reg = <0x3100 0x100>;
+ interrupts = <0x0 0x31 0x0>;
+ qcom,adc-bit-resolution = <15>;
+ qcom,adc-vdd-reference = <1800>;
+
+ chan@8 {
+ label = "die_temp";
+ qcom,channel-num = <8>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "absolute";
+ qcom,scale-function = <3>;
+ qcom,hw-settle-time = <0>;
+ qcom,fast-avg-setup = <0>;
+ };
+
+ chan@9 {
+ label = "ref_625mv";
+ qcom,channel-num = <9>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "absolute";
+ qcom,scale-function = <0>;
+ qcom,hw-settle-time = <0>;
+ qcom,fast-avg-setup = <0>;
+ };
+
+ chan@10 {
+ label = "ref_1250v";
+ qcom,channel-num = <10>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "absolute";
+ qcom,scale-function = <0>;
+ qcom,hw-settle-time = <0>;
+ qcom,fast-avg-setup = <0>;
+ };
+ };
};
qcom,pm8019@1 {
diff --git a/arch/arm/boot/dts/msm8974-liquid.dts b/arch/arm/boot/dts/msm8974-liquid.dts
index 6be571a..6ccd933 100644
--- a/arch/arm/boot/dts/msm8974-liquid.dts
+++ b/arch/arm/boot/dts/msm8974-liquid.dts
@@ -59,6 +59,10 @@
};
};
+ qcom,mdss_mdp@fd900000 {
+ qcom,memory-reservation-size = <0x1000000>; /* size 16MB */
+ };
+
qcom,hdmi_tx@fd922100 {
status = "ok";
};
diff --git a/arch/arm/boot/dts/msm8974-mtp.dts b/arch/arm/boot/dts/msm8974-mtp.dts
index f75ebbe..460caf2 100644
--- a/arch/arm/boot/dts/msm8974-mtp.dts
+++ b/arch/arm/boot/dts/msm8974-mtp.dts
@@ -180,6 +180,8 @@
&pm8941_chg {
status = "ok";
+ qcom,chg-charging-disabled;
+
qcom,chg-chgr@1000 {
status = "ok";
};
diff --git a/arch/arm/boot/dts/msm9625.dtsi b/arch/arm/boot/dts/msm9625.dtsi
index 8cb7191..871c9e5 100644
--- a/arch/arm/boot/dts/msm9625.dtsi
+++ b/arch/arm/boot/dts/msm9625.dtsi
@@ -29,8 +29,6 @@
l2: cache-controller@f9040000 {
compatible = "arm,pl310-cache";
reg = <0xf9040000 0x1000>;
- arm,data-latency = <1 1 1>;
- arm,tag-latency = <1 1 1>;
cache-unified;
cache-level = <2>;
};
@@ -238,8 +236,71 @@
qcom,sdcc-bus-speed-mode = "SDR12", "SDR25", "SDR50", "DDR50";
status = "disable";
};
+
+ qcom,bam_dmux@fc834000 {
+ compatible = "qcom,bam_dmux";
+ reg = <0xfc834000 0x7000>;
+ interrupts = <0 29 1>;
+ };
};
/include/ "msm-pm8019-rpm-regulator.dtsi"
/include/ "msm-pm8019.dtsi"
/include/ "msm9625-regulator.dtsi"
+
+&pm8019_vadc {
+ chan@49 {
+ label = "batt_id_therm";
+ qcom,channel-num = <49>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <0>;
+ qcom,hw-settle-time = <0>;
+ qcom,fast-avg-setup = <0>;
+ };
+
+ chan@51 {
+ label = "pa_therm1";
+ qcom,channel-num = <51>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <2>;
+ qcom,hw-settle-time = <0>;
+ qcom,fast-avg-setup = <0>;
+ };
+
+ chan@52 {
+ label = "pa_therm2";
+ qcom,channel-num = <52>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <2>;
+ qcom,hw-settle-time = <0>;
+ qcom,fast-avg-setup = <0>;
+ };
+
+ chan@50 {
+ label = "xo_therm";
+ qcom,channel-num = <50>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <4>;
+ qcom,hw-settle-time = <0>;
+ qcom,fast-avg-setup = <0>;
+ };
+
+ chan@60 {
+ label = "xo_therm_amux";
+ qcom,channel-num = <60>;
+ qcom,decimation = <0>;
+ qcom,pre-div-channel-scaling = <0>;
+ qcom,calibration-type = "ratiometric";
+ qcom,scale-function = <4>;
+ qcom,hw-settle-time = <0>;
+ qcom,fast-avg-setup = <0>;
+ };
+};
diff --git a/arch/arm/configs/msm9625_defconfig b/arch/arm/configs/msm9625_defconfig
index 4e34ebd..0a5ec10 100644
--- a/arch/arm/configs/msm9625_defconfig
+++ b/arch/arm/configs/msm9625_defconfig
@@ -37,6 +37,8 @@
# CONFIG_MSM_PROC_COMM is not set
CONFIG_MSM_SMD=y
CONFIG_MSM_SMD_PKG4=y
+CONFIG_MSM_IPC_ROUTER=y
+CONFIG_MSM_IPC_ROUTER_SMD_XPRT=y
CONFIG_MSM_RPM_REGULATOR_SMD=y
CONFIG_MSM_DIRECT_SCLK_ACCESS=y
CONFIG_MSM_WATCHDOG_V2=y
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index 8374296..10c7089 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -176,6 +176,7 @@
select MSM_RUN_QUEUE_STATS
select ARM_HAS_SG_CHAIN
select MSM_KRAIT_WFE_FIXUP
+ select MSM_ULTRASOUND_A
config ARCH_MSM8930
bool "MSM8930"
@@ -202,7 +203,7 @@
select MSM_REMOTE_SPINLOCK_SFPB
select ARCH_SPARSEMEM_ENABLE
select ARCH_HAS_HOLES_MEMORYMODEL
- select MSM_ULTRASOUND
+ select MSM_ULTRASOUND_A
select MULTI_IRQ_HANDLER
select MSM_PM8X60 if PM
select HOLES_IN_ZONE if SPARSEMEM
@@ -235,6 +236,7 @@
select ARCH_SUPPORTS_MSI
select ARM_HAS_SG_CHAIN
select MSM_KRAIT_WFE_FIXUP
+ select MSM_ULTRASOUND_A
config ARCH_MSM8974
bool "MSM8974"
@@ -355,6 +357,7 @@
select SMP
select MSM_SMP
select CPU_V7
+ select MSM_SCM if SMP
select MSM_GPIOMUX
select MSM_RPM_SMD
select MSM_NATIVE_RESTART
@@ -2337,11 +2340,15 @@
for the platforms that use APRv2.
Say M if you want to enable this module.
-config MSM_ULTRASOUND
- bool "MSM ultrasound support"
- depends on MSM_AUDIO_QDSP6
+config MSM_ULTRASOUND_A
+ bool "QDSP6 HW Ultrasound support"
help
- Enable support for qdsp6/ultrasound.
+ Enable HW ultrasound support in QDSP6.
+ QDSP6 can support HW encoder & decoder and
+ ultrasound processing. It will enable
+ ultrasound data paths between
+ HW and services, calculating input events
+ upon the ultrasound data.
config MSM_RPC_VIBRATOR
bool "RPC based MSM Vibrator Support"
diff --git a/arch/arm/mach-msm/acpuclock-krait.c b/arch/arm/mach-msm/acpuclock-krait.c
index d38396d..a386e78 100644
--- a/arch/arm/mach-msm/acpuclock-krait.c
+++ b/arch/arm/mach-msm/acpuclock-krait.c
@@ -528,7 +528,7 @@
};
/* Initialize a HFPLL at a given rate and enable it. */
-static void __init hfpll_init(struct scalable *sc,
+static void __cpuinit hfpll_init(struct scalable *sc,
const struct core_speed *tgt_s)
{
dev_dbg(drv.dev, "Initializing HFPLL%d\n", sc - drv.scalable);
diff --git a/arch/arm/mach-msm/board-8226.c b/arch/arm/mach-msm/board-8226.c
index b27382f..33f18a2 100644
--- a/arch/arm/mach-msm/board-8226.c
+++ b/arch/arm/mach-msm/board-8226.c
@@ -28,7 +28,6 @@
#endif
#include <asm/mach/map.h>
#include <asm/hardware/gic.h>
-#include <asm/arch_timer.h>
#include <asm/mach/arch.h>
#include <asm/mach/time.h>
#include <mach/board.h>
@@ -41,6 +40,7 @@
#include <mach/socinfo.h>
#include <mach/board.h>
#include <mach/clk-provider.h>
+#include "board-dt.h"
#include "clock.h"
static struct clk_lookup msm_clocks_dummy[] = {
@@ -55,36 +55,10 @@
.size = ARRAY_SIZE(msm_clocks_dummy),
};
-static struct of_device_id irq_match[] __initdata = {
- { .compatible = "qcom,msm-qgic2", .data = gic_of_init, },
- { .compatible = "qcom,msm-gpio", .data = msm_gpio_of_init, },
- {}
-};
-
-static void __init msm8226_dt_timer_init(void)
-{
- arch_timer_of_register();
-}
-
-static struct sys_timer msm8226_dt_timer = {
- .init = msm8226_dt_timer_init
-};
-
-void __init msm8226_init_irq(void)
-{
- of_irq_init(irq_match);
-}
-
void __init msm8226_init(void)
{
msm8226_init_gpiomux();
-
msm_clock_init(&msm_dummy_clock_init_data);
-}
-
-void __init msm8226_dt_init(void)
-{
- msm8226_init();
if (socinfo_init() < 0)
pr_err("%s: socinfo_init() failed\n", __func__);
@@ -100,9 +74,9 @@
DT_MACHINE_START(MSM8226_DT, "Qualcomm MSM 8226 (Flattened Device Tree)")
.map_io = msm_map_msm8226_io,
- .init_irq = msm8226_init_irq,
- .init_machine = msm8226_dt_init,
+ .init_irq = msm_dt_init_irq_nompm,
+ .init_machine = msm8226_init,
.handle_irq = gic_handle_irq,
- .timer = &msm8226_dt_timer,
+ .timer = &msm_dt_timer,
.dt_compat = msm8226_dt_match,
MACHINE_END
diff --git a/arch/arm/mach-msm/board-9625.c b/arch/arm/mach-msm/board-9625.c
index 27e91ae..49f2561 100644
--- a/arch/arm/mach-msm/board-9625.c
+++ b/arch/arm/mach-msm/board-9625.c
@@ -35,6 +35,7 @@
#include <mach/msm_memtypes.h>
#include <mach/msm_iomap.h>
#include <mach/msm_smd.h>
+#include <mach/scm.h>
#include <mach/rpm-smd.h>
#include <mach/rpm-regulator-smd.h>
#include <mach/mpm.h>
@@ -44,6 +45,9 @@
#include "spm.h"
#define MSM_KERNEL_EBI_SIZE 0x51000
+#define SCM_SVC_L2CC_PL310 16
+#define L2CC_PL310_CTRL_ID 1
+#define L2CC_PL310_ON 1
static struct memtype_reserve msm9625_reserve_table[] __initdata = {
[MEMTYPE_SMI] = {
@@ -133,7 +137,8 @@
void __init msm9625_init_irq(void)
{
struct device_node *node;
- l2x0_of_init(L2CC_AUX_CTRL, L2X0_AUX_CTRL_MASK);
+ scm_call_atomic1(SCM_SVC_L2CC_PL310, L2CC_PL310_CTRL_ID, L2CC_PL310_ON);
+ l2x0_of_init(0, ~0UL);
of_irq_init(irq_match);
node = of_find_matching_node(NULL, mpm_match);
diff --git a/arch/arm/mach-msm/board-dt.c b/arch/arm/mach-msm/board-dt.c
index 15a544a..3654de8 100644
--- a/arch/arm/mach-msm/board-dt.c
+++ b/arch/arm/mach-msm/board-dt.c
@@ -57,3 +57,8 @@
if (node)
of_mpm_init(node);
}
+
+void __init msm_dt_init_irq_nompm(void)
+{
+ of_irq_init(irq_match);
+}
diff --git a/arch/arm/mach-msm/board-dt.h b/arch/arm/mach-msm/board-dt.h
index 31143a5..16a6135 100644
--- a/arch/arm/mach-msm/board-dt.h
+++ b/arch/arm/mach-msm/board-dt.h
@@ -12,3 +12,4 @@
extern struct sys_timer msm_dt_timer;
void __init msm_dt_init_irq(void);
+void __init msm_dt_init_irq_nompm(void);
diff --git a/arch/arm/mach-msm/devices-msm7x27a.c b/arch/arm/mach-msm/devices-msm7x27a.c
index 9943812..2c49b21 100644
--- a/arch/arm/mach-msm/devices-msm7x27a.c
+++ b/arch/arm/mach-msm/devices-msm7x27a.c
@@ -1963,6 +1963,41 @@
.size = ARRAY_SIZE(msm_clock_8625_dummy),
};
+
+static int __init msm_gpio_config_gps(void)
+{
+ unsigned int gps_gpio = 7;
+ int ret = 0;
+
+ if (!machine_is_msm8625_evb())
+ return ret;
+
+ ret = gpio_tlmm_config(GPIO_CFG(gps_gpio, 0, GPIO_CFG_OUTPUT,
+ GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA), GPIO_CFG_ENABLE);
+ if (ret < 0) {
+ pr_err("gpio tlmm failed for gpio-%d\n", gps_gpio);
+ return ret;
+ }
+
+ ret = gpio_request(gps_gpio, "gnss-gpio");
+ if (ret < 0) {
+ pr_err("failed to request gpio-%d\n", gps_gpio);
+ return ret;
+ }
+
+ ret = gpio_direction_input(gps_gpio);
+ if (ret < 0) {
+ pr_err("failed to change direction for gpio-%d\n", gps_gpio);
+ return ret;
+ }
+
+ ret = gpio_export(gps_gpio, true);
+ if (ret < 0)
+ pr_err("failed to export gpio for user\n");
+
+ return ret;
+}
+
int __init msm7x2x_misc_init(void)
{
if (machine_is_msm8625_rumi3()) {
@@ -1994,6 +2029,9 @@
platform_device_register(&pl310_erp_device);
+ if (msm_gpio_config_gps() < 0)
+ pr_err("Error for gpio config for GPS gpio\n");
+
return 0;
}
diff --git a/arch/arm/mach-msm/include/mach/msm72k_otg.h b/arch/arm/mach-msm/include/mach/msm72k_otg.h
index 623de2a..50e2936 100644
--- a/arch/arm/mach-msm/include/mach/msm72k_otg.h
+++ b/arch/arm/mach-msm/include/mach/msm72k_otg.h
@@ -154,6 +154,7 @@
struct work_struct otg_resume_work;
struct notifier_block usbdev_nb;
struct msm_xo_voter *xo_handle; /*handle to vote for TCXO D1 buffer*/
+ unsigned curr_power;
#ifdef CONFIG_USB_MSM_ACA
struct timer_list id_timer; /* drives id_status polling */
unsigned b_max_power; /* ACA: max power of accessory*/
diff --git a/arch/arm/mach-msm/include/mach/ocmem.h b/arch/arm/mach-msm/include/mach/ocmem.h
index 904de5e..cb8aae0 100644
--- a/arch/arm/mach-msm/include/mach/ocmem.h
+++ b/arch/arm/mach-msm/include/mach/ocmem.h
@@ -134,6 +134,9 @@
int ocmem_unmap(int client_id, struct ocmem_buf *buffer,
struct ocmem_map_list *list);
+int ocmem_dump(int client_id, struct ocmem_buf *buffer,
+ unsigned long dst_phys_addr);
+
/* Priority Enforcement APIs */
int ocmem_evict(int client_id);
diff --git a/arch/arm/mach-msm/include/mach/ocmem_priv.h b/arch/arm/mach-msm/include/mach/ocmem_priv.h
index 09dfac0..0b30c26 100644
--- a/arch/arm/mach-msm/include/mach/ocmem_priv.h
+++ b/arch/arm/mach-msm/include/mach/ocmem_priv.h
@@ -56,6 +56,8 @@
NR_TRANSFER_FAILS,
NR_EVICTIONS,
NR_RESTORES,
+ NR_DUMP_REQUESTS,
+ NR_DUMP_COMPLETE,
NR_OCMEM_ZSTAT_ITEMS,
};
@@ -198,6 +200,7 @@
int process_evict(int);
int process_restore(int);
int process_shrink(int, struct ocmem_handle *, unsigned long);
+int process_dump(int, struct ocmem_handle *, unsigned long);
int ocmem_rdm_transfer(int, struct ocmem_map_list *,
unsigned long, int);
int ocmem_clear(unsigned long, unsigned long);
diff --git a/arch/arm/mach-msm/include/mach/qdsp6v2/apr_us.h b/arch/arm/mach-msm/include/mach/qdsp6v2/apr_us.h
index da639ce..22f343c 100644
--- a/arch/arm/mach-msm/include/mach/qdsp6v2/apr_us.h
+++ b/arch/arm/mach-msm/include/mach/qdsp6v2/apr_us.h
@@ -17,20 +17,6 @@
/* ======================================================================= */
/* Session Level commands */
-#define USM_SESSION_CMD_MEMORY_MAP 0x00012304
-struct usm_stream_cmd_memory_map {
- struct apr_hdr hdr;
- u32 buf_add;
- u32 buf_size;
- u16 mempool_id;
- u16 reserved;
-} __packed;
-
-#define USM_SESSION_CMD_MEMORY_UNMAP 0x00012305
-struct usm_stream_cmd_memory_unmap {
- struct apr_hdr hdr;
- u32 buf_add;
-} __packed;
#define USM_SESSION_CMD_RUN 0x00012306
struct usm_stream_cmd_run {
@@ -113,31 +99,6 @@
u8 transp_data[USM_MAX_CFG_DATA_SIZE];
} __packed;
-
-#define USM_DATA_CMD_READ 0x0001230E
-struct usm_stream_cmd_read {
- struct apr_hdr hdr;
- u32 buf_add;
- u32 buf_size;
- u32 uid;
- u32 counter;
-} __packed;
-
-#define USM_DATA_EVENT_READ_DONE 0x0001230F
-
-#define USM_DATA_CMD_WRITE 0x00011273
-struct usm_stream_cmd_write {
- struct apr_hdr hdr;
- u32 buf_add;
- u32 buf_size;
- u32 uid;
- u32 msw_ts;
- u32 lsw_ts;
- u32 flags;
-} __packed;
-
-#define USM_DATA_EVENT_WRITE_DONE 0x00011274
-
/* Start/stop US signal detection */
#define USM_SESSION_CMD_SIGNAL_DETECT_MODE 0x00012719
diff --git a/arch/arm/mach-msm/include/mach/qdsp6v2/apr_us_a.h b/arch/arm/mach-msm/include/mach/qdsp6v2/apr_us_a.h
new file mode 100644
index 0000000..4008698
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/qdsp6v2/apr_us_a.h
@@ -0,0 +1,59 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __APR_US_A_H__
+#define __APR_US_A_H__
+
+#include "apr_us.h"
+
+/* ======================================================================= */
+/* Session Level commands */
+#define USM_SESSION_CMD_MEMORY_MAP 0x00012304
+struct usm_stream_cmd_memory_map {
+ struct apr_hdr hdr;
+ u32 buf_add;
+ u32 buf_size;
+ u16 mempool_id;
+ u16 reserved;
+} __packed;
+
+#define USM_SESSION_CMD_MEMORY_UNMAP 0x00012305
+struct usm_stream_cmd_memory_unmap {
+ struct apr_hdr hdr;
+ u32 buf_add;
+} __packed;
+
+#define USM_DATA_CMD_READ 0x0001230E
+struct usm_stream_cmd_read {
+ struct apr_hdr hdr;
+ u32 buf_add;
+ u32 buf_size;
+ u32 uid;
+ u32 counter;
+} __packed;
+
+#define USM_DATA_EVENT_READ_DONE 0x0001230F
+
+#define USM_DATA_CMD_WRITE 0x00011273
+struct usm_stream_cmd_write {
+ struct apr_hdr hdr;
+ u32 buf_add;
+ u32 buf_size;
+ u32 uid;
+ u32 msw_ts;
+ u32 lsw_ts;
+ u32 flags;
+} __packed;
+
+#define USM_DATA_EVENT_WRITE_DONE 0x00011274
+
+#endif /* __APR_US_A_H__ */
diff --git a/arch/arm/mach-msm/include/mach/socinfo.h b/arch/arm/mach-msm/include/mach/socinfo.h
index 5c88101..34bdc79 100644
--- a/arch/arm/mach-msm/include/mach/socinfo.h
+++ b/arch/arm/mach-msm/include/mach/socinfo.h
@@ -101,6 +101,7 @@
MSM_CPU_8064AB,
MSM_CPU_8930,
MSM_CPU_8930AA,
+ MSM_CPU_8930AB,
MSM_CPU_7X27AA,
MSM_CPU_9615,
MSM_CPU_8974,
@@ -342,6 +343,15 @@
#endif
}
+static inline int cpu_is_msm8930ab(void)
+{
+#ifdef CONFIG_ARCH_MSM8930
+ return read_msm_cpu_type() == MSM_CPU_8930AB;
+#else
+ return 0;
+#endif
+}
+
static inline int cpu_is_msm8627(void)
{
/* 8930 and 8627 will share the same CONFIG_ARCH type unless otherwise needed */
@@ -449,7 +459,8 @@
static inline int soc_class_is_msm8930(void)
{
- return cpu_is_msm8930() || cpu_is_msm8930aa() || cpu_is_msm8627();
+ return cpu_is_msm8930() || cpu_is_msm8930aa() || cpu_is_msm8930ab() ||
+ cpu_is_msm8627();
}
#endif
diff --git a/arch/arm/mach-msm/lpm_resources.c b/arch/arm/mach-msm/lpm_resources.c
index 2db92f3..255cd46 100644
--- a/arch/arm/mach-msm/lpm_resources.c
+++ b/arch/arm/mach-msm/lpm_resources.c
@@ -695,6 +695,10 @@
{
struct msm_lpm_resource *rs = &msm_lpm_l2;
switch (action) {
+ case CPU_UP_PREPARE:
+ case CPU_UP_PREPARE_FROZEN:
+ rs->rs_data.value = MSM_LPM_L2_CACHE_ACTIVE;
+ break;
case CPU_ONLINE_FROZEN:
case CPU_ONLINE:
if (num_online_cpus() > 1)
diff --git a/arch/arm/mach-msm/ocmem.c b/arch/arm/mach-msm/ocmem.c
index 793fcc5..7829d8d 100644
--- a/arch/arm/mach-msm/ocmem.c
+++ b/arch/arm/mach-msm/ocmem.c
@@ -82,6 +82,8 @@
"Transfer failures",
"Evictions",
"Restorations",
+ "Dump requests",
+ "Dump completed",
};
struct ocmem_quota_table {
diff --git a/arch/arm/mach-msm/ocmem_api.c b/arch/arm/mach-msm/ocmem_api.c
index 6e094fd..689e015 100644
--- a/arch/arm/mach-msm/ocmem_api.c
+++ b/arch/arm/mach-msm/ocmem_api.c
@@ -399,6 +399,36 @@
}
EXPORT_SYMBOL(ocmem_unmap);
+int ocmem_dump(int client_id, struct ocmem_buf *buffer,
+ unsigned long dst_phys_addr)
+{
+ int ret = 0;
+ struct ocmem_handle *handle = NULL;
+
+ if (!check_id(client_id)) {
+ pr_err("ocmem: Invalid client id: %d\n", client_id);
+ return -EINVAL;
+ }
+
+ if (!zone_active(client_id)) {
+ pr_err("ocmem: Client id: %s (id: %d) not allowed to use OCMEM\n",
+ get_name(client_id), client_id);
+ return -EINVAL;
+ }
+
+ if (!buffer) {
+ pr_err("ocmem: Invalid buffer\n");
+ return -EINVAL;
+ }
+
+ handle = buffer_to_handle(buffer);
+ mutex_lock(&handle->handle_mutex);
+ ret = process_dump(client_id, handle, dst_phys_addr);
+ mutex_unlock(&handle->handle_mutex);
+ return ret;
+}
+EXPORT_SYMBOL(ocmem_dump);
+
unsigned long get_max_quota(int client_id)
{
if (!check_id(client_id)) {
diff --git a/arch/arm/mach-msm/ocmem_sched.c b/arch/arm/mach-msm/ocmem_sched.c
index e8854d5..c380c54 100644
--- a/arch/arm/mach-msm/ocmem_sched.c
+++ b/arch/arm/mach-msm/ocmem_sched.c
@@ -65,6 +65,7 @@
MAX_OCMEM_PRIO = PRIO_OCMEM + 1,
};
+static void __iomem *ocmem_vaddr;
static struct list_head sched_queue[MAX_OCMEM_PRIO];
static struct mutex sched_queue_mutex;
@@ -1670,6 +1671,34 @@
return -EINVAL;
}
+static int do_dump(struct ocmem_req *req, unsigned long addr)
+{
+
+ void __iomem *req_vaddr;
+ unsigned long offset = 0x0;
+
+ down_write(&req->rw_sem);
+
+ offset = phys_to_offset(req->req_start);
+
+ req_vaddr = ocmem_vaddr + offset;
+
+ if (!req_vaddr)
+ goto err_do_dump;
+
+ pr_debug("Dumping client %s buffer ocmem p: %lx (v: %p) to ddr %lx\n",
+ get_name(req->owner), req->req_start,
+ req_vaddr, addr);
+
+ memcpy((void *)addr, req_vaddr, req->req_sz);
+
+ up_write(&req->rw_sem);
+ return 0;
+err_do_dump:
+ up_write(&req->rw_sem);
+ return -EINVAL;
+}
+
int process_restore(int id)
{
struct ocmem_req *req = NULL;
@@ -1828,6 +1857,38 @@
return -EINVAL;
}
+int process_dump(int id, struct ocmem_handle *handle, unsigned long addr)
+{
+ struct ocmem_req *req = NULL;
+ int rc = 0;
+
+ req = handle_to_req(handle);
+
+ if (!req)
+ return -EINVAL;
+
+ if (!is_mapped(req)) {
+ pr_err("Buffer is not mapped\n");
+ goto dump_error;
+ }
+
+ inc_ocmem_stat(zone_of(req), NR_DUMP_REQUESTS);
+
+ mutex_lock(&sched_mutex);
+ rc = do_dump(req, addr);
+ mutex_unlock(&sched_mutex);
+
+ if (rc < 0)
+ goto dump_error;
+
+ inc_ocmem_stat(zone_of(req), NR_DUMP_COMPLETE);
+ return 0;
+
+dump_error:
+ pr_err("Dumping OCMEM memory failed for client %d\n", id);
+ return -EINVAL;
+}
+
static void ocmem_sched_wk_func(struct work_struct *work)
{
@@ -1906,6 +1967,7 @@
pdata = platform_get_drvdata(pdev);
mutex_init(&sched_mutex);
mutex_init(&sched_queue_mutex);
+ ocmem_vaddr = pdata->vbase;
for (i = MIN_PRIO; i < MAX_OCMEM_PRIO; i++)
INIT_LIST_HEAD(&sched_queue[i]);
diff --git a/arch/arm/mach-msm/pm-8x60.c b/arch/arm/mach-msm/pm-8x60.c
index 5c40750..f55d509 100644
--- a/arch/arm/mach-msm/pm-8x60.c
+++ b/arch/arm/mach-msm/pm-8x60.c
@@ -1071,7 +1071,7 @@
msm_pc_debug_counters_phys = res->start;
WARN_ON(resource_size(res) < SZ_64);
- msm_pc_debug_counters = devm_ioremap(&pdev->dev, res->start,
+ msm_pc_debug_counters = devm_ioremap_nocache(&pdev->dev, res->start,
resource_size(res));
if (!msm_pc_debug_counters)
diff --git a/arch/arm/mach-msm/qdsp6v2/Makefile b/arch/arm/mach-msm/qdsp6v2/Makefile
index ed8cb345..3731722 100644
--- a/arch/arm/mach-msm/qdsp6v2/Makefile
+++ b/arch/arm/mach-msm/qdsp6v2/Makefile
@@ -25,5 +25,5 @@
obj-$(CONFIG_MSM_QDSP6V2_CODECS) += rtac_v2.o q6audio_v2.o q6audio_v2_aio.o
obj-$(CONFIG_MSM_QDSP6V2_CODECS) += audio_mp3.o audio_amrnb.o audio_amrwb.o audio_evrc.o audio_qcelp.o amrwb_in.o
obj-$(CONFIG_MSM_ADSP_LOADER) += adsp-loader.o
-obj-$(CONFIG_MSM_ULTRASOUND) += ultrasound/
+obj-$(CONFIG_MSM_ULTRASOUND_A) += ultrasound/version_a/
obj-m += adsprpc.o
diff --git a/arch/arm/mach-msm/qdsp6v2/ultrasound/Makefile b/arch/arm/mach-msm/qdsp6v2/ultrasound/Makefile
deleted file mode 100644
index 0be1303..0000000
--- a/arch/arm/mach-msm/qdsp6v2/ultrasound/Makefile
+++ /dev/null
@@ -1,2 +0,0 @@
-obj-y += q6usm.o usf.o usfcdev.o
-EXTRA_CFLAGS += -I$(src)/..
diff --git a/arch/arm/mach-msm/qdsp6v2/ultrasound/q6usm.h b/arch/arm/mach-msm/qdsp6v2/ultrasound/q6usm.h
index 1fe71bf..c68ad68 100644
--- a/arch/arm/mach-msm/qdsp6v2/ultrasound/q6usm.h
+++ b/arch/arm/mach-msm/qdsp6v2/ultrasound/q6usm.h
@@ -15,6 +15,11 @@
#include <mach/qdsp6v2/apr_us.h>
+#define Q6USM_EVENT_UNDEF 0
+#define Q6USM_EVENT_READ_DONE 1
+#define Q6USM_EVENT_WRITE_DONE 2
+#define Q6USM_EVENT_SIGNAL_DETECT_RESULT 3
+
/* cyclic buffer with 1 gap support */
#define USM_MIN_BUF_CNT 3
@@ -39,16 +44,6 @@
/* bit 4 represents META enable of encoded data buffer */
#define BUFFER_META_ENABLE 0x0010
-struct us_region {
- dma_addr_t phys;
- /* If == NULL, the region isn't allocated */
- void *data;
- /* number of buffers in the region */
- uint32_t buf_cnt;
- /* size of buffer */
- uint32_t buf_size;
-};
-
struct us_port_data {
dma_addr_t phys;
/* cyclic region of buffers with 1 gap */
@@ -57,15 +52,17 @@
uint32_t buf_cnt;
/* size of buffer */
uint32_t buf_size;
- /* TX: write index */
+ /* write index */
uint32_t dsp_buf;
- /* TX: read index */
+ /* read index */
uint32_t cpu_buf;
/* expected token from dsp */
uint32_t expected_token;
/* read or write locks */
struct mutex lock;
spinlock_t dsp_lock;
+ /* extended parameters, related to q6 variants */
+ void *ext;
};
struct us_client {
@@ -97,19 +94,11 @@
void *priv);
int q6usm_open_read(struct us_client *usc, uint32_t format);
void q6usm_us_client_free(struct us_client *usc);
-int q6usm_memory_map(struct us_client *usc, uint32_t buf_add,
- int dir, uint32_t bufsz, uint32_t bufcnt);
-int q6usm_memory_unmap(struct us_client *usc, uint32_t buf_add,
- int dir);
-
-uint32_t q6usm_get_ready_data(int dir, struct us_client *usc);
uint32_t q6usm_get_virtual_address(int dir, struct us_client *usc,
struct vm_area_struct *vms);
-
int q6usm_open_write(struct us_client *usc, uint32_t format);
int q6usm_write(struct us_client *usc, uint32_t write_ind);
-bool q6usm_is_write_buf_full(struct us_client *usc, uint32_t* free_region);
-
+bool q6usm_is_write_buf_full(struct us_client *usc, uint32_t *free_region);
int q6usm_set_us_detection(struct us_client *usc,
struct usm_session_cmd_detect_info *detect_info,
uint16_t detect_info_size);
diff --git a/arch/arm/mach-msm/qdsp6v2/ultrasound/usf.c b/arch/arm/mach-msm/qdsp6v2/ultrasound/usf.c
index a973b92..d00eae8 100644
--- a/arch/arm/mach-msm/qdsp6v2/ultrasound/usf.c
+++ b/arch/arm/mach-msm/qdsp6v2/ultrasound/usf.c
@@ -27,8 +27,8 @@
#include "usfcdev.h"
/* The driver version*/
-#define DRV_VERSION "1.4.0"
-#define USF_VERSION_ID 0x0140
+#define DRV_VERSION "1.4.1"
+#define USF_VERSION_ID 0x0141
/* Standard timeout in the asynchronous ops */
#define USF_TIMEOUT_JIFFIES (1*HZ) /* 1 sec */
@@ -351,7 +351,7 @@
}
switch (opcode) {
- case USM_DATA_EVENT_WRITE_DONE:
+ case Q6USM_EVENT_WRITE_DONE:
wake_up(&usf_xx->wait);
break;
default:
@@ -370,14 +370,14 @@
}
switch (opcode) {
- case USM_DATA_EVENT_READ_DONE:
+ case Q6USM_EVENT_READ_DONE:
if (token == USM_WRONG_TOKEN)
usf_xx->usf_state = USF_ERROR_STATE;
usf_xx->new_region = token;
wake_up(&usf_xx->wait);
break;
- case USM_SESSION_EVENT_SIGNAL_DETECT_RESULT:
+ case Q6USM_EVENT_SIGNAL_DETECT_RESULT:
usf_xx->us_detect_type = (payload[APR_US_DETECT_RESULT_IND]) ?
USF_US_DETECT_YES :
USF_US_DETECT_NO;
@@ -1043,8 +1043,7 @@
if ((usf_xx->usf_state != USF_WORK_STATE) ||
(rc == -ERESTARTSYS)) {
- pr_err("%s: Getting ready region failed "
- "work state[%d]; rc[%d]\n",
+ pr_err("%s: Get ready region failure; state[%d]; rc[%d]\n",
__func__, usf_xx->usf_state, rc);
return -EINTR;
}
@@ -1459,4 +1458,3 @@
device_initcall(usf_init);
MODULE_DESCRIPTION("Ultrasound framework driver");
-MODULE_VERSION(DRV_VERSION);
diff --git a/arch/arm/mach-msm/qdsp6v2/ultrasound/version_a/Makefile b/arch/arm/mach-msm/qdsp6v2/ultrasound/version_a/Makefile
new file mode 100644
index 0000000..38d7d51
--- /dev/null
+++ b/arch/arm/mach-msm/qdsp6v2/ultrasound/version_a/Makefile
@@ -0,0 +1,2 @@
+obj-y += q6usm_a.o ../usf.o ../usfcdev.o
+ccflags-y := -I$(src)/.. -I$(src)/../..
diff --git a/arch/arm/mach-msm/qdsp6v2/ultrasound/q6usm.c b/arch/arm/mach-msm/qdsp6v2/ultrasound/version_a/q6usm_a.c
similarity index 96%
rename from arch/arm/mach-msm/qdsp6v2/ultrasound/q6usm.c
rename to arch/arm/mach-msm/qdsp6v2/ultrasound/version_a/q6usm_a.c
index dce3812..5d30eb1 100644
--- a/arch/arm/mach-msm/qdsp6v2/ultrasound/q6usm.c
+++ b/arch/arm/mach-msm/qdsp6v2/ultrasound/version_a/q6usm_a.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -19,11 +19,9 @@
#include <linux/slab.h>
#include <linux/msm_audio.h>
#include <sound/apr_audio.h>
+#include <mach/qdsp6v2/apr_us_a.h>
#include "q6usm.h"
-/* The driver version*/
-#define DRV_VERSION "1.2"
-
#define SESSION_MAX 0x02 /* aDSP:USM limit */
#define READDONE_IDX_STATUS 0
@@ -58,6 +56,96 @@
static struct usm_mmap this_mmap;
+static void q6usm_add_mmaphdr(struct us_client *usc, struct apr_hdr *hdr,
+ uint32_t pkt_size, bool cmd_flg)
+{
+ hdr->hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, \
+ APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
+ hdr->src_port = 0;
+ hdr->dest_port = 0;
+ if (cmd_flg) {
+ hdr->token = 0;
+ atomic_set(&this_mmap.cmd_state, 1);
+ }
+ hdr->pkt_size = pkt_size;
+ return;
+}
+
+static int q6usm_memory_map(struct us_client *usc, uint32_t buf_add, int dir,
+ uint32_t bufsz, uint32_t bufcnt)
+{
+ struct usm_stream_cmd_memory_map mem_map;
+ int rc = 0;
+
+ if ((usc == NULL) || (usc->apr == NULL) || (this_mmap.apr == NULL)) {
+ pr_err("%s: APR handle NULL\n", __func__);
+ return -EINVAL;
+ }
+
+ q6usm_add_mmaphdr(usc, &mem_map.hdr,
+ sizeof(struct usm_stream_cmd_memory_map), true);
+ mem_map.hdr.opcode = USM_SESSION_CMD_MEMORY_MAP;
+
+ mem_map.buf_add = buf_add;
+ mem_map.buf_size = bufsz * bufcnt;
+ mem_map.mempool_id = 0;
+
+ pr_debug("%s: buf add[%x] buf_add_parameter[%x]\n",
+ __func__, mem_map.buf_add, buf_add);
+
+ rc = apr_send_pkt(this_mmap.apr, (uint32_t *) &mem_map);
+ if (rc < 0) {
+ pr_err("%s: mem_map op[0x%x]rc[%d]\n",
+ __func__, mem_map.hdr.opcode, rc);
+ goto fail_cmd;
+ }
+
+ rc = wait_event_timeout(this_mmap.cmd_wait,
+ (atomic_read(&this_mmap.cmd_state) == 0),
+ Q6USM_TIMEOUT_JIFFIES);
+ if (!rc) {
+ rc = -ETIME;
+ pr_err("%s: timeout. waited for memory_map\n", __func__);
+ } else
+ rc = 0;
+fail_cmd:
+ return rc;
+}
+
+int q6usm_memory_unmap(struct us_client *usc, uint32_t buf_add, int dir)
+{
+ struct usm_stream_cmd_memory_unmap mem_unmap;
+ int rc = 0;
+
+ if ((usc == NULL) || (usc->apr == NULL) || (this_mmap.apr == NULL)) {
+ pr_err("%s: APR handle NULL\n", __func__);
+ return -EINVAL;
+ }
+
+ q6usm_add_mmaphdr(usc, &mem_unmap.hdr,
+ sizeof(struct usm_stream_cmd_memory_unmap), true);
+ mem_unmap.hdr.opcode = USM_SESSION_CMD_MEMORY_UNMAP;
+ mem_unmap.buf_add = buf_add;
+
+ rc = apr_send_pkt(this_mmap.apr, (uint32_t *) &mem_unmap);
+ if (rc < 0) {
+ pr_err("%s:mem_unmap op[0x%x]rc[%d]\n",
+ __func__, mem_unmap.hdr.opcode, rc);
+ goto fail_cmd;
+ }
+
+ rc = wait_event_timeout(this_mmap.cmd_wait,
+ (atomic_read(&this_mmap.cmd_state) == 0),
+ Q6USM_TIMEOUT_JIFFIES);
+ if (!rc) {
+ rc = -ETIME;
+ pr_err("%s: timeout. waited for memory_map\n", __func__);
+ } else
+ rc = 0;
+fail_cmd:
+ return rc;
+}
+
static int q6usm_session_alloc(struct us_client *usc)
{
int ind = 0;
@@ -276,10 +364,11 @@
uint32_t token;
uint32_t *payload = data->payload;
- pr_debug("%s: ptr0[0x%x]; ptr1[0x%x]; opcode[0x%x];"
- "token[0x%x]; payload_s[%d]; src[%d]; dest[%d];\n",
- __func__, payload[0], payload[1], data->opcode, data->token,
- data->payload_size, data->src_port, data->dest_port);
+ pr_debug("%s: ptr0[0x%x]; ptr1[0x%x]; opcode[0x%x]\n",
+ __func__, payload[0], payload[1], data->opcode);
+ pr_debug("%s: token[0x%x]; payload_size[%d]; src[%d]; dest[%d];\n",
+ __func__, data->token, data->payload_size,
+ data->src_port, data->dest_port);
if (data->opcode == APR_BASIC_RSP_RESULT) {
/* status field check */
@@ -315,6 +404,7 @@
unsigned long dsp_flags;
uint32_t *payload = data->payload;
uint32_t token = data->token;
+ uint32_t opcode = Q6USM_EVENT_UNDEF;
if (usc == NULL) {
pr_err("%s: client info is NULL\n", __func__);
@@ -363,6 +453,7 @@
case USM_DATA_EVENT_READ_DONE: {
struct us_port_data *port = &usc->port[OUT];
+ opcode = Q6USM_EVENT_READ_DONE;
spin_lock_irqsave(&port->dsp_lock, dsp_flags);
if (payload[READDONE_IDX_STATUS]) {
pr_err("%s: wrong READDONE[%d]; token[%d]\n",
@@ -408,6 +499,7 @@
case USM_DATA_EVENT_WRITE_DONE: {
struct us_port_data *port = &usc->port[IN];
+ opcode = Q6USM_EVENT_WRITE_DONE;
if (payload[WRITEDONE_IDX_STATUS]) {
pr_err("%s: wrong WRITEDONE_IDX_STATUS[%d]\n",
__func__,
@@ -428,6 +520,7 @@
pr_debug("%s: US detect result: result=%d",
__func__,
payload[0]);
+ opcode = Q6USM_EVENT_SIGNAL_DETECT_RESULT;
break;
} /* case USM_SESSION_EVENT_SIGNAL_DETECT_RESULT */
@@ -438,21 +531,12 @@
} /* switch */
if (usc->cb)
- usc->cb(data->opcode, token,
+ usc->cb(opcode, token,
data->payload, usc->priv);
return 0;
}
-uint32_t q6usm_get_ready_data(int dir, struct us_client *usc)
-{
- uint32_t ret = 0xffffffff;
-
- if ((usc != NULL) && ((dir == IN) || (dir == OUT)))
- ret = usc->port[dir].dsp_buf;
- return ret;
-}
-
uint32_t q6usm_get_virtual_address(int dir,
struct us_client *usc,
struct vm_area_struct *vms)
@@ -490,21 +574,6 @@
return;
}
-static void q6usm_add_mmaphdr(struct us_client *usc, struct apr_hdr *hdr,
- uint32_t pkt_size, bool cmd_flg)
-{
- hdr->hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, \
- APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
- hdr->src_port = 0;
- hdr->dest_port = 0;
- if (cmd_flg) {
- hdr->token = 0;
- atomic_set(&this_mmap.cmd_state, 1);
- }
- hdr->pkt_size = pkt_size;
- return;
-}
-
static uint32_t q6usm_ext2int_format(uint32_t ext_format)
{
uint32_t int_format = INVALID_FORMAT;
@@ -573,7 +642,7 @@
}
-int q6usm_enc_cfg_blk(struct us_client *usc, struct us_encdec_cfg* us_cfg)
+int q6usm_enc_cfg_blk(struct us_client *usc, struct us_encdec_cfg *us_cfg)
{
uint32_t int_format = INVALID_FORMAT;
struct usm_stream_cmd_encdec_cfg_blk enc_cfg_obj;
@@ -849,80 +918,6 @@
}
-int q6usm_memory_map(struct us_client *usc, uint32_t buf_add, int dir,
- uint32_t bufsz, uint32_t bufcnt)
-{
- struct usm_stream_cmd_memory_map mem_map;
- int rc = 0;
-
- if ((usc == NULL) || (usc->apr == NULL) || (this_mmap.apr == NULL)) {
- pr_err("%s: APR handle NULL\n", __func__);
- return -EINVAL;
- }
-
- q6usm_add_mmaphdr(usc, &mem_map.hdr,
- sizeof(struct usm_stream_cmd_memory_map), true);
- mem_map.hdr.opcode = USM_SESSION_CMD_MEMORY_MAP;
-
- mem_map.buf_add = buf_add;
- mem_map.buf_size = bufsz * bufcnt;
- mem_map.mempool_id = 0;
-
- pr_debug("%s: buf add[%x] buf_add_parameter[%x]\n",
- __func__, mem_map.buf_add, buf_add);
-
- rc = apr_send_pkt(this_mmap.apr, (uint32_t *) &mem_map);
- if (rc < 0) {
- pr_err("%s: mem_map op[0x%x]rc[%d]\n",
- __func__, mem_map.hdr.opcode, rc);
- goto fail_cmd;
- }
-
- rc = wait_event_timeout(this_mmap.cmd_wait,
- (atomic_read(&this_mmap.cmd_state) == 0),
- Q6USM_TIMEOUT_JIFFIES);
- if (!rc) {
- rc = -ETIME;
- pr_err("%s: timeout. waited for memory_map\n", __func__);
- } else
- rc = 0;
-fail_cmd:
- return rc;
-}
-
-int q6usm_memory_unmap(struct us_client *usc, uint32_t buf_add, int dir)
-{
- struct usm_stream_cmd_memory_unmap mem_unmap;
- int rc = 0;
-
- if ((usc == NULL) || (usc->apr == NULL) || (this_mmap.apr == NULL)) {
- pr_err("%s: APR handle NULL\n", __func__);
- return -EINVAL;
- }
-
- q6usm_add_mmaphdr(usc, &mem_unmap.hdr,
- sizeof(struct usm_stream_cmd_memory_unmap), true);
- mem_unmap.hdr.opcode = USM_SESSION_CMD_MEMORY_UNMAP;
- mem_unmap.buf_add = buf_add;
-
- rc = apr_send_pkt(this_mmap.apr, (uint32_t *) &mem_unmap);
- if (rc < 0) {
- pr_err("%s:mem_unmap op[0x%x]rc[%d]\n",
- __func__, mem_unmap.hdr.opcode, rc);
- goto fail_cmd;
- }
-
- rc = wait_event_timeout(this_mmap.cmd_wait,
- (atomic_read(&this_mmap.cmd_state) == 0),
- Q6USM_TIMEOUT_JIFFIES);
- if (!rc) {
- rc = -ETIME;
- pr_err("%s: timeout. waited for memory_map\n", __func__);
- } else
- rc = 0;
-fail_cmd:
- return rc;
-}
int q6usm_read(struct us_client *usc, uint32_t read_ind)
{
@@ -1057,7 +1052,7 @@
return rc;
}
-bool q6usm_is_write_buf_full(struct us_client *usc, uint32_t* free_region)
+bool q6usm_is_write_buf_full(struct us_client *usc, uint32_t *free_region)
{
struct us_port_data *port = NULL;
u32 cpu_buf = 0;
diff --git a/arch/arm/mach-msm/socinfo.c b/arch/arm/mach-msm/socinfo.c
index 0beb952..b865daa 100644
--- a/arch/arm/mach-msm/socinfo.c
+++ b/arch/arm/mach-msm/socinfo.c
@@ -296,6 +296,12 @@
/* 8064AB IDs */
[153] = MSM_CPU_8064AB,
+ /* 8930AB IDs */
+ [154] = MSM_CPU_8930AB,
+ [155] = MSM_CPU_8930AB,
+ [156] = MSM_CPU_8930AB,
+ [157] = MSM_CPU_8930AB
+
/* Uninitialized IDs are not known to run Linux.
MSM_CPU_UNKNOWN is set to 0 to ensure these IDs are
considered as unknown CPU. */
diff --git a/arch/arm/mach-msm/subsystem_restart.c b/arch/arm/mach-msm/subsystem_restart.c
index bae1ab0..a58f2ab 100644
--- a/arch/arm/mach-msm/subsystem_restart.c
+++ b/arch/arm/mach-msm/subsystem_restart.c
@@ -40,12 +40,68 @@
#include "smd_private.h"
+/**
+ * enum p_subsys_state - state of a subsystem (private)
+ * @SUBSYS_NORMAL: subsystem is operating normally
+ * @SUBSYS_CRASHED: subsystem has crashed and hasn't been shutdown
+ * @SUBSYS_RESTARTING: subsystem has been shutdown and is now restarting
+ *
+ * The 'private' side of the subsytem state used to determine where in the
+ * restart process the subsystem is.
+ */
+enum p_subsys_state {
+ SUBSYS_NORMAL,
+ SUBSYS_CRASHED,
+ SUBSYS_RESTARTING,
+};
+
+/**
+ * enum subsys_state - state of a subsystem (public)
+ * @SUBSYS_OFFLINE: subsystem is offline
+ * @SUBSYS_ONLINE: subsystem is online
+ *
+ * The 'public' side of the subsytem state, exposed to userspace.
+ */
+enum subsys_state {
+ SUBSYS_OFFLINE,
+ SUBSYS_ONLINE,
+};
+
+static const char * const subsys_states[] = {
+ [SUBSYS_OFFLINE] = "OFFLINE",
+ [SUBSYS_ONLINE] = "ONLINE",
+};
+
+/**
+ * struct subsys_tracking - track state of a subsystem or restart order
+ * @p_state: private state of subsystem/order
+ * @state: public state of subsystem/order
+ * @s_lock: protects p_state
+ * @lock: protects subsystem/order callbacks and state
+ *
+ * Tracks the state of a subsystem or a set of subsystems (restart order).
+ * Doing this avoids the need to grab each subsystem's lock and update
+ * each subsystems state when restarting an order.
+ */
+struct subsys_tracking {
+ enum p_subsys_state p_state;
+ spinlock_t s_lock;
+ enum subsys_state state;
+ struct mutex lock;
+};
+
+/**
+ * struct subsys_soc_restart_order - subsystem restart order
+ * @subsystem_list: names of subsystems in this restart order
+ * @count: number of subsystems in order
+ * @track: state tracking and locking
+ * @subsys_ptrs: pointers to subsystems in this restart order
+ */
struct subsys_soc_restart_order {
const char * const *subsystem_list;
int count;
- struct mutex shutdown_lock;
- struct mutex powerup_lock;
+ struct subsys_tracking track;
struct subsys_device *subsys_ptrs[];
};
@@ -55,36 +111,34 @@
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 - subsystem device
+ * @desc: subsystem descriptor
+ * @wake_lock: prevents suspend during subsystem_restart()
+ * @wlname: name of @wake_lock
+ * @work: context for subsystem_restart_wq_func() for this device
+ * @track: state tracking and locking
+ * @notify: subsys notify handle
+ * @dev: device
+ * @owner: module that provides @desc
+ * @count: reference count of subsystem_get()/subsystem_put()
+ * @id: ida
+ * @restart_order: order of other devices this devices restarts with
+ * @dentry: debugfs directory for this device
+ */
struct subsys_device {
struct subsys_desc *desc;
struct wake_lock wake_lock;
char wlname[64];
struct work_struct work;
- spinlock_t restart_lock;
- bool restarting;
+
+ struct subsys_tracking track;
void *notify;
struct device dev;
struct module *owner;
int count;
- enum subsys_state state;
int id;
-
- struct mutex shutdown_lock;
- struct mutex powerup_lock;
-
void *restart_order;
#ifdef CONFIG_DEBUG_FS
struct dentry *dentry;
@@ -105,7 +159,7 @@
static ssize_t state_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
- enum subsys_state state = to_subsys(dev)->state;
+ enum subsys_state state = to_subsys(dev)->track.state;
return snprintf(buf, PAGE_SIZE, "%s\n", subsys_states[state]);
}
@@ -114,14 +168,14 @@
{
unsigned long flags;
- spin_lock_irqsave(&subsys->restart_lock, flags);
- if (subsys->state != state) {
- subsys->state = state;
- spin_unlock_irqrestore(&subsys->restart_lock, flags);
+ spin_lock_irqsave(&subsys->track.s_lock, flags);
+ if (subsys->track.state != state) {
+ subsys->track.state = state;
+ spin_unlock_irqrestore(&subsys->track.s_lock, flags);
sysfs_notify(&subsys->dev.kobj, NULL, "state");
return;
}
- spin_unlock_irqrestore(&subsys->restart_lock, flags);
+ spin_unlock_irqrestore(&subsys->track.s_lock, flags);
}
static struct device_attribute subsys_attrs[] = {
@@ -396,56 +450,27 @@
struct subsys_device, work);
struct subsys_device **list;
struct subsys_desc *desc = dev->desc;
- struct subsys_soc_restart_order *soc_restart_order = NULL;
- struct mutex *powerup_lock;
- struct mutex *shutdown_lock;
+ struct subsys_soc_restart_order *order = dev->restart_order;
+ struct subsys_tracking *track;
unsigned count;
unsigned long flags;
- if (restart_level != RESET_SUBSYS_INDEPENDENT)
- soc_restart_order = dev->restart_order;
-
/*
* It's OK to not take the registration lock at this point.
* This is because the subsystem list inside the relevant
* restart order is not being traversed.
*/
- if (!soc_restart_order) {
+ if (restart_level != RESET_SUBSYS_INDEPENDENT && order) {
+ list = order->subsys_ptrs;
+ count = order->count;
+ track = &order->track;
+ } else {
list = &dev;
count = 1;
- powerup_lock = &dev->powerup_lock;
- shutdown_lock = &dev->shutdown_lock;
- } else {
- list = soc_restart_order->subsys_ptrs;
- count = soc_restart_order->count;
- powerup_lock = &soc_restart_order->powerup_lock;
- shutdown_lock = &soc_restart_order->shutdown_lock;
+ track = &dev->track;
}
- pr_debug("[%p]: Attempting to get shutdown lock!\n", current);
-
- /*
- * Try to acquire shutdown_lock. If this fails, these subsystems are
- * already being restarted - return.
- */
- if (!mutex_trylock(shutdown_lock))
- goto out;
-
- pr_debug("[%p]: Attempting to get powerup lock!\n", current);
-
- /*
- * 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. 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!",
- __func__, current);
-
+ mutex_lock(&track->lock);
do_epoch_check(dev);
/*
@@ -461,13 +486,9 @@
for_each_subsys_device(list, count, NULL, subsystem_shutdown);
send_notification_to_order(list, count, SUBSYS_AFTER_SHUTDOWN);
- /*
- * Now that we've finished shutting down these subsystems, release the
- * shutdown lock. If a subsystem restart request comes in for a
- * subsystem in _this_ restart order after the unlock below, and
- * before the powerup lock is released, panic and bail out.
- */
- mutex_unlock(shutdown_lock);
+ spin_lock_irqsave(&track->s_lock, flags);
+ track->p_state = SUBSYS_RESTARTING;
+ spin_unlock_irqrestore(&track->s_lock, flags);
/* Collect ram dumps for all subsystems in order here */
for_each_subsys_device(list, count, NULL, subsystem_ramdump);
@@ -479,44 +500,46 @@
pr_info("[%p]: Restart sequence for %s completed.\n",
current, desc->name);
- mutex_unlock(powerup_lock);
-
mutex_unlock(&soc_order_reg_lock);
+ mutex_unlock(&track->lock);
- pr_debug("[%p]: Released powerup lock!\n", current);
-
-out:
- spin_lock_irqsave(&dev->restart_lock, flags);
- dev->restarting = false;
+ spin_lock_irqsave(&track->s_lock, flags);
+ track->p_state = SUBSYS_NORMAL;
wake_unlock(&dev->wake_lock);
- spin_unlock_irqrestore(&dev->restart_lock, flags);
+ spin_unlock_irqrestore(&track->s_lock, flags);
}
static void __subsystem_restart_dev(struct subsys_device *dev)
{
struct subsys_desc *desc = dev->desc;
const char *name = dev->desc->name;
+ struct subsys_soc_restart_order *order = dev->restart_order;
+ struct subsys_tracking *track;
unsigned long flags;
+ if (restart_level != RESET_SUBSYS_INDEPENDENT && order)
+ track = &order->track;
+ else
+ track = &dev->track;
+
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.
+ * 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->state != SUBSYS_CRASHED) {
- if (dev->state == SUBSYS_ONLINE && !dev->restarting) {
- dev->restarting = true;
- dev->state = SUBSYS_CRASHED;
+ spin_lock_irqsave(&track->s_lock, flags);
+ if (track->p_state != SUBSYS_CRASHED) {
+ if (dev->track.state == SUBSYS_ONLINE &&
+ track->p_state != SUBSYS_RESTARTING) {
+ track->p_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);
+ spin_unlock_irqrestore(&track->s_lock, flags);
}
int subsystem_restart_dev(struct subsys_device *dev)
@@ -650,8 +673,7 @@
struct subsys_device *subsys = to_subsys(dev);
wake_lock_destroy(&subsys->wake_lock);
- mutex_destroy(&subsys->shutdown_lock);
- mutex_destroy(&subsys->powerup_lock);
+ mutex_destroy(&subsys->track.lock);
ida_simple_remove(&subsys_ida, subsys->id);
kfree(subsys);
}
@@ -670,7 +692,7 @@
subsys->dev.parent = desc->dev;
subsys->dev.bus = &subsys_bus_type;
subsys->dev.release = subsys_device_release;
- subsys->state = SUBSYS_ONLINE; /* Until proper refcounting appears */
+ subsys->track.state = SUBSYS_ONLINE; /* Until proper refcounting */
subsys->notify = subsys_notif_add_subsys(desc->name);
subsys->restart_order = update_restart_order(subsys);
@@ -678,7 +700,7 @@
snprintf(subsys->wlname, sizeof(subsys->wlname), "ssr(%s)", desc->name);
wake_lock_init(&subsys->wake_lock, WAKE_LOCK_SUSPEND, subsys->wlname);
INIT_WORK(&subsys->work, subsystem_restart_wq_func);
- spin_lock_init(&subsys->restart_lock);
+ spin_lock_init(&subsys->track.s_lock);
subsys->id = ida_simple_get(&subsys_ida, 0, 0, GFP_KERNEL);
if (subsys->id < 0) {
@@ -687,8 +709,7 @@
}
dev_set_name(&subsys->dev, "subsys%d", subsys->id);
- mutex_init(&subsys->shutdown_lock);
- mutex_init(&subsys->powerup_lock);
+ mutex_init(&subsys->track.lock);
ret = subsys_debugfs_add(subsys);
if (ret)
@@ -705,8 +726,7 @@
err_register:
subsys_debugfs_remove(subsys);
err_debugfs:
- mutex_destroy(&subsys->shutdown_lock);
- mutex_destroy(&subsys->powerup_lock);
+ mutex_destroy(&subsys->track.lock);
ida_simple_remove(&subsys_ida, subsys->id);
err_ida:
wake_lock_destroy(&subsys->wake_lock);
@@ -721,10 +741,10 @@
return;
if (get_device(&subsys->dev)) {
- mutex_lock(&subsys->powerup_lock);
+ mutex_lock(&subsys->track.lock);
WARN_ON(subsys->count);
device_unregister(&subsys->dev);
- mutex_unlock(&subsys->powerup_lock);
+ mutex_unlock(&subsys->track.lock);
subsys_debugfs_remove(subsys);
put_device(&subsys->dev);
}
@@ -760,13 +780,13 @@
if (cpu_is_msm8x60()) {
for (i = 0; i < ARRAY_SIZE(orders_8x60_all); i++) {
- mutex_init(&orders_8x60_all[i]->powerup_lock);
- mutex_init(&orders_8x60_all[i]->shutdown_lock);
+ mutex_init(&orders_8x60_all[i]->track.lock);
+ spin_lock_init(&orders_8x60_all[i]->track.s_lock);
}
for (i = 0; i < ARRAY_SIZE(orders_8x60_modems); i++) {
- mutex_init(&orders_8x60_modems[i]->powerup_lock);
- mutex_init(&orders_8x60_modems[i]->shutdown_lock);
+ mutex_init(&orders_8x60_modems[i]->track.lock);
+ spin_lock_init(&orders_8x60_modems[i]->track.s_lock);
}
restart_orders = orders_8x60_all;
@@ -779,13 +799,12 @@
}
for (i = 0; i < n_restart_orders; i++) {
- mutex_init(&restart_orders[i]->powerup_lock);
- mutex_init(&restart_orders[i]->shutdown_lock);
+ mutex_init(&restart_orders[i]->track.lock);
+ spin_lock_init(&restart_orders[i]->track.s_lock);
}
- if (restart_orders == NULL || n_restart_orders < 1) {
+ if (restart_orders == NULL || n_restart_orders < 1)
WARN_ON(1);
- }
return 0;
}
diff --git a/drivers/char/diag/diagchar.h b/drivers/char/diag/diagchar.h
index b535d53..a37260b 100644
--- a/drivers/char/diag/diagchar.h
+++ b/drivers/char/diag/diagchar.h
@@ -140,6 +140,7 @@
int ref_count;
struct mutex diagchar_mutex;
wait_queue_head_t wait_q;
+ wait_queue_head_t smd_wait_q;
struct diag_client_map *client_map;
int *data_ready;
int num_clients;
diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c
index 9f7c7ac..c29a1d3f 100644
--- a/drivers/char/diag/diagchar_core.c
+++ b/drivers/char/diag/diagchar_core.c
@@ -1412,6 +1412,7 @@
driver->mask_check = 0;
mutex_init(&driver->diagchar_mutex);
init_waitqueue_head(&driver->wait_q);
+ init_waitqueue_head(&driver->smd_wait_q);
INIT_WORK(&(driver->diag_drain_work), diag_drain_work_fn);
INIT_WORK(&(driver->diag_read_smd_work), diag_read_smd_work_fn);
INIT_WORK(&(driver->diag_read_smd_cntl_work),
diff --git a/drivers/char/diag/diagfwd.c b/drivers/char/diag/diagfwd.c
index e4501f4..d27ebcf 100644
--- a/drivers/char/diag/diagfwd.c
+++ b/drivers/char/diag/diagfwd.c
@@ -115,6 +115,7 @@
return APQ8064_TOOLS_ID;
case MSM_CPU_8930:
case MSM_CPU_8930AA:
+ case MSM_CPU_8930AB:
return MSM8930_TOOLS_ID;
case MSM_CPU_8974:
return MSM8974_TOOLS_ID;
@@ -142,6 +143,7 @@
case MSM_CPU_8064AB:
case MSM_CPU_8930:
case MSM_CPU_8930AA:
+ case MSM_CPU_8930AB:
case MSM_CPU_8627:
case MSM_CPU_9615:
case MSM_CPU_8974:
@@ -220,8 +222,9 @@
void __diag_smd_send_req(void)
{
- void *buf = NULL;
- int *in_busy_ptr = NULL;
+ void *buf = NULL, *temp_buf = NULL;
+ int total_recd = 0, r = 0, pkt_len, *in_busy_ptr = NULL;
+ int loop_count = 0;
struct diag_request *write_ptr_modem = NULL;
if (!driver->in_busy_1) {
@@ -235,27 +238,63 @@
}
if (driver->ch && buf) {
- int r = smd_read_avail(driver->ch);
+ temp_buf = buf;
+ pkt_len = smd_cur_packet_size(driver->ch);
- if (r > IN_BUF_SIZE) {
- if (r < MAX_IN_BUF_SIZE) {
- pr_err("diag: SMD sending in "
- "packets upto %d bytes", r);
- buf = krealloc(buf, r, GFP_KERNEL);
- } else {
- pr_err("diag: SMD sending in "
- "packets more than %d bytes", MAX_IN_BUF_SIZE);
+ while (pkt_len && (pkt_len != total_recd)) {
+ loop_count++;
+ r = smd_read_avail(driver->ch);
+ pr_debug("diag: In %s, received pkt %d %d\n",
+ __func__, r, total_recd);
+ if (!r) {
+ /* Nothing to read from SMD */
+ wait_event(driver->smd_wait_q,
+ ((driver->ch == 0) ||
+ smd_read_avail(driver->ch)));
+ /* If the smd channel is open */
+ if (driver->ch) {
+ pr_debug("diag: In %s, return from wait_event\n",
+ __func__);
+ continue;
+ } else {
+ pr_debug("diag: In %s, return from wait_event ch closed\n",
+ __func__);
+ return;
+ }
+ }
+ total_recd += r;
+ if (total_recd > IN_BUF_SIZE) {
+ if (total_recd < MAX_IN_BUF_SIZE) {
+ pr_err("diag: In %s, SMD sending in packets up to %d bytes\n",
+ __func__, total_recd);
+ buf = krealloc(buf, total_recd,
+ GFP_KERNEL);
+ } else {
+ pr_err("diag: In %s, SMD sending in packets more than %d bytes\n",
+ __func__, MAX_IN_BUF_SIZE);
+ return;
+ }
+ }
+ if (pkt_len < r) {
+ pr_err("diag: In %s, SMD sending incorrect pkt\n",
+ __func__);
return;
}
+ if (pkt_len > r)
+ pr_debug("diag: In %s, SMD sending partial pkt %d %d %d %d\n",
+ __func__, pkt_len, r, total_recd,
+ loop_count);
+ /* keep reading for complete packet */
+ smd_read(driver->ch, temp_buf, r);
+ temp_buf += r;
}
- if (r > 0) {
+
+ if (total_recd > 0) {
if (!buf)
- pr_info("Out of diagmem for Modem\n");
+ pr_err("diag: Out of diagmem for Modem\n");
else {
- APPEND_DEBUG('i');
- smd_read(driver->ch, buf, r);
APPEND_DEBUG('j');
- write_ptr_modem->length = r;
+ write_ptr_modem->length = total_recd;
*in_busy_ptr = 1;
diag_device_write(buf, MODEM_DATA,
write_ptr_modem);
@@ -442,9 +481,10 @@
void __diag_smd_wcnss_send_req(void)
{
- void *buf = NULL;
- int *in_busy_wcnss_ptr = NULL;
+ void *buf = NULL, *temp_buf = NULL;
+ int total_recd = 0, r = 0, pkt_len, *in_busy_wcnss_ptr = NULL;
struct diag_request *write_ptr_wcnss = NULL;
+ int loop_count = 0;
if (!driver->in_busy_wcnss_1) {
buf = driver->buf_in_wcnss_1;
@@ -457,24 +497,64 @@
}
if (driver->ch_wcnss && buf) {
- int r = smd_read_avail(driver->ch_wcnss);
- if (r > IN_BUF_SIZE) {
- if (r < MAX_IN_BUF_SIZE) {
- pr_err("diag: wcnss packets > %d bytes", r);
- buf = krealloc(buf, r, GFP_KERNEL);
- } else {
- pr_err("diag: wcnss pkt > %d", MAX_IN_BUF_SIZE);
+ temp_buf = buf;
+ pkt_len = smd_cur_packet_size(driver->ch_wcnss);
+
+ while (pkt_len && (pkt_len != total_recd)) {
+ loop_count++;
+ r = smd_read_avail(driver->ch_wcnss);
+ pr_debug("diag: In %s, received pkt %d %d\n",
+ __func__, r, total_recd);
+ if (!r) {
+ /* Nothing to read from SMD */
+ wait_event(driver->smd_wait_q,
+ ((driver->ch_wcnss == 0) ||
+ smd_read_avail(driver->ch_wcnss)));
+ /* If the smd channel is open */
+ if (driver->ch_wcnss) {
+ pr_debug("diag: In %s, return from wait_event\n",
+ __func__);
+ continue;
+ } else {
+ pr_debug("diag: In %s, return from wait_event ch_wcnss closed\n",
+ __func__);
+ return;
+ }
+ }
+ total_recd += r;
+ if (total_recd > IN_BUF_SIZE) {
+ if (total_recd < MAX_IN_BUF_SIZE) {
+ pr_err("diag: In %s, SMD sending in packets up to %d bytes\n",
+ __func__, total_recd);
+ buf = krealloc(buf, total_recd,
+ GFP_KERNEL);
+ } else {
+ pr_err("diag: In %s, SMD sending in packets more than %d bytes\n",
+ __func__, MAX_IN_BUF_SIZE);
+ return;
+ }
+ }
+ if (pkt_len < r) {
+ pr_err("diag: In %s, SMD sending incorrect pkt\n",
+ __func__);
return;
}
+ if (pkt_len > r) {
+ pr_debug("diag: In %s, SMD sending partial pkt %d %d %d %d\n",
+ __func__, pkt_len, r, total_recd,
+ loop_count);
+ }
+ /* keep reading for complete packet */
+ smd_read(driver->ch_wcnss, temp_buf, r);
+ temp_buf += r;
}
- if (r > 0) {
+
+ if (total_recd > 0) {
if (!buf) {
- pr_err("Out of diagmem for wcnss\n");
+ pr_err("diag: Out of diagmem for wcnss\n");
} else {
- APPEND_DEBUG('i');
- smd_read(driver->ch_wcnss, buf, r);
APPEND_DEBUG('j');
- write_ptr_wcnss->length = r;
+ write_ptr_wcnss->length = total_recd;
*in_busy_wcnss_ptr = 1;
diag_device_write(buf, WCNSS_DATA,
write_ptr_wcnss);
@@ -488,9 +568,10 @@
void __diag_smd_lpass_send_req(void)
{
- void *buf = NULL;
- int *in_busy_lpass_ptr = NULL;
+ void *buf = NULL, *temp_buf = NULL;
+ int total_recd = 0, r = 0, pkt_len, *in_busy_lpass_ptr = NULL;
struct diag_request *write_ptr_lpass = NULL;
+ int loop_count = 0;
if (!driver->in_busy_lpass_1) {
buf = driver->buf_in_lpass_1;
@@ -503,27 +584,63 @@
}
if (driver->chlpass && buf) {
- int r = smd_read_avail(driver->chlpass);
+ temp_buf = buf;
+ pkt_len = smd_cur_packet_size(driver->chlpass);
- if (r > IN_BUF_SIZE) {
- if (r < MAX_IN_BUF_SIZE) {
- pr_err("diag: SMD sending in "
- "packets upto %d bytes", r);
- buf = krealloc(buf, r, GFP_KERNEL);
- } else {
- pr_err("diag: SMD sending in "
- "packets more than %d bytes", MAX_IN_BUF_SIZE);
+ while (pkt_len && (pkt_len != total_recd)) {
+ loop_count++;
+ r = smd_read_avail(driver->chlpass);
+ pr_debug("diag: In %s, received pkt %d %d\n",
+ __func__, r, total_recd);
+ if (!r) {
+ /* Nothing to read from SMD */
+ wait_event(driver->smd_wait_q,
+ ((driver->chlpass == 0) ||
+ smd_read_avail(driver->chlpass)));
+ /* If the smd channel is open */
+ if (driver->chlpass) {
+ pr_debug("diag: In %s, return from wait_event\n",
+ __func__);
+ continue;
+ } else {
+ pr_debug("diag: In %s, return from wait_event chlpass closed\n",
+ __func__);
+ return;
+ }
+ }
+ total_recd += r;
+ if (total_recd > IN_BUF_SIZE) {
+ if (total_recd < MAX_IN_BUF_SIZE) {
+ pr_err("diag: In %s, SMD sending in packets up to %d bytes\n",
+ __func__, total_recd);
+ buf = krealloc(buf, total_recd,
+ GFP_KERNEL);
+ } else {
+ pr_err("diag: In %s, SMD sending in packets more than %d bytes\n",
+ __func__, MAX_IN_BUF_SIZE);
+ return;
+ }
+ }
+ if (pkt_len < r) {
+ pr_err("diag: In %s, SMD sending incorrect pkt\n",
+ __func__);
return;
}
+ if (pkt_len > r)
+ pr_debug("diag: In %s, SMD sending partial pkt %d %d %d %d\n",
+ __func__, pkt_len, r, total_recd,
+ loop_count);
+ /* keep reading for complete packet */
+ smd_read(driver->chlpass, temp_buf, r);
+ temp_buf += r;
}
- if (r > 0) {
+
+ if (total_recd > 0) {
if (!buf)
- printk(KERN_INFO "Out of diagmem for LPASS\n");
+ pr_err("diag: Out of diagmem for LPASS\n");
else {
- APPEND_DEBUG('i');
- smd_read(driver->chlpass, buf, r);
APPEND_DEBUG('j');
- write_ptr_lpass->length = r;
+ write_ptr_lpass->length = total_recd;
*in_busy_lpass_ptr = 1;
diag_device_write(buf, LPASS_DATA,
write_ptr_lpass);
@@ -1222,14 +1339,16 @@
static void diag_smd_notify(void *ctxt, unsigned event)
{
if (event == SMD_EVENT_CLOSE) {
+ driver->ch = 0;
+ wake_up(&driver->smd_wait_q);
queue_work(driver->diag_cntl_wq,
&(driver->diag_clean_modem_reg_work));
- driver->ch = 0;
return;
} else if (event == SMD_EVENT_OPEN) {
if (ch_temp)
driver->ch = ch_temp;
}
+ wake_up(&driver->smd_wait_q);
queue_work(driver->diag_wq, &(driver->diag_read_smd_work));
}
@@ -1237,14 +1356,16 @@
static void diag_smd_lpass_notify(void *ctxt, unsigned event)
{
if (event == SMD_EVENT_CLOSE) {
+ driver->chlpass = 0;
+ wake_up(&driver->smd_wait_q);
queue_work(driver->diag_cntl_wq,
&(driver->diag_clean_lpass_reg_work));
- driver->chlpass = 0;
return;
} else if (event == SMD_EVENT_OPEN) {
if (chlpass_temp)
driver->chlpass = chlpass_temp;
}
+ wake_up(&driver->smd_wait_q);
queue_work(driver->diag_wq, &(driver->diag_read_smd_lpass_work));
}
#endif
@@ -1252,14 +1373,16 @@
static void diag_smd_wcnss_notify(void *ctxt, unsigned event)
{
if (event == SMD_EVENT_CLOSE) {
+ driver->ch_wcnss = 0;
+ wake_up(&driver->smd_wait_q);
queue_work(driver->diag_cntl_wq,
&(driver->diag_clean_wcnss_reg_work));
- driver->ch_wcnss = 0;
return;
} else if (event == SMD_EVENT_OPEN) {
if (ch_wcnss_temp)
driver->ch_wcnss = ch_wcnss_temp;
}
+ wake_up(&driver->smd_wait_q);
queue_work(driver->diag_wq, &(driver->diag_read_smd_wcnss_work));
}
diff --git a/drivers/media/dvb/mpq/video/mpq_dvb_video.c b/drivers/media/dvb/mpq/video/mpq_dvb_video.c
index bd8c4a4..4628ba7 100644
--- a/drivers/media/dvb/mpq/video/mpq_dvb_video.c
+++ b/drivers/media/dvb/mpq/video/mpq_dvb_video.c
@@ -846,7 +846,6 @@
{
struct vdec_picsize pic_res;
int rc;
- struct video_buffer_req vdec_buf_req;
pic_res.frame_height = 1080;
pic_res.frame_width = 1920;
@@ -864,15 +863,6 @@
DBG("Failed in mpq_int_vid_dec_set_cont_on_reconfig : %d\n",\
rc);
- rc = mpq_int_vid_dec_get_buffer_req(client_ctx, &vdec_buf_req);
- if (rc)
- DBG("Failed in mpq_int_vid_dec_get_buffer_req : %d\n", rc);
-
- vdec_buf_req.num_output_buffers = 12;
- rc = mpq_int_set_out_buffer_req(client_ctx, &vdec_buf_req);
- if (rc)
- DBG("Failed in mpq_int_set_out_buffer_req (15) : %d\n", rc);
-
return rc;
}
@@ -1285,6 +1275,27 @@
return 0;
}
+static int mpq_int_vid_dec_set_buffer_req(struct video_client_ctx *client_ctx,
+ struct video_buffer_req vdec_buf_req)
+{
+ int rc = 0;
+ struct video_buffer_req vdec_req;
+
+ rc = mpq_int_vid_dec_get_buffer_req(client_ctx, &vdec_req);
+ if (rc)
+ DBG("Failed in mpq_int_vid_dec_get_buffer_req : %d\n", rc);
+
+ vdec_req.num_output_buffers = vdec_buf_req.num_output_buffers;
+ DBG(" num_output_buffers Set to %u\n", vdec_buf_req.num_output_buffers);
+ if (!vdec_buf_req.num_output_buffers)
+ return -EINVAL;
+ rc = mpq_int_set_out_buffer_req(client_ctx, &vdec_req);
+ if (rc)
+ DBG("Failed in mpq_int_set_out_buffer_req %d\n", rc);
+
+ return 0;
+}
+
static int mpq_int_vid_dec_set_buffer(struct mpq_dvb_video_inst *dev_inst,
struct video_data_buffer *data_buffer,
enum buffer_dir dir_buffer)
@@ -2006,6 +2017,10 @@
DBG("cmd : VIDEO_CMD_GET_BUFFER_REQ\n");
rc = mpq_int_vid_dec_get_buffer_req(client_ctx, &cmd->buf_req);
break;
+ case VIDEO_CMD_SET_BUFFER_COUNT:
+ DBG("cmd : VIDEO_CMD_SET_BUFFER_COUNT\n");
+ rc = mpq_int_vid_dec_set_buffer_req(client_ctx, cmd->buf_req);
+ break;
case VIDEO_CMD_READ_RAW_OUTPUT:
DBG("cmd : VIDEO_CMD_READ_RAW_OUTPUT\n");
rc = mpq_int_vid_dec_fill_output_buffer(client_ctx,
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index b91f3d1..3aa38d2 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -1502,48 +1502,6 @@
mmc_host_clk_release(host);
}
-static void mmc_poweroff_notify(struct mmc_host *host)
-{
- struct mmc_card *card;
- unsigned int timeout;
- unsigned int notify_type = EXT_CSD_NO_POWER_NOTIFICATION;
- int err = 0;
-
- card = host->card;
- mmc_claim_host(host);
-
- /*
- * Send power notify command only if card
- * is mmc and notify state is powered ON
- */
- if (card && mmc_card_mmc(card) &&
- (card->poweroff_notify_state == MMC_POWERED_ON)) {
-
- if (host->power_notify_type == MMC_HOST_PW_NOTIFY_SHORT) {
- notify_type = EXT_CSD_POWER_OFF_SHORT;
- timeout = card->ext_csd.generic_cmd6_time;
- card->poweroff_notify_state = MMC_POWEROFF_SHORT;
- } else {
- notify_type = EXT_CSD_POWER_OFF_LONG;
- timeout = card->ext_csd.power_off_longtime;
- card->poweroff_notify_state = MMC_POWEROFF_LONG;
- }
-
- err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
- EXT_CSD_POWER_OFF_NOTIFICATION,
- notify_type, timeout);
-
- if (err && err != -EBADMSG)
- pr_err("Device failed to respond within %d poweroff time.",
- timeout);
- pr_err("Forcefully powering down the device\n");
-
- /* Set the card state to no notification after the poweroff */
- card->poweroff_notify_state = MMC_NO_POWER_NOTIFICATION;
- }
- mmc_release_host(host);
-}
-
/*
* Apply power to the MMC stack. This is a two-stage process.
* First, we enable power to the card without the clock running.
@@ -1601,30 +1559,11 @@
void mmc_power_off(struct mmc_host *host)
{
- int err = 0;
mmc_host_clk_hold(host);
host->ios.clock = 0;
host->ios.vdd = 0;
- mmc_poweroff_notify(host);
- /*
- * For eMMC 4.5 device send AWAKE command before
- * POWER_OFF_NOTIFY command, because in sleep state
- * eMMC 4.5 devices respond to only RESET and AWAKE cmd
- */
- if (host->card && mmc_card_is_sleep(host->card) &&
- host->bus_ops->resume) {
- err = host->bus_ops->resume(host);
-
- if (!err)
- mmc_poweroff_notify(host);
- else
- pr_warning("%s: error %d during resume",
- mmc_hostname(host), err);
- pr_warning(" (continue with poweroff sequence)\n");
- }
-
/*
* Reset ocr mask to be the highest possible voltage supported for
* this mmc host. This value will be used at next power up.
@@ -2888,7 +2827,6 @@
break;
}
host->rescan_disable = 1;
- host->power_notify_type = MMC_HOST_PW_NOTIFY_SHORT;
spin_unlock_irqrestore(&host->lock, flags);
if (cancel_delayed_work_sync(&host->detect))
wake_unlock(&host->detect_wake_lock);
@@ -2917,7 +2855,6 @@
break;
}
host->rescan_disable = 0;
- host->power_notify_type = MMC_HOST_PW_NOTIFY_LONG;
spin_unlock_irqrestore(&host->lock, flags);
mmc_detect_change(host, 0);
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 50af7fa..47fd9b9 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -1028,7 +1028,7 @@
* so check for success and update the flag
*/
if (!err)
- card->poweroff_notify_state = MMC_POWERED_ON;
+ card->ext_csd.power_off_notification = EXT_CSD_POWER_ON;
}
/*
@@ -1356,6 +1356,35 @@
return err;
}
+static int mmc_can_poweroff_notify(const struct mmc_card *card)
+{
+ return card &&
+ mmc_card_mmc(card) &&
+ (card->ext_csd.power_off_notification == EXT_CSD_POWER_ON);
+}
+
+static int mmc_poweroff_notify(struct mmc_card *card, unsigned int notify_type)
+{
+ unsigned int timeout = card->ext_csd.generic_cmd6_time;
+ int err;
+
+ /* Use EXT_CSD_POWER_OFF_SHORT as default notification type. */
+ if (notify_type == EXT_CSD_POWER_OFF_LONG)
+ timeout = card->ext_csd.power_off_longtime;
+
+ err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
+ EXT_CSD_POWER_OFF_NOTIFICATION,
+ notify_type, timeout);
+ if (err)
+ pr_err("%s: Power Off Notification timed out, %u\n",
+ mmc_hostname(card->host), timeout);
+
+ /* Disable the power off notification after the switch operation. */
+ card->ext_csd.power_off_notification = EXT_CSD_NO_POWER_NOTIFICATION;
+
+ return err;
+}
+
/*
* Host is being removed. Free up the current card.
*/
@@ -1419,11 +1448,11 @@
BUG_ON(!host->card);
mmc_claim_host(host);
- if (mmc_card_can_sleep(host)) {
+ if (mmc_can_poweroff_notify(host->card))
+ err = mmc_poweroff_notify(host->card, EXT_CSD_POWER_OFF_SHORT);
+ else if (mmc_card_can_sleep(host))
err = mmc_card_sleep(host);
- if (!err)
- mmc_card_set_sleep(host->card);
- } else if (!mmc_host_is_spi(host))
+ else if (!mmc_host_is_spi(host))
mmc_deselect_cards(host);
host->card->state &= ~(MMC_STATE_HIGHSPEED | MMC_STATE_HIGHSPEED_200);
mmc_release_host(host);
@@ -1456,7 +1485,6 @@
int ret;
host->card->state &= ~(MMC_STATE_HIGHSPEED | MMC_STATE_HIGHSPEED_200);
- mmc_card_clr_sleep(host->card);
mmc_claim_host(host);
ret = mmc_init_card(host, host->ocr, host->card);
mmc_release_host(host);
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index ab3fc46..bd374f6 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -1790,11 +1790,6 @@
if (host->pdata->quirks & DW_MCI_QUIRK_HIGHSPEED)
mmc->caps |= MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED;
- if (mmc->caps2 & MMC_CAP2_POWEROFF_NOTIFY)
- mmc->power_notify_type = MMC_HOST_PW_NOTIFY_SHORT;
- else
- mmc->power_notify_type = MMC_HOST_PW_NOTIFY_NONE;
-
if (host->pdata->blk_settings) {
mmc->max_segs = host->pdata->blk_settings->max_segs;
mmc->max_blk_size = host->pdata->blk_settings->max_blk_size;
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c
index 29413ab..2fbd804 100644
--- a/drivers/mmc/host/msm_sdcc.c
+++ b/drivers/mmc/host/msm_sdcc.c
@@ -5841,6 +5841,7 @@
mmc->caps2 |= MMC_CAP2_SANITIZE;
mmc->caps2 |= MMC_CAP2_CACHE_CTRL;
mmc->caps2 |= MMC_CAP2_INIT_BKOPS;
+ mmc->caps2 |= MMC_CAP2_POWEROFF_NOTIFY;
if (plat->nonremovable)
mmc->caps |= MMC_CAP_NONREMOVABLE;
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 2f7a2f3..43f7e77 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -2581,15 +2581,6 @@
if (caps[1] & SDHCI_DRIVER_TYPE_D)
mmc->caps |= MMC_CAP_DRIVER_TYPE_D;
- /*
- * If Power Off Notify capability is enabled by the host,
- * set notify to short power off notify timeout value.
- */
- if (mmc->caps2 & MMC_CAP2_POWEROFF_NOTIFY)
- mmc->power_notify_type = MMC_HOST_PW_NOTIFY_SHORT;
- else
- mmc->power_notify_type = MMC_HOST_PW_NOTIFY_NONE;
-
/* Initial value for re-tuning timer count */
host->tuning_count = (caps[1] & SDHCI_RETUNING_TIMER_COUNT_MASK) >>
SDHCI_RETUNING_TIMER_COUNT_SHIFT;
diff --git a/drivers/power/qpnp-charger.c b/drivers/power/qpnp-charger.c
index 8d5244b..ef555f7 100644
--- a/drivers/power/qpnp-charger.c
+++ b/drivers/power/qpnp-charger.c
@@ -1145,6 +1145,10 @@
goto fail_chg_enable;
}
+ /* Get the charging-disabled property */
+ charging_disabled = of_property_read_bool(spmi->dev.of_node,
+ "qcom,chg-charging-disabled");
+
spmi_for_each_container_dev(spmi_resource, spmi) {
if (!spmi_resource) {
pr_err("qpnp_chg: spmi resource absent\n");
@@ -1278,6 +1282,8 @@
qpnp_chg_charge_en(chip, 1);
the_chip = chip;
+ qpnp_chg_charge_dis(chip, charging_disabled);
+
pr_info("Probe success !\n");
return 0;
@@ -1293,7 +1299,6 @@
qpnp_charger_remove(struct spmi_device *spmi)
{
struct qpnp_chg_chip *chip = dev_get_drvdata(&spmi->dev);
-
dev_set_drvdata(&spmi->dev, NULL);
kfree(chip);
diff --git a/drivers/slimbus/slim-msm-ctrl.c b/drivers/slimbus/slim-msm-ctrl.c
index e2f37cc..58a1d66 100644
--- a/drivers/slimbus/slim-msm-ctrl.c
+++ b/drivers/slimbus/slim-msm-ctrl.c
@@ -1257,7 +1257,7 @@
else
clk_prepare_enable(dev->hclk);
- ret = msm_slim_sps_init(dev, bam_mem, MGR_STATUS);
+ ret = msm_slim_sps_init(dev, bam_mem, MGR_STATUS, false);
if (ret != 0) {
dev_err(dev->dev, "error SPS init\n");
goto err_sps_init_failed;
diff --git a/drivers/slimbus/slim-msm.c b/drivers/slimbus/slim-msm.c
index 8a1ea84..7cd34d3 100644
--- a/drivers/slimbus/slim-msm.c
+++ b/drivers/slimbus/slim-msm.c
@@ -494,7 +494,7 @@
/* Registers BAM h/w resource with SPS driver and initializes msgq endpoints */
int msm_slim_sps_init(struct msm_slim_ctrl *dev, struct resource *bam_mem,
- u32 pipe_reg)
+ u32 pipe_reg, bool remote)
{
int i, ret;
u32 bam_handle;
@@ -521,10 +521,16 @@
bam_props.virt_addr = dev->bam.base;
bam_props.phys_addr = bam_mem->start;
bam_props.irq = dev->bam.irq;
- bam_props.manage = SPS_BAM_MGR_LOCAL;
+ if (!remote) {
+ bam_props.manage = SPS_BAM_MGR_LOCAL;
+ bam_props.sec_config = SPS_BAM_SEC_DO_CONFIG;
+ } else {
+ bam_props.manage = SPS_BAM_MGR_DEVICE_REMOTE |
+ SPS_BAM_MGR_MULTI_EE;
+ bam_props.sec_config = SPS_BAM_SEC_DO_NOT_CONFIG;
+ }
bam_props.summing_threshold = MSM_SLIM_PERF_SUMM_THRESHOLD;
- bam_props.sec_config = SPS_BAM_SEC_DO_CONFIG;
bam_props.p_sec_config_props = &sec_props;
bam_props.options = SPS_O_DESC_DONE | SPS_O_ERROR |
diff --git a/drivers/slimbus/slim-msm.h b/drivers/slimbus/slim-msm.h
index f68475a..35bb040 100644
--- a/drivers/slimbus/slim-msm.h
+++ b/drivers/slimbus/slim-msm.h
@@ -246,6 +246,6 @@
u32 *msm_get_msg_buf(struct msm_slim_ctrl *dev, int len);
int msm_slim_rx_msgq_get(struct msm_slim_ctrl *dev, u32 *data, int offset);
int msm_slim_sps_init(struct msm_slim_ctrl *dev, struct resource *bam_mem,
- u32 pipe_reg);
+ u32 pipe_reg, bool remote);
void msm_slim_sps_exit(struct msm_slim_ctrl *dev);
#endif
diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
index d7da073..bf5410a 100644
--- a/drivers/usb/dwc3/ep0.c
+++ b/drivers/usb/dwc3/ep0.c
@@ -1016,11 +1016,13 @@
dwc->ep0state = EP0_STATUS_PHASE;
- if (dwc->delayed_status) {
+ if (dwc->delayed_status &&
+ list_empty(&dwc->eps[0]->request_list)) {
WARN_ON_ONCE(event->endpoint_number != 1);
dev_vdbg(dwc->dev, "Mass Storage delayed status\n");
return;
}
+ dwc->delayed_status = false;
dwc3_ep0_do_control_status(dwc, event);
}
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 35f7283..ab44d1e 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -2500,7 +2500,7 @@
dev_set_name(&dwc->gadget.dev, "gadget");
dwc->gadget.ops = &dwc3_gadget_ops;
- dwc->gadget.max_speed = USB_SPEED_SUPER;
+ dwc->gadget.max_speed = USB_SPEED_HIGH;
dwc->gadget.speed = USB_SPEED_UNKNOWN;
dwc->gadget.dev.parent = dwc->dev;
dwc->gadget.sg_supported = true;
diff --git a/drivers/usb/gadget/f_qdss.c b/drivers/usb/gadget/f_qdss.c
index 4f098f1..fd4f352 100644
--- a/drivers/usb/gadget/f_qdss.c
+++ b/drivers/usb/gadget/f_qdss.c
@@ -436,11 +436,30 @@
}
}
+static void usb_qdss_disconnect_work(struct work_struct *work)
+{
+ struct f_qdss *qdss = container_of(work, struct f_qdss, disconnect_w);
+ int status;
+
+ pr_debug("usb_qdss_disconnect_work\n");
+
+ /* notify qdss to cancell all active transfers*/
+ if (qdss->ch.notify) {
+ qdss->ch.notify(qdss->ch.priv, USB_QDSS_DISCONNECT, NULL,
+ NULL);
+ /* If the app was never started, we can skip USB BAM reset */
+ status = set_qdss_data_connection(qdss->data,
+ qdss->data->address, 0);
+ if (status)
+ pr_err("qdss_disconnect error");
+ }
+
+}
+
static void qdss_disable(struct usb_function *f)
{
struct f_qdss *qdss = func_to_qdss(f);
unsigned long flags;
- int status;
pr_debug("qdss_disable\n");
@@ -451,24 +470,15 @@
/*cancell all active xfers*/
qdss_eps_disable(f);
- /* notify qdss to cancell all active transfers*/
- if (qdss->ch.notify) {
- qdss->ch.notify(qdss->ch.priv, USB_QDSS_DISCONNECT, NULL,
- NULL);
- /* If the app was never started, we can skip USB BAM reset */
- status = set_qdss_data_connection(qdss->data,
- qdss->data->address, 0);
- if (status)
- pr_err("qdss_disable error");
- }
+ schedule_work(&qdss->disconnect_w);
}
-static void usb_qdss_work_func(struct work_struct *work)
+static void usb_qdss_connect_work(struct work_struct *work)
{
- struct f_qdss *qdss = container_of(work, struct f_qdss, qdss_work);
+ struct f_qdss *qdss = container_of(work, struct f_qdss, connect_w);
int status;
- pr_debug("usb_qdss_work_func\n");
+ pr_debug("usb_qdss_connect_work\n");
status = init_data(qdss->data);
if (status) {
@@ -549,7 +559,7 @@
qdss->usb_connected = 1;
if (qdss->usb_connected && ch->app_conn)
- schedule_work(&qdss->qdss_work);
+ schedule_work(&qdss->connect_w);
return 0;
fail:
@@ -618,7 +628,8 @@
spin_lock_init(&qdss->lock);
INIT_LIST_HEAD(&qdss->ctrl_read_pool);
INIT_LIST_HEAD(&qdss->ctrl_write_pool);
- INIT_WORK(&qdss->qdss_work, usb_qdss_work_func);
+ INIT_WORK(&qdss->connect_w, usb_qdss_connect_work);
+ INIT_WORK(&qdss->disconnect_w, usb_qdss_disconnect_work);
status = usb_add_function(c, &qdss->function);
if (status) {
@@ -767,7 +778,7 @@
/* the case USB cabel was connected befor qdss called qdss_open*/
if (qdss->usb_connected == 1)
- schedule_work(&qdss->qdss_work);
+ schedule_work(&qdss->connect_w);
return ch;
}
diff --git a/drivers/usb/gadget/f_qdss.h b/drivers/usb/gadget/f_qdss.h
index b61244b..d6be8b7 100644
--- a/drivers/usb/gadget/f_qdss.h
+++ b/drivers/usb/gadget/f_qdss.h
@@ -32,7 +32,8 @@
struct usb_qdss_ch ch;
struct list_head ctrl_read_pool;
struct list_head ctrl_write_pool;
- struct work_struct qdss_work;
+ struct work_struct connect_w;
+ struct work_struct disconnect_w;
spinlock_t lock;
unsigned int data_enabled:1;
unsigned int ctrl_in_enabled:1;
diff --git a/drivers/usb/misc/mdm_data_bridge.c b/drivers/usb/misc/mdm_data_bridge.c
index c78fd0c..e821fda 100644
--- a/drivers/usb/misc/mdm_data_bridge.c
+++ b/drivers/usb/misc/mdm_data_bridge.c
@@ -21,7 +21,7 @@
#include <linux/ratelimit.h>
#include <mach/usb_bridge.h>
-#define MAX_RX_URBS 50
+#define MAX_RX_URBS 100
#define RMNET_RX_BUFSIZE 2048
#define STOP_SUBMIT_URB_LIMIT 500
diff --git a/drivers/usb/otg/msm72k_otg.c b/drivers/usb/otg/msm72k_otg.c
index ca1b155..36a91f1 100644
--- a/drivers/usb/otg/msm72k_otg.c
+++ b/drivers/usb/otg/msm72k_otg.c
@@ -536,6 +536,9 @@
test_bit(ID_B, &dev->inputs))
charge = USB_IDCHG_MAX;
+ if (dev->curr_power == charge)
+ return 0;
+
pr_debug("Charging with %dmA current\n", charge);
/* Call vbus_draw only if the charger is of known type and also
* ignore request to stop charging as a result of suspend interrupt
@@ -545,6 +548,8 @@
(charge || new_chg != USB_CHG_TYPE__WALLCHARGER))
pdata->chg_vbus_draw(charge);
+ dev->curr_power = charge;
+
if (new_chg == USB_CHG_TYPE__WALLCHARGER) {
wake_lock(&dev->wlock);
queue_work(dev->wq, &dev->sm_work);
diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c
index 18f8729..a4c7131 100644
--- a/drivers/usb/otg/msm_otg.c
+++ b/drivers/usb/otg/msm_otg.c
@@ -1120,14 +1120,12 @@
static void msm_otg_notify_host_mode(struct msm_otg *motg, bool host_mode)
{
- struct power_supply *usb = psy ? psy : &motg->usb_psy;
-
- if (!usb) {
+ if (!psy) {
pr_err("No USB power supply registered!\n");
return;
}
- if (psy) {
+ if (legacy_power_supply) {
/* legacy support */
if (host_mode)
power_supply_set_scope(psy, POWER_SUPPLY_SCOPE_SYSTEM);
@@ -1136,14 +1134,13 @@
return;
} else {
motg->host_mode = host_mode;
- power_supply_changed(usb);
+ power_supply_changed(psy);
}
}
static int msm_otg_notify_chg_type(struct msm_otg *motg)
{
static int charger_type;
- struct power_supply *usb = psy ? psy : &motg->usb_psy;
/*
* TODO
@@ -1167,40 +1164,38 @@
else
charger_type = POWER_SUPPLY_TYPE_BATTERY;
- if (!usb) {
+ if (!psy) {
pr_err("No USB power supply registered!\n");
return -EINVAL;
}
pr_debug("setting usb power supply type %d\n", charger_type);
- power_supply_set_supply_type(usb, charger_type);
+ power_supply_set_supply_type(psy, charger_type);
return 0;
}
static int msm_otg_notify_power_supply(struct msm_otg *motg, unsigned mA)
{
- struct power_supply *usb = psy ? psy : &motg->usb_psy;
-
- if (!usb) {
+ if (!psy) {
dev_dbg(motg->phy.dev, "no usb power supply registered\n");
goto psy_error;
}
if (motg->cur_power == 0 && mA > 2) {
/* Enable charging */
- if (power_supply_set_online(usb, true))
+ if (power_supply_set_online(psy, true))
goto psy_error;
- if (power_supply_set_current_limit(usb, 1000*mA))
+ if (power_supply_set_current_limit(psy, 1000*mA))
goto psy_error;
} else if (motg->cur_power > 0 && (mA == 0 || mA == 2)) {
/* Disable charging */
- if (power_supply_set_online(usb, false))
+ if (power_supply_set_online(psy, false))
goto psy_error;
/* Set max current limit */
- if (power_supply_set_current_limit(usb, 0))
+ if (power_supply_set_current_limit(psy, 0))
goto psy_error;
}
- power_supply_changed(usb);
+ power_supply_changed(psy);
return 0;
psy_error:
@@ -3386,8 +3381,7 @@
enum power_supply_property psp,
union power_supply_propval *val)
{
- struct msm_otg *motg = container_of(psy, struct msm_otg,
- usb_psy);
+ struct msm_otg *motg = container_of(psy, struct msm_otg, usb_psy);
switch (psp) {
case POWER_SUPPLY_PROP_SCOPE:
if (motg->host_mode)
@@ -3413,8 +3407,7 @@
enum power_supply_property psp,
const union power_supply_propval *val)
{
- struct msm_otg *motg = container_of(psy, struct msm_otg,
- usb_psy);
+ struct msm_otg *motg = container_of(psy, struct msm_otg, usb_psy);
switch (psp) {
/* Process PMIC notification in PRESENT prop */
@@ -4011,19 +4004,19 @@
motg->usb_psy.get_property = otg_power_get_property_usb;
motg->usb_psy.set_property = otg_power_set_property_usb;
- if (motg->pdata->otg_control == OTG_PMIC_CONTROL) {
+ if (!pm8921_charger_register_vbus_sn(NULL)) {
/* if pm8921 use legacy implementation */
- if (!pm8921_charger_register_vbus_sn(&msm_otg_set_vbus_state)) {
- dev_dbg(motg->phy.dev, "%s: legacy support\n",
- __func__);
- legacy_power_supply = true;
- } else {
- ret = msm_otg_register_power_supply(pdev, motg);
- if (ret)
- goto remove_phy;
- }
+ dev_dbg(motg->phy.dev, "%s: legacy support\n", __func__);
+ legacy_power_supply = true;
+ } else {
+ /* otherwise register our own power supply */
+ if (!msm_otg_register_power_supply(pdev, motg))
+ psy = &motg->usb_psy;
}
+ if (legacy_power_supply && pdata->otg_control == OTG_PMIC_CONTROL)
+ pm8921_charger_register_vbus_sn(&msm_otg_set_vbus_state);
+
return 0;
remove_phy:
diff --git a/drivers/video/msm/mdss/mdss_mdp_ctl.c b/drivers/video/msm/mdss/mdss_mdp_ctl.c
index d21a095..73b8c60 100644
--- a/drivers/video/msm/mdss/mdss_mdp_ctl.c
+++ b/drivers/video/msm/mdss/mdss_mdp_ctl.c
@@ -396,7 +396,6 @@
ctl->width = width;
ctl->height = height;
- ctl->dst_format = mfd->panel_info.out_format;
if (!ctl->mixer_left) {
ctl->mixer_left =
@@ -467,6 +466,20 @@
ctl->opmode |= (ctl->intf_num << 4);
+ if (ctl->intf_num == MDSS_MDP_NO_INTF) {
+ ctl->dst_format = mfd->panel_info.out_format;
+ } else {
+ switch (mfd->panel_info.bpp) {
+ case 18:
+ ctl->dst_format = MDSS_MDP_PANEL_FORMAT_RGB666;
+ break;
+ case 24:
+ default:
+ ctl->dst_format = MDSS_MDP_PANEL_FORMAT_RGB888;
+ break;
+ }
+ }
+
if (ctl->mixer_right) {
ctl->opmode |= MDSS_MDP_CTL_OP_PACK_3D_ENABLE |
MDSS_MDP_CTL_OP_PACK_3D_H_ROW_INT;
@@ -560,6 +573,12 @@
temp |= (ctl->intf_type << ((ctl->intf_num - MDSS_MDP_INTF0) * 8));
MDSS_MDP_REG_WRITE(MDSS_MDP_REG_DISP_INTF_SEL, temp);
+ if (ctl->intf_num != MDSS_MDP_NO_INTF) {
+ off = MDSS_MDP_REG_INTF_OFFSET(ctl->intf_num);
+ MDSS_MDP_REG_WRITE(off + MDSS_MDP_REG_INTF_PANEL_FORMAT,
+ ctl->dst_format);
+ }
+
outsize = (mixer->height << 16) | mixer->width;
off = MDSS_MDP_REG_LM_OFFSET(mixer->num);
MDSS_MDP_REG_WRITE(off + MDSS_MDP_REG_LM_OUT_SIZE, outsize);
diff --git a/drivers/video/msm/mdss/mdss_mdp_hwio.h b/drivers/video/msm/mdss/mdss_mdp_hwio.h
index 651d595..1da30b8 100644
--- a/drivers/video/msm/mdss/mdss_mdp_hwio.h
+++ b/drivers/video/msm/mdss/mdss_mdp_hwio.h
@@ -395,6 +395,7 @@
#define MDSS_MDP_REG_INTF_FRAME_COUNT 0x0AC
#define MDSS_MDP_REG_INTF_LINE_COUNT 0x0B0
#define MDSS_MDP_PANEL_FORMAT_RGB888 0x213F
+#define MDSS_MDP_PANEL_FORMAT_RGB666 0x212A
enum mdss_mdp_pingpong_index {
MDSS_MDP_PINGPONG0,
diff --git a/drivers/video/msm/mdss/mdss_mdp_intf_video.c b/drivers/video/msm/mdss/mdss_mdp_intf_video.c
index 3c7c362..4d3fbf0 100644
--- a/drivers/video/msm/mdss/mdss_mdp_intf_video.c
+++ b/drivers/video/msm/mdss/mdss_mdp_intf_video.c
@@ -153,8 +153,6 @@
p->hsync_skew);
MDSS_MDP_REG_WRITE(off + MDSS_MDP_REG_INTF_POLARITY_CTL,
polarity_ctl);
- MDSS_MDP_REG_WRITE(off + MDSS_MDP_REG_INTF_PANEL_FORMAT,
- MDSS_MDP_PANEL_FORMAT_RGB888);
return 0;
}
diff --git a/include/linux/dvb/video.h b/include/linux/dvb/video.h
index 81475c2..2a2a53d 100644
--- a/include/linux/dvb/video.h
+++ b/include/linux/dvb/video.h
@@ -113,6 +113,7 @@
#define VIDEO_CMD_FREE_H264_MV_BUFFER (17)
#define VIDEO_CMD_CLEAR_INPUT_BUFFER (18)
#define VIDEO_CMD_CLEAR_OUTPUT_BUFFER (19)
+#define VIDEO_CMD_SET_BUFFER_COUNT (20)
/* Flags for VIDEO_CMD_FREEZE */
#define VIDEO_CMD_FREEZE_TO_BLACK (1 << 0)
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
index 30ca87c..fb854ba 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -60,6 +60,7 @@
unsigned int sa_timeout; /* Units: 100ns */
unsigned int generic_cmd6_time; /* Units: 10ms */
unsigned int power_off_longtime; /* Units: ms */
+ u8 power_off_notification; /* state */
unsigned int hs_max_dtr;
#define MMC_HIGH_26_MAX_DTR 26000000
#define MMC_HIGH_52_MAX_DTR 52000000
@@ -309,7 +310,6 @@
#define MMC_CARD_SDXC (1<<6) /* card is SDXC */
#define MMC_CARD_REMOVED (1<<7) /* card has been removed */
#define MMC_STATE_HIGHSPEED_200 (1<<8) /* card is in HS200 mode */
-#define MMC_STATE_SLEEP (1<<9) /* card is in sleep state */
#define MMC_STATE_DOING_BKOPS (1<<10) /* card is doing BKOPS */
unsigned int quirks; /* card quirks */
#define MMC_QUIRK_LENIENT_FN0 (1<<0) /* allow SDIO FN0 writes outside of the VS CCCR range */
@@ -326,11 +326,6 @@
#define MMC_QUIRK_LONG_READ_TIME (1<<9) /* Data read time > CSD says */
/* byte mode */
#define MMC_QUIRK_INAND_DATA_TIMEOUT (1<<8) /* For incorrect data timeout */
- unsigned int poweroff_notify_state; /* eMMC4.5 notify feature */
-#define MMC_NO_POWER_NOTIFICATION 0
-#define MMC_POWERED_ON 1
-#define MMC_POWEROFF_SHORT 2
-#define MMC_POWEROFF_LONG 3
unsigned int erase_size; /* erase size in sectors */
unsigned int erase_shift; /* if erase unit is power 2 */
@@ -486,7 +481,6 @@
#define mmc_sd_card_uhs(c) ((c)->state & MMC_STATE_ULTRAHIGHSPEED)
#define mmc_card_ext_capacity(c) ((c)->state & MMC_CARD_SDXC)
#define mmc_card_removed(c) ((c) && ((c)->state & MMC_CARD_REMOVED))
-#define mmc_card_is_sleep(c) ((c)->state & MMC_STATE_SLEEP)
#define mmc_card_doing_bkops(c) ((c)->state & MMC_STATE_DOING_BKOPS)
#define mmc_card_set_present(c) ((c)->state |= MMC_STATE_PRESENT)
@@ -499,11 +493,9 @@
#define mmc_sd_card_set_uhs(c) ((c)->state |= MMC_STATE_ULTRAHIGHSPEED)
#define mmc_card_set_ext_capacity(c) ((c)->state |= MMC_CARD_SDXC)
#define mmc_card_set_removed(c) ((c)->state |= MMC_CARD_REMOVED)
-#define mmc_card_set_sleep(c) ((c)->state |= MMC_STATE_SLEEP)
#define mmc_card_set_doing_bkops(c) ((c)->state |= MMC_STATE_DOING_BKOPS)
-
#define mmc_card_clr_doing_bkops(c) ((c)->state &= ~MMC_STATE_DOING_BKOPS)
-#define mmc_card_clr_sleep(c) ((c)->state &= ~MMC_STATE_SLEEP)
+
/*
* Quirk add/remove for MMC products.
*/
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 8f0a756..f435221 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -251,10 +251,6 @@
#define MMC_CAP2_SANITIZE (1 << 13) /* Support Sanitize */
#define MMC_CAP2_INIT_BKOPS (1 << 15) /* Need to set BKOPS_EN */
mmc_pm_flag_t pm_caps; /* supported pm features */
- unsigned int power_notify_type;
-#define MMC_HOST_PW_NOTIFY_NONE 0
-#define MMC_HOST_PW_NOTIFY_SHORT 1
-#define MMC_HOST_PW_NOTIFY_LONG 2
int clk_requests; /* internal reference counter */
unsigned int clk_delay; /* number of MCI clk hold cycles */
diff --git a/sound/soc/msm/qdsp6v2/q6voice.c b/sound/soc/msm/qdsp6v2/q6voice.c
index 1f6dbf1..4e41c80 100644
--- a/sound/soc/msm/qdsp6v2/q6voice.c
+++ b/sound/soc/msm/qdsp6v2/q6voice.c
@@ -42,6 +42,12 @@
/* CVS CAL Size: 49152 = 48 * 1024 */
#define CVS_CAL_SIZE 49152
+enum {
+ VOC_TOKEN_NONE,
+ VOIP_MEM_MAP_TOKEN,
+ VOC_CAL_MEM_MAP_TOKEN,
+};
+
static struct common_data common;
static int voice_send_enable_vocproc_cmd(struct voice_data *v);
@@ -50,7 +56,6 @@
static int voice_send_set_device_cmd(struct voice_data *v);
static int voice_send_disable_vocproc_cmd(struct voice_data *v);
static int voice_send_vol_index_cmd(struct voice_data *v);
-static int voice_send_mvm_map_memory_physical_cmd(struct voice_data *v);
static int voice_send_mvm_unmap_memory_physical_cmd(struct voice_data *v,
unsigned int bufcnt);
static int voice_send_mvm_cal_network_cmd(struct voice_data *v);
@@ -59,6 +64,16 @@
static int voice_send_cvs_packet_exchange_config_cmd(struct voice_data *v);
static int voice_set_packet_exchange_mode_and_config(uint16_t session_id,
uint32_t mode);
+
+static int voice_send_cvs_register_cal_cmd(struct voice_data *v);
+static int voice_send_cvs_deregister_cal_cmd(struct voice_data *v);
+static int voice_send_cvp_register_dev_cfg_cmd(struct voice_data *v);
+static int voice_send_cvp_deregister_dev_cfg_cmd(struct voice_data *v);
+static int voice_send_cvp_register_cal_cmd(struct voice_data *v);
+static int voice_send_cvp_deregister_cal_cmd(struct voice_data *v);
+static int voice_send_cvp_register_vol_cal_cmd(struct voice_data *v);
+static int voice_send_cvp_deregister_vol_cal_cmd(struct voice_data *v);
+
static int voice_cvs_stop_playback(struct voice_data *v);
static int voice_cvs_start_playback(struct voice_data *v);
static int voice_cvs_start_record(struct voice_data *v, uint32_t rec_mode);
@@ -1263,32 +1278,557 @@
return -EINVAL;
}
-static int voice_send_mvm_map_memory_physical_cmd(struct voice_data *v)
+static int voice_send_cvs_register_cal_cmd(struct voice_data *v)
+{
+ struct cvs_register_cal_data_cmd cvs_reg_cal_cmd;
+ struct acdb_cal_block cal_block;
+ int ret = 0;
+ memset(&cvs_reg_cal_cmd, 0, sizeof(cvs_reg_cal_cmd));
+
+ if (v == NULL) {
+ pr_err("%s: v is NULL\n", __func__);
+
+ goto fail;
+ }
+
+ if (!common.apr_q6_cvs) {
+ pr_err("%s: apr_cvs is NULL\n", __func__);
+
+ goto fail;
+ }
+
+ if (!common.cal_mem_handle) {
+ pr_err("%s: Cal mem handle is NULL\n", __func__);
+
+ goto fail;
+ }
+
+ get_all_vocstrm_cal(&cal_block);
+ if (cal_block.cal_size == 0) {
+ pr_err("%s: CVS cal size is 0\n", __func__);
+
+ goto fail;
+ }
+
+ cvs_reg_cal_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
+ APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
+ cvs_reg_cal_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
+ sizeof(cvs_reg_cal_cmd) - APR_HDR_SIZE);
+ cvs_reg_cal_cmd.hdr.src_port = v->session_id;
+ cvs_reg_cal_cmd.hdr.dest_port = voice_get_cvs_handle(v);
+ cvs_reg_cal_cmd.hdr.token = 0;
+ cvs_reg_cal_cmd.hdr.opcode =
+ VSS_ISTREAM_CMD_REGISTER_CALIBRATION_DATA_V2;
+
+ cvs_reg_cal_cmd.cvs_cal_data.cal_mem_handle = common.cal_mem_handle;
+ cvs_reg_cal_cmd.cvs_cal_data.cal_mem_address = cal_block.cal_paddr;
+ cvs_reg_cal_cmd.cvs_cal_data.cal_mem_size = cal_block.cal_size;
+
+ /* Get the column info corresponding to CVS cal from ACDB. */
+ get_voice_col_data(VOCSTRM_CAL, &cal_block);
+ memcpy(&cvs_reg_cal_cmd.cvs_cal_data.column_info[0],
+ (void *) cal_block.cal_kvaddr,
+ cal_block.cal_size);
+
+ v->cvs_state = CMD_STATUS_FAIL;
+ ret = apr_send_pkt(common.apr_q6_cvs, (uint32_t *) &cvs_reg_cal_cmd);
+ if (ret < 0) {
+ pr_err("%s: Error %d registering CVS cal\n", __func__, ret);
+
+ goto fail;
+ }
+ ret = wait_event_timeout(v->cvs_wait,
+ (v->cvs_state == CMD_STATUS_SUCCESS),
+ msecs_to_jiffies(TIMEOUT_MS));
+ if (!ret) {
+ pr_err("%s: Command timeout\n", __func__);
+
+ goto fail;
+ }
+
+ return 0;
+
+fail:
+ return -EINVAL;
+}
+
+static int voice_send_cvs_deregister_cal_cmd(struct voice_data *v)
+{
+ struct cvs_deregister_cal_data_cmd cvs_dereg_cal_cmd;
+ struct acdb_cal_block cal_block;
+ int ret = 0;
+ memset(&cvs_dereg_cal_cmd, 0, sizeof(cvs_dereg_cal_cmd));
+
+ if (v == NULL) {
+ pr_err("%s: v is NULL\n", __func__);
+
+ goto fail;
+ }
+
+ if (!common.apr_q6_cvs) {
+ pr_err("%s: apr_cvs is NULL\n", __func__);
+
+ goto fail;
+ }
+
+ get_all_vocstrm_cal(&cal_block);
+ if (cal_block.cal_size == 0)
+ return 0;
+
+ cvs_dereg_cal_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
+ APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
+ cvs_dereg_cal_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
+ sizeof(cvs_dereg_cal_cmd) - APR_HDR_SIZE);
+ cvs_dereg_cal_cmd.hdr.src_port = v->session_id;
+ cvs_dereg_cal_cmd.hdr.dest_port = voice_get_cvs_handle(v);
+ cvs_dereg_cal_cmd.hdr.token = 0;
+ cvs_dereg_cal_cmd.hdr.opcode =
+ VSS_ISTREAM_CMD_DEREGISTER_CALIBRATION_DATA;
+
+ v->cvs_state = CMD_STATUS_FAIL;
+ ret = apr_send_pkt(common.apr_q6_cvs, (uint32_t *) &cvs_dereg_cal_cmd);
+ if (ret < 0) {
+ pr_err("%s: Error %d de-registering CVS cal\n", __func__, ret);
+
+ goto fail;
+ }
+ ret = wait_event_timeout(v->cvs_wait,
+ (v->cvs_state == CMD_STATUS_SUCCESS),
+ msecs_to_jiffies(TIMEOUT_MS));
+ if (!ret) {
+ pr_err("%s: Command timeout\n", __func__);
+
+ goto fail;
+ }
+
+ return 0;
+
+fail:
+ return -EINVAL;
+
+}
+
+static int voice_send_cvp_register_dev_cfg_cmd(struct voice_data *v)
+{
+ struct cvp_register_dev_cfg_cmd cvp_reg_dev_cfg_cmd;
+ struct acdb_cal_block cal_block;
+ int ret = 0;
+ memset(&cvp_reg_dev_cfg_cmd, 0, sizeof(cvp_reg_dev_cfg_cmd));
+
+ if (v == NULL) {
+ pr_err("%s: v is NULL\n", __func__);
+
+ goto fail;
+ }
+
+ if (!common.apr_q6_cvp) {
+ pr_err("%s: apr_cvp is NULL\n", __func__);
+
+ goto fail;
+ }
+
+ if (!common.cal_mem_handle) {
+ pr_err("%s: Cal mem handle is NULL\n", __func__);
+
+ goto fail;
+ }
+
+ get_vocproc_dev_cfg_cal(&cal_block);
+ if (cal_block.cal_size == 0) {
+ pr_err("%s: CVP cal size is 0\n", __func__);
+
+ goto fail;
+ }
+
+ cvp_reg_dev_cfg_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
+ APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
+ cvp_reg_dev_cfg_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
+ sizeof(cvp_reg_dev_cfg_cmd) - APR_HDR_SIZE);
+ cvp_reg_dev_cfg_cmd.hdr.src_port = v->session_id;
+ cvp_reg_dev_cfg_cmd.hdr.dest_port = voice_get_cvp_handle(v);
+ cvp_reg_dev_cfg_cmd.hdr.token = 0;
+ cvp_reg_dev_cfg_cmd.hdr.opcode =
+ VSS_IVOCPROC_CMD_REGISTER_DEVICE_CONFIG;
+
+ cvp_reg_dev_cfg_cmd.cvp_dev_cfg_data.mem_handle = common.cal_mem_handle;
+ cvp_reg_dev_cfg_cmd.cvp_dev_cfg_data.mem_address = cal_block.cal_paddr;
+ cvp_reg_dev_cfg_cmd.cvp_dev_cfg_data.mem_size = cal_block.cal_size;
+
+ v->cvp_state = CMD_STATUS_FAIL;
+ ret = apr_send_pkt(common.apr_q6_cvp,
+ (uint32_t *) &cvp_reg_dev_cfg_cmd);
+ if (ret < 0) {
+ pr_err("%s: Error %d registering CVP dev cfg cal\n",
+ __func__, ret);
+
+ goto fail;
+ }
+ ret = wait_event_timeout(v->cvp_wait,
+ (v->cvp_state == CMD_STATUS_SUCCESS),
+ msecs_to_jiffies(TIMEOUT_MS));
+ if (!ret) {
+ pr_err("%s: Command timeout\n", __func__);
+
+ goto fail;
+ }
+
+ return 0;
+
+fail:
+ return -EINVAL;
+}
+
+static int voice_send_cvp_deregister_dev_cfg_cmd(struct voice_data *v)
+{
+ struct cvp_deregister_dev_cfg_cmd cvp_dereg_dev_cfg_cmd;
+ struct acdb_cal_block cal_block;
+ int ret = 0;
+ memset(&cvp_dereg_dev_cfg_cmd, 0, sizeof(cvp_dereg_dev_cfg_cmd));
+
+ if (v == NULL) {
+ pr_err("%s: v is NULL\n", __func__);
+
+ goto fail;
+ }
+
+ if (!common.apr_q6_cvp) {
+ pr_err("%s: apr_cvp is NULL.\n", __func__);
+
+ goto fail;
+ }
+
+ get_vocproc_dev_cfg_cal(&cal_block);
+ if (cal_block.cal_size == 0)
+ return 0;
+
+ cvp_dereg_dev_cfg_cmd.hdr.hdr_field =
+ APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
+ APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
+ cvp_dereg_dev_cfg_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
+ sizeof(cvp_dereg_dev_cfg_cmd) - APR_HDR_SIZE);
+ cvp_dereg_dev_cfg_cmd.hdr.src_port = v->session_id;
+ cvp_dereg_dev_cfg_cmd.hdr.dest_port = voice_get_cvp_handle(v);
+ cvp_dereg_dev_cfg_cmd.hdr.token = 0;
+ cvp_dereg_dev_cfg_cmd.hdr.opcode =
+ VSS_IVOCPROC_CMD_DEREGISTER_DEVICE_CONFIG;
+
+ v->cvp_state = CMD_STATUS_FAIL;
+ ret = apr_send_pkt(common.apr_q6_cvp,
+ (uint32_t *) &cvp_dereg_dev_cfg_cmd);
+ if (ret < 0) {
+ pr_err("%s: Error %d de-registering CVP dev cfg cal\n",
+ __func__, ret);
+
+ goto fail;
+ }
+ ret = wait_event_timeout(v->cvp_wait,
+ (v->cvp_state == CMD_STATUS_SUCCESS),
+ msecs_to_jiffies(TIMEOUT_MS));
+ if (!ret) {
+ pr_err("%s: Command timeout\n", __func__);
+
+ goto fail;
+ }
+
+ return 0;
+
+fail:
+ return -EINVAL;
+}
+
+static int voice_send_cvp_register_cal_cmd(struct voice_data *v)
+{
+ struct cvp_register_cal_data_cmd cvp_reg_cal_cmd;
+ struct acdb_cal_block cal_block;
+ int ret = 0;
+ memset(&cvp_reg_cal_cmd, 0, sizeof(cvp_reg_cal_cmd));
+
+ if (v == NULL) {
+ pr_err("%s: v is NULL\n", __func__);
+
+ goto fail;
+ }
+
+ if (!common.apr_q6_cvp) {
+ pr_err("%s: apr_cvp is NULL\n", __func__);
+
+ goto fail;
+ }
+
+ if (!common.cal_mem_handle) {
+ pr_err("%s: Cal mem handle is NULL\n", __func__);
+
+ goto fail;
+ }
+
+ get_all_vocproc_cal(&cal_block);
+ if (cal_block.cal_size == 0) {
+ pr_err("%s: CVP cal size is 0\n", __func__);
+
+ goto fail;
+ }
+
+ cvp_reg_cal_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
+ APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
+ cvp_reg_cal_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
+ sizeof(cvp_reg_cal_cmd) - APR_HDR_SIZE);
+ cvp_reg_cal_cmd.hdr.src_port = v->session_id;
+ cvp_reg_cal_cmd.hdr.dest_port = voice_get_cvp_handle(v);
+ cvp_reg_cal_cmd.hdr.token = 0;
+ cvp_reg_cal_cmd.hdr.opcode =
+ VSS_IVOCPROC_CMD_REGISTER_CALIBRATION_DATA_V2;
+
+ cvp_reg_cal_cmd.cvp_cal_data.cal_mem_handle = common.cal_mem_handle;
+ cvp_reg_cal_cmd.cvp_cal_data.cal_mem_address = cal_block.cal_paddr;
+ cvp_reg_cal_cmd.cvp_cal_data.cal_mem_size = cal_block.cal_size;
+
+ /* Get the column info corresponding to CVP cal from ACDB. */
+ get_voice_col_data(VOCPROC_CAL, &cal_block);
+ memcpy(&cvp_reg_cal_cmd.cvp_cal_data.column_info[0],
+ (void *) cal_block.cal_kvaddr,
+ cal_block.cal_size);
+
+ v->cvp_state = CMD_STATUS_FAIL;
+ ret = apr_send_pkt(common.apr_q6_cvp, (uint32_t *) &cvp_reg_cal_cmd);
+ if (ret < 0) {
+ pr_err("%s: Error %d registering CVP cal\n", __func__, ret);
+
+ goto fail;
+ }
+ ret = wait_event_timeout(v->cvp_wait,
+ (v->cvp_state == CMD_STATUS_SUCCESS),
+ msecs_to_jiffies(TIMEOUT_MS));
+ if (!ret) {
+ pr_err("%s: Command timeout\n", __func__);
+
+ goto fail;
+ }
+
+ return 0;
+
+fail:
+ return -EINVAL;
+}
+
+static int voice_send_cvp_deregister_cal_cmd(struct voice_data *v)
+{
+ struct cvp_deregister_cal_data_cmd cvp_dereg_cal_cmd;
+ struct acdb_cal_block cal_block;
+ int ret = 0;
+ memset(&cvp_dereg_cal_cmd, 0, sizeof(cvp_dereg_cal_cmd));
+
+ if (v == NULL) {
+ pr_err("%s: v is NULL\n", __func__);
+
+ goto fail;
+ }
+
+ if (!common.apr_q6_cvp) {
+ pr_err("%s: apr_cvp is NULL.\n", __func__);
+
+ goto fail;
+ }
+
+ get_all_vocproc_cal(&cal_block);
+ if (cal_block.cal_size == 0)
+ return 0;
+
+ cvp_dereg_cal_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
+ APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
+ cvp_dereg_cal_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
+ sizeof(cvp_dereg_cal_cmd) - APR_HDR_SIZE);
+ cvp_dereg_cal_cmd.hdr.src_port = v->session_id;
+ cvp_dereg_cal_cmd.hdr.dest_port = voice_get_cvp_handle(v);
+ cvp_dereg_cal_cmd.hdr.token = 0;
+ cvp_dereg_cal_cmd.hdr.opcode =
+ VSS_IVOCPROC_CMD_DEREGISTER_CALIBRATION_DATA;
+
+ v->cvp_state = CMD_STATUS_FAIL;
+ ret = apr_send_pkt(common.apr_q6_cvp, (uint32_t *) &cvp_dereg_cal_cmd);
+ if (ret < 0) {
+ pr_err("%s: Error %d de-registering CVP cal\n", __func__, ret);
+
+ goto fail;
+ }
+ ret = wait_event_timeout(v->cvp_wait,
+ (v->cvp_state == CMD_STATUS_SUCCESS),
+ msecs_to_jiffies(TIMEOUT_MS));
+ if (!ret) {
+ pr_err("%s: Command timeout\n", __func__);
+
+ goto fail;
+ }
+
+ return 0;
+
+fail:
+ return -EINVAL;
+}
+
+static int voice_send_cvp_register_vol_cal_cmd(struct voice_data *v)
+{
+ struct cvp_register_vol_cal_data_cmd cvp_reg_vol_cal_cmd;
+ struct acdb_cal_block cal_block;
+ int ret = 0;
+ memset(&cvp_reg_vol_cal_cmd, 0, sizeof(cvp_reg_vol_cal_cmd));
+
+ if (v == NULL) {
+ pr_err("%s: v is NULL\n", __func__);
+
+ goto fail;
+ }
+
+ if (!common.apr_q6_cvp) {
+ pr_err("%s: apr_cvp is NULL.\n", __func__);
+
+ goto fail;
+ }
+
+ if (!common.cal_mem_handle) {
+ pr_err("%s: Cal mem handle is NULL\n", __func__);
+
+ goto fail;
+ }
+
+ get_all_vocvol_cal(&cal_block);
+ if (cal_block.cal_size == 0) {
+ pr_err("%s: CVP vol cal size is 0\n", __func__);
+
+ goto fail;
+ }
+
+ cvp_reg_vol_cal_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
+ APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
+ cvp_reg_vol_cal_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
+ sizeof(cvp_reg_vol_cal_cmd) - APR_HDR_SIZE);
+ cvp_reg_vol_cal_cmd.hdr.src_port = v->session_id;
+ cvp_reg_vol_cal_cmd.hdr.dest_port = voice_get_cvp_handle(v);
+ cvp_reg_vol_cal_cmd.hdr.token = 0;
+ cvp_reg_vol_cal_cmd.hdr.opcode =
+ VSS_IVOCPROC_CMD_REGISTER_VOL_CALIBRATION_DATA;
+
+ cvp_reg_vol_cal_cmd.cvp_vol_cal_data.cal_mem_handle =
+ common.cal_mem_handle;
+ cvp_reg_vol_cal_cmd.cvp_vol_cal_data.cal_mem_address =
+ cal_block.cal_paddr;
+ cvp_reg_vol_cal_cmd.cvp_vol_cal_data.cal_mem_size = cal_block.cal_size;
+
+ /* Get the column info corresponding to CVP volume cal from ACDB. */
+ get_voice_col_data(VOCVOL_CAL, &cal_block);
+ memcpy(&cvp_reg_vol_cal_cmd.cvp_vol_cal_data.column_info[0],
+ (void *) cal_block.cal_kvaddr,
+ cal_block.cal_size);
+
+ v->cvp_state = CMD_STATUS_FAIL;
+ ret = apr_send_pkt(common.apr_q6_cvp,
+ (uint32_t *) &cvp_reg_vol_cal_cmd);
+ if (ret < 0) {
+ pr_err("%s: Error %d registering CVP vol cal\n", __func__, ret);
+
+ goto fail;
+ }
+ ret = wait_event_timeout(v->cvp_wait,
+ (v->cvp_state == CMD_STATUS_SUCCESS),
+ msecs_to_jiffies(TIMEOUT_MS));
+ if (!ret) {
+ pr_err("%s: Command timeout\n", __func__);
+
+ goto fail;
+ }
+
+ return 0;
+
+fail:
+ return -EINVAL;
+}
+
+static int voice_send_cvp_deregister_vol_cal_cmd(struct voice_data *v)
+{
+ struct cvp_deregister_vol_cal_data_cmd cvp_dereg_vol_cal_cmd;
+ struct acdb_cal_block cal_block;
+ int ret = 0;
+ memset(&cvp_dereg_vol_cal_cmd, 0, sizeof(cvp_dereg_vol_cal_cmd));
+
+ if (v == NULL) {
+ pr_err("%s: v is NULL\n", __func__);
+
+ goto fail;
+ }
+
+ if (!common.apr_q6_cvp) {
+ pr_err("%s: apr_cvp is NULL\n", __func__);
+
+ goto fail;
+ }
+
+ get_all_vocvol_cal(&cal_block);
+ if (cal_block.cal_size == 0)
+ return 0;
+
+ cvp_dereg_vol_cal_cmd.hdr.hdr_field =
+ APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
+ APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
+ cvp_dereg_vol_cal_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
+ sizeof(cvp_dereg_vol_cal_cmd) - APR_HDR_SIZE);
+ cvp_dereg_vol_cal_cmd.hdr.src_port = v->session_id;
+ cvp_dereg_vol_cal_cmd.hdr.dest_port = voice_get_cvp_handle(v);
+ cvp_dereg_vol_cal_cmd.hdr.token = 0;
+ cvp_dereg_vol_cal_cmd.hdr.opcode =
+ VSS_IVOCPROC_CMD_DEREGISTER_VOL_CALIBRATION_DATA;
+
+ v->cvp_state = CMD_STATUS_FAIL;
+ ret = apr_send_pkt(common.apr_q6_cvp,
+ (uint32_t *) &cvp_dereg_vol_cal_cmd);
+ if (ret < 0) {
+ pr_err("%s: Error %d de-registering CVP vol cal\n",
+ __func__, ret);
+
+ goto fail;
+ }
+ ret = wait_event_timeout(v->cvp_wait,
+ (v->cvp_state == CMD_STATUS_SUCCESS),
+ msecs_to_jiffies(TIMEOUT_MS));
+ if (!ret) {
+ pr_err("%s: Command timeout\n", __func__);
+
+ goto fail;
+ }
+
+ return 0;
+
+fail:
+ return -EINVAL;
+}
+
+static int voice_map_memory_physical_cmd(struct voice_data *v,
+ struct mem_map_table *table_info,
+ dma_addr_t phys,
+ uint32_t size,
+ uint32_t token)
{
struct vss_imemory_cmd_map_physical_t mvm_map_phys_cmd;
uint32_t *memtable;
int ret = 0;
- void *apr_mvm;
- u16 mvm_handle;
if (v == NULL) {
pr_err("%s: v is NULL\n", __func__);
- return -EINVAL;
+
+ goto fail;
}
- apr_mvm = common.apr_q6_mvm;
-
- if (!apr_mvm) {
+ if (!common.apr_q6_mvm) {
pr_err("%s: apr_mvm is NULL.\n", __func__);
- return -EINVAL;
+
+ goto fail;
}
- if (!v->shmem_info.memtbl.data) {
- pr_err("%s: shmem_info.memtbl.data is NULL.\n", __func__);
- return -EINVAL;
+ if (!table_info->data) {
+ pr_err("%s: memory table is NULL.\n", __func__);
+
+ goto fail;
}
- memtable = (uint32_t *)v->shmem_info.memtbl.data;
+ memtable = (uint32_t *) table_info->data;
/*
* Store next table descriptor's address(64 bit) as NULL as there
@@ -1301,25 +1841,22 @@
memtable[2] = 0;
/* Store shared mem add */
- memtable[3] = v->shmem_info.sh_buf.buf[0].phys;
+ memtable[3] = phys;
memtable[4] = 0;
/* Store shared memory size */
- memtable[5] = v->shmem_info.sh_buf.buf[0].size * NUM_OF_BUFFERS;
-
- mvm_handle = voice_get_mvm_handle(v);
+ memtable[5] = size;
mvm_map_phys_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
mvm_map_phys_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
sizeof(mvm_map_phys_cmd) - APR_HDR_SIZE);
mvm_map_phys_cmd.hdr.src_port = v->session_id;
- mvm_map_phys_cmd.hdr.dest_port = mvm_handle;
- mvm_map_phys_cmd.hdr.token = 0;
+ mvm_map_phys_cmd.hdr.dest_port = voice_get_mvm_handle(v);
+ mvm_map_phys_cmd.hdr.token = token;
mvm_map_phys_cmd.hdr.opcode = VSS_IMEMORY_CMD_MAP_PHYSICAL;
- mvm_map_phys_cmd.table_descriptor.mem_address =
- v->shmem_info.memtbl.phys;
+ mvm_map_phys_cmd.table_descriptor.mem_address = table_info->phys;
mvm_map_phys_cmd.table_descriptor.mem_size =
sizeof(struct vss_imemory_block_t) +
sizeof(struct vss_imemory_table_descriptor_t);
@@ -1330,36 +1867,71 @@
mvm_map_phys_cmd.min_data_width = 8;
mvm_map_phys_cmd.max_data_width = 64;
- pr_debug("%s: ntd->add: %lld, ntd->size: %d, table->add: 0x%x\n",
- __func__,
- *((uint64_t *)v->shmem_info.memtbl.data),
- *(((uint32_t *)(v->shmem_info.memtbl.data)) + 2),
- *(((uint32_t *)(v->shmem_info.memtbl.data)) + 3));
- pr_debug("%s: table->size: %d, pkt_size: %d, mvm_handle: 0x%x\n",
- __func__,
- *(((uint32_t *)(v->shmem_info.memtbl.data)) + 5),
- mvm_map_phys_cmd.hdr.pkt_size, mvm_handle);
+ pr_debug("%s: next table desc: add: %lld, size: %d\n",
+ __func__, *((uint64_t *) memtable),
+ *(((uint32_t *) memtable) + 2));
+ pr_debug("%s: phy add of of mem being mapped 0x%x, size: %d\n",
+ __func__, *(((uint32_t *) memtable) + 3),
+ *(((uint32_t *) memtable) + 5));
v->mvm_state = CMD_STATUS_FAIL;
- ret = apr_send_pkt(apr_mvm, (uint32_t *) &mvm_map_phys_cmd);
+ ret = apr_send_pkt(common.apr_q6_mvm, (uint32_t *) &mvm_map_phys_cmd);
if (ret < 0) {
- pr_err("Fail: sending mvm map phy cmd %d\n", ret);
+ pr_err("%s: Error %d sending mvm map phy cmd\n", __func__, ret);
+
goto fail;
}
ret = wait_event_timeout(v->mvm_wait,
- (v->mvm_state == CMD_STATUS_SUCCESS),
- msecs_to_jiffies(TIMEOUT_MS));
+ (v->mvm_state == CMD_STATUS_SUCCESS),
+ msecs_to_jiffies(TIMEOUT_MS));
if (!ret) {
- pr_err("%s: wait_event timeout %d\n", __func__, ret);
+ pr_err("%s: Command timeout\n", __func__);
+
goto fail;
}
return 0;
+
fail:
return -EINVAL;
}
+static int voice_mem_map_cal_block(struct voice_data *v)
+{
+ int ret = 0;
+ struct acdb_cal_block cal_block;
+
+ if (v == NULL) {
+ pr_err("%s: v is NULL\n", __func__);
+
+ return -EINVAL;
+ }
+
+ if (common.cal_mem_handle != 0) {
+ pr_debug("%s: Cal block already mem mapped\n", __func__);
+
+ return ret;
+ }
+
+ /* Get the physical address of calibration memory block from ACDB. */
+ get_voice_cal_allocation(&cal_block);
+
+ if (!cal_block.cal_paddr) {
+ pr_err("%s: Cal block not allocated\n", __func__);
+
+ return -EINVAL;
+ }
+
+ ret = voice_map_memory_physical_cmd(v,
+ &common.cal_mem_map_table,
+ cal_block.cal_paddr,
+ cal_block.cal_size,
+ VOC_CAL_MEM_MAP_TOKEN);
+
+ return ret;
+}
+
static int voice_setup_vocproc(struct voice_data *v)
{
struct cvp_create_full_ctl_session_cmd cvp_session_cmd;
@@ -1437,6 +2009,12 @@
goto fail;
}
+ voice_send_cvs_register_cal_cmd(v);
+
+ voice_send_cvp_register_dev_cfg_cmd(v);
+ voice_send_cvp_register_cal_cmd(v);
+ voice_send_cvp_register_vol_cal_cmd(v);
+
/* enable vocproc */
ret = voice_send_enable_vocproc_cmd(v);
if (ret < 0)
@@ -1789,6 +2367,11 @@
goto fail;
}
+ voice_send_cvp_deregister_vol_cal_cmd(v);
+ voice_send_cvp_deregister_cal_cmd(v);
+ voice_send_cvp_deregister_dev_cfg_cmd(v);
+
+ voice_send_cvs_deregister_cal_cmd(v);
/* destrop cvp session */
cvp_destroy_session_cmd.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
@@ -1997,20 +2580,18 @@
{
struct cvs_set_mute_cmd cvs_mute_cmd;
int ret = 0;
- void *apr_cvs;
- u16 cvs_handle;
if (v == NULL) {
pr_err("%s: v is NULL\n", __func__);
- return -EINVAL;
- }
- apr_cvs = common.apr_q6_cvs;
- if (!apr_cvs) {
- pr_err("%s: apr_cvs is NULL.\n", __func__);
- return -EINVAL;
+ goto fail;
}
- cvs_handle = voice_get_cvs_handle(v);
+
+ if (!common.apr_q6_cvs) {
+ pr_err("%s: apr_cvs is NULL.\n", __func__);
+
+ goto fail;
+ }
/* send mute/unmute to cvs */
cvs_mute_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
@@ -2019,25 +2600,31 @@
cvs_mute_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
sizeof(cvs_mute_cmd) - APR_HDR_SIZE);
cvs_mute_cmd.hdr.src_port = v->session_id;
- cvs_mute_cmd.hdr.dest_port = cvs_handle;
+ cvs_mute_cmd.hdr.dest_port = voice_get_cvs_handle(v);
cvs_mute_cmd.hdr.token = 0;
- cvs_mute_cmd.hdr.opcode = VSS_ISTREAM_CMD_SET_MUTE;
- cvs_mute_cmd.cvs_set_mute.direction = 0; /*tx*/
+ cvs_mute_cmd.hdr.opcode = VSS_IVOLUME_CMD_MUTE_V2;
+ cvs_mute_cmd.cvs_set_mute.direction = VSS_IVOLUME_DIRECTION_TX;
cvs_mute_cmd.cvs_set_mute.mute_flag = v->dev_tx.mute;
+ cvs_mute_cmd.cvs_set_mute.ramp_duration_ms = DEFAULT_MUTE_RAMP_DURATION;
v->cvs_state = CMD_STATUS_FAIL;
- ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_mute_cmd);
+ ret = apr_send_pkt(common.apr_q6_cvs, (uint32_t *) &cvs_mute_cmd);
if (ret < 0) {
- pr_err("Fail: send STREAM SET MUTE\n");
+ pr_err("%s: Error %d sending stream mute\n", __func__, ret);
+
goto fail;
}
ret = wait_event_timeout(v->cvs_wait,
(v->cvs_state == CMD_STATUS_SUCCESS),
msecs_to_jiffies(TIMEOUT_MS));
- if (!ret)
- pr_err("%s: wait_event timeout\n", __func__);
+ if (!ret) {
+ pr_err("%s: Command timeout\n", __func__);
+
+ goto fail;
+ }
return 0;
+
fail:
return -EINVAL;
}
@@ -2046,19 +2633,18 @@
{
struct cvp_set_mute_cmd cvp_mute_cmd;
int ret = 0;
- void *apr_cvp;
- u16 cvp_handle;
+
if (v == NULL) {
pr_err("%s: v is NULL\n", __func__);
- return -EINVAL;
- }
- apr_cvp = common.apr_q6_cvp;
- if (!apr_cvp) {
- pr_err("%s: apr_cvp is NULL.\n", __func__);
- return -EINVAL;
+ goto fail;
}
- cvp_handle = voice_get_cvp_handle(v);
+
+ if (!common.apr_q6_cvp) {
+ pr_err("%s: apr_cvp is NULL.\n", __func__);
+
+ goto fail;
+ }
cvp_mute_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
APR_HDR_LEN(APR_HDR_SIZE),
@@ -2066,25 +2652,32 @@
cvp_mute_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
sizeof(cvp_mute_cmd) - APR_HDR_SIZE);
cvp_mute_cmd.hdr.src_port = v->session_id;
- cvp_mute_cmd.hdr.dest_port = cvp_handle;
+ cvp_mute_cmd.hdr.dest_port = voice_get_cvp_handle(v);
cvp_mute_cmd.hdr.token = 0;
- cvp_mute_cmd.hdr.opcode = VSS_IVOCPROC_CMD_SET_MUTE;
- cvp_mute_cmd.cvp_set_mute.direction = 1;
+ cvp_mute_cmd.hdr.opcode = VSS_IVOLUME_CMD_MUTE_V2;
+ cvp_mute_cmd.cvp_set_mute.direction = VSS_IVOLUME_DIRECTION_RX;
cvp_mute_cmd.cvp_set_mute.mute_flag = v->dev_rx.mute;
+
v->cvp_state = CMD_STATUS_FAIL;
- ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_mute_cmd);
+ ret = apr_send_pkt(common.apr_q6_cvp, (uint32_t *) &cvp_mute_cmd);
if (ret < 0) {
- pr_err("Fail in sending RX device mute cmd\n");
- return -EINVAL;
+ pr_err("%s: Error %d sending rx device cmd\n", __func__, ret);
+
+ goto fail;
}
ret = wait_event_timeout(v->cvp_wait,
(v->cvp_state == CMD_STATUS_SUCCESS),
msecs_to_jiffies(TIMEOUT_MS));
if (!ret) {
- pr_err("%s: wait_event timeout\n", __func__);
- return -EINVAL;
+ pr_err("%s: Command timeout\n", __func__);
+
+ goto fail;
}
+
return 0;
+
+fail:
+ return -EINVAL;
}
static int voice_send_vol_index_cmd(struct voice_data *v)
@@ -2569,6 +3162,9 @@
goto fail;
}
+ voice_send_cvp_deregister_vol_cal_cmd(v);
+ voice_send_cvp_deregister_cal_cmd(v);
+ voice_send_cvp_deregister_dev_cfg_cmd(v);
v->voc_state = VOC_CHANGE;
}
@@ -2598,6 +3194,10 @@
goto fail;
}
+ voice_send_cvp_register_dev_cfg_cmd(v);
+ voice_send_cvp_register_cal_cmd(v);
+ voice_send_cvp_register_vol_cal_cmd(v);
+
ret = voice_send_enable_vocproc_cmd(v);
if (ret < 0) {
pr_err("%s: enable vocproc failed %d\n", __func__, ret);
@@ -2985,8 +3585,21 @@
pr_err("create mvm and cvs failed\n");
goto fail;
}
+
+ /* Memory map the calibration memory block. */
+ ret = voice_mem_map_cal_block(v);
+ if (ret < 0) {
+ pr_err("%s: Memory map of cal block failed %d\n",
+ __func__, ret);
+ /* Allow call to continue, call quality will be bad. */
+ }
+
if (is_voip_session(session_id)) {
- ret = voice_send_mvm_map_memory_physical_cmd(v);
+ ret = voice_map_memory_physical_cmd(v,
+ &v->shmem_info.memtbl,
+ v->shmem_info.sh_buf.buf[0].phys,
+ v->shmem_info.sh_buf.buf[0].size * NUM_OF_BUFFERS,
+ VOIP_MEM_MAP_TOKEN);
if (ret) {
pr_err("%s: mvm_map_memory_phy failed %d\n",
__func__, ret);
@@ -3132,7 +3745,8 @@
}
} else if (data->opcode == VSS_IMEMORY_RSP_MAP) {
pr_debug("%s, Revd VSS_IMEMORY_RSP_MAP response\n", __func__);
- if (data->payload_size) {
+
+ if (data->payload_size && data->token == VOIP_MEM_MAP_TOKEN) {
ptr = data->payload;
if (ptr[0]) {
v->shmem_info.mem_handle = ptr[0];
@@ -3141,6 +3755,21 @@
v->mvm_state = CMD_STATUS_SUCCESS;
wake_up(&v->mvm_wait);
}
+ } else if (data->payload_size &&
+ data->token == VOC_CAL_MEM_MAP_TOKEN) {
+ ptr = data->payload;
+ if (ptr[0]) {
+ c->cal_mem_handle = ptr[0];
+
+ pr_debug("%s: cal mem handle 0x%x\n",
+ __func__, c->cal_mem_handle);
+
+ v->mvm_state = CMD_STATUS_SUCCESS;
+ wake_up(&v->mvm_wait);
+ }
+ } else {
+ pr_err("%s: Unknown mem map token %d\n",
+ __func__, data->token);
}
}
return 0;
@@ -3204,14 +3833,14 @@
v->cvs_state = CMD_STATUS_SUCCESS;
wake_up(&v->cvs_wait);
break;
- case VSS_ISTREAM_CMD_SET_MUTE:
+ case VSS_IVOLUME_CMD_MUTE_V2:
case VSS_ISTREAM_CMD_SET_MEDIA_TYPE:
case VSS_ISTREAM_CMD_VOC_AMR_SET_ENC_RATE:
case VSS_ISTREAM_CMD_VOC_AMRWB_SET_ENC_RATE:
case VSS_ISTREAM_CMD_SET_ENC_DTX_MODE:
case VSS_ISTREAM_CMD_CDMA_SET_ENC_MINMAX_RATE:
case APRV2_IBASIC_CMD_DESTROY_SESSION:
- case VSS_ISTREAM_CMD_REGISTER_CALIBRATION_DATA:
+ case VSS_ISTREAM_CMD_REGISTER_CALIBRATION_DATA_V2:
case VSS_ISTREAM_CMD_DEREGISTER_CALIBRATION_DATA:
case VSS_ICOMMON_CMD_MAP_MEMORY:
case VSS_ICOMMON_CMD_UNMAP_MEMORY:
@@ -3410,13 +4039,15 @@
case VSS_IVOCPROC_CMD_ENABLE:
case VSS_IVOCPROC_CMD_DISABLE:
case APRV2_IBASIC_CMD_DESTROY_SESSION:
- case VSS_IVOCPROC_CMD_REGISTER_VOLUME_CAL_TABLE:
- case VSS_IVOCPROC_CMD_DEREGISTER_VOLUME_CAL_TABLE:
- case VSS_IVOCPROC_CMD_REGISTER_CALIBRATION_DATA:
+ case VSS_IVOCPROC_CMD_REGISTER_VOL_CALIBRATION_DATA:
+ case VSS_IVOCPROC_CMD_DEREGISTER_VOL_CALIBRATION_DATA:
+ case VSS_IVOCPROC_CMD_REGISTER_CALIBRATION_DATA_V2:
case VSS_IVOCPROC_CMD_DEREGISTER_CALIBRATION_DATA:
+ case VSS_IVOCPROC_CMD_REGISTER_DEVICE_CONFIG:
+ case VSS_IVOCPROC_CMD_DEREGISTER_DEVICE_CONFIG:
case VSS_ICOMMON_CMD_MAP_MEMORY:
case VSS_ICOMMON_CMD_UNMAP_MEMORY:
- case VSS_IVOCPROC_CMD_SET_MUTE:
+ case VSS_IVOLUME_CMD_MUTE_V2:
v->cvp_state = CMD_STATUS_SUCCESS;
wake_up(&v->cvp_wait);
break;
@@ -3564,6 +4195,74 @@
return -EINVAL;
}
+static int voice_alloc_cal_mem_map_table(void)
+{
+ int ret = 0;
+ int len;
+
+ common.cal_mem_map_table.client = msm_ion_client_create(UINT_MAX,
+ "voc_client");
+
+ if (IS_ERR_OR_NULL((void *) common.cal_mem_map_table.client)) {
+ pr_err("%s: ION create client for cal mem map table failed\n",
+ __func__);
+
+ goto err;
+ }
+
+ common.cal_mem_map_table.handle =
+ ion_alloc(common.cal_mem_map_table.client,
+ sizeof(struct vss_imemory_table_t),
+ SZ_4K, (0x1 << ION_AUDIO_HEAP_ID), 0);
+ if (IS_ERR_OR_NULL((void *) common.cal_mem_map_table.handle)) {
+ pr_err("%s: ION memory alloc for cal mem map table failed\n",
+ __func__);
+
+ goto err_ion_client;
+ }
+
+ ret = ion_phys(common.cal_mem_map_table.client,
+ common.cal_mem_map_table.handle,
+ (ion_phys_addr_t *) &common.cal_mem_map_table.phys,
+ (size_t *) &len);
+ if (ret) {
+ pr_err("%s: Phy addr for cal mem map table failed %d\n",
+ __func__, ret);
+
+ goto err_ion_handle;
+ }
+
+ common.cal_mem_map_table.data =
+ ion_map_kernel(common.cal_mem_map_table.client,
+ common.cal_mem_map_table.handle);
+ if (IS_ERR_OR_NULL((void *) common.cal_mem_map_table.data)) {
+ pr_err("%s: Virtual addr for cal memory map table failed\n",
+ __func__);
+
+ goto err_ion_handle;
+ }
+
+ memset(common.cal_mem_map_table.data, 0,
+ sizeof(struct vss_imemory_table_t));
+
+ common.cal_mem_map_table.size = sizeof(struct vss_imemory_table_t);
+
+ pr_debug("%s: data 0x%x phys 0x%x\n", __func__,
+ (unsigned int) common.cal_mem_map_table.data,
+ common.cal_mem_map_table.phys);
+
+ return 0;
+
+err_ion_handle:
+ ion_free(common.cal_mem_map_table.client,
+ common.cal_mem_map_table.handle);
+err_ion_client:
+ ion_client_destroy(common.cal_mem_map_table.client);
+ memset(&common.cal_mem_map_table, 0, sizeof(common.cal_mem_map_table));
+err:
+ return -EINVAL;
+}
+
static int __init voice_init(void)
{
int rc = 0, i = 0;
@@ -3612,6 +4311,9 @@
pr_err("failed to alloc mem map talbe %d\n", rc);
}
+ /* Allocate memory for calibration memory map table. */
+ rc = voice_alloc_cal_mem_map_table();
+
return rc;
}
diff --git a/sound/soc/msm/qdsp6v2/q6voice.h b/sound/soc/msm/qdsp6v2/q6voice.h
index df0cbec..9f82694 100644
--- a/sound/soc/msm/qdsp6v2/q6voice.h
+++ b/sound/soc/msm/qdsp6v2/q6voice.h
@@ -25,6 +25,8 @@
*/
#define BUFFER_BLOCK_SIZE 4096
+#define MAX_COL_INFO_SIZE 324
+
#define VOC_REC_UPLINK 0x00
#define VOC_REC_DOWNLINK 0x01
#define VOC_REC_BOTH 0x02
@@ -437,9 +439,13 @@
#define APRV2_IBASIC_CMD_DESTROY_SESSION 0x0001003C
-#define VSS_ISTREAM_CMD_SET_MUTE 0x00011022
+/*
+ * This command changes the mute setting. The new mute setting will
+ * be applied over the specified ramp duration.
+ */
+#define VSS_IVOLUME_CMD_MUTE_V2 0x0001138B
-#define VSS_ISTREAM_CMD_REGISTER_CALIBRATION_DATA 0x00011279
+#define VSS_ISTREAM_CMD_REGISTER_CALIBRATION_DATA_V2 0x00011369
#define VSS_ISTREAM_CMD_DEREGISTER_CALIBRATION_DATA 0x0001127A
@@ -541,22 +547,33 @@
*/
} __packed;
-struct vss_istream_cmd_set_mute_t {
+#define VSS_IVOLUME_DIRECTION_TX 0
+#define VSS_IVOLUME_DIRECTION_RX 1
+
+#define VSS_IVOLUME_MUTE_OFF 0
+#define VSS_IVOLUME_MUTE_ON 1
+
+#define DEFAULT_MUTE_RAMP_DURATION 500
+
+struct vss_ivolume_cmd_mute_v2_t {
uint16_t direction;
- /**<
- * 0 : TX only
- * 1 : RX only
- * 2 : TX and Rx
- */
+ /*
+ * The direction field sets the direction to apply the mute command.
+ * The Supported values:
+ * VSS_IVOLUME_DIRECTION_TX
+ * VSS_IVOLUME_DIRECTION_RX
+ */
uint16_t mute_flag;
- /**<
- * Mute, un-mute.
- *
- * 0 : Silence disable
- * 1 : Silence enable
- * 2 : CNG enable. Applicable to TX only. If set on RX behavior
- * will be the same as 1
- */
+ /*
+ * Turn mute on or off. The Supported values:
+ * VSS_IVOLUME_MUTE_OFF
+ * VSS_IVOLUME_MUTE_ON
+ */
+ uint16_t ramp_duration_ms;
+ /*
+ * Mute change ramp duration in milliseconds.
+ * The Supported values: 0 to 5000.
+ */
} __packed;
struct vss_istream_cmd_create_full_control_session_t {
@@ -666,14 +683,21 @@
*/
} __packed;
-struct vss_istream_cmd_register_calibration_data_t {
- uint32_t phys_addr;
- /* Phsical address to be registered with stream. The calibration data
- * is stored at this address.
- */
- uint32_t mem_size;
+struct vss_istream_cmd_register_calibration_data_v2_t {
+ uint32_t cal_mem_handle;
+ /* Handle to the shared memory that holds the calibration data. */
+ uint64_t cal_mem_address;
+ /* Location of calibration data. */
+ uint32_t cal_mem_size;
/* Size of the calibration data in bytes. */
-};
+ uint8_t column_info[MAX_COL_INFO_SIZE];
+ /*
+ * Column info contains the number of columns and the array of columns
+ * in the calibration table. The order in which the columns are provided
+ * here must match the order in which they exist in the calibration
+ * table provided.
+ */
+} __packed;
struct vss_icommon_cmd_set_ui_property_enable_t {
uint32_t module_id;
@@ -705,7 +729,7 @@
struct cvs_set_mute_cmd {
struct apr_hdr hdr;
- struct vss_istream_cmd_set_mute_t cvs_set_mute;
+ struct vss_ivolume_cmd_mute_v2_t cvs_set_mute;
} __packed;
struct cvs_set_media_type_cmd {
@@ -740,7 +764,7 @@
struct cvs_register_cal_data_cmd {
struct apr_hdr hdr;
- struct vss_istream_cmd_register_calibration_data_t cvs_cal_data;
+ struct vss_istream_cmd_register_calibration_data_v2_t cvs_cal_data;
} __packed;
struct cvs_deregister_cal_data_cmd {
@@ -797,11 +821,24 @@
#define VSS_IVOCPROC_CMD_DISABLE 0x000110E1
/**< No payload. Wait for APRV2_IBASIC_RSP_RESULT response. */
-#define VSS_IVOCPROC_CMD_REGISTER_CALIBRATION_DATA 0x00011275
-#define VSS_IVOCPROC_CMD_DEREGISTER_CALIBRATION_DATA 0x00011276
+/*
+ * Registers the memory that contains device specific configuration data with
+ * the vocproc. The client must register device configuration data with the
+ * vocproc that corresponds with the device being set on the vocproc.
+ */
+#define VSS_IVOCPROC_CMD_REGISTER_DEVICE_CONFIG 0x00011371
-#define VSS_IVOCPROC_CMD_REGISTER_VOLUME_CAL_TABLE 0x00011277
-#define VSS_IVOCPROC_CMD_DEREGISTER_VOLUME_CAL_TABLE 0x00011278
+/*
+ * Deregisters the memory that holds device configuration data from the
+ vocproc.
+*/
+#define VSS_IVOCPROC_CMD_DEREGISTER_DEVICE_CONFIG 0x00011372
+
+#define VSS_IVOCPROC_CMD_REGISTER_CALIBRATION_DATA_V2 0x00011373
+#define VSS_IVOCPROC_CMD_DEREGISTER_CALIBRATION_DATA 0x00011276
+
+#define VSS_IVOCPROC_CMD_REGISTER_VOL_CALIBRATION_DATA 0x00011374
+#define VSS_IVOCPROC_CMD_DEREGISTER_VOL_CALIBRATION_DATA 0x00011375
#define VSS_IVOCPROC_TOPOLOGY_ID_NONE 0x00010F70
#define VSS_IVOCPROC_TOPOLOGY_ID_TX_SM_ECNS 0x00010F71
@@ -847,8 +884,6 @@
#define VSS_MEDIA_ID_4GV_WB_MODEM 0x00010FC4
/*CDMA EVRC-WB vocoder modem format */
-#define VSS_IVOCPROC_CMD_SET_MUTE 0x000110EF
-
#define VOICE_CMD_SET_PARAM 0x00011006
#define VOICE_CMD_GET_PARAM 0x00011007
#define VOICE_EVT_GET_PARAM_ACK 0x00011008
@@ -941,39 +976,54 @@
*/
} __packed;
-struct vss_ivocproc_cmd_register_calibration_data_t {
- uint32_t phys_addr;
- /* Phsical address to be registered with vocproc. Calibration data
- * is stored at this address.
+struct vss_ivocproc_cmd_register_device_config_t {
+ uint32_t mem_handle;
+ /*
+ * Handle to the shared memory that holds the per-network calibration
+ * data.
*/
+ uint64_t mem_address;
+ /* Location of calibration data. */
uint32_t mem_size;
/* Size of the calibration data in bytes. */
} __packed;
-struct vss_ivocproc_cmd_register_volume_cal_table_t {
- uint32_t phys_addr;
- /* Phsical address to be registered with the vocproc. The volume
- * calibration table is stored at this location.
+struct vss_ivocproc_cmd_register_calibration_data_v2_t {
+ uint32_t cal_mem_handle;
+ /*
+ * Handle to the shared memory that holds the per-network calibration
+ * data.
*/
-
- uint32_t mem_size;
- /* Size of the volume calibration table in bytes. */
+ uint64_t cal_mem_address;
+ /* Location of calibration data. */
+ uint32_t cal_mem_size;
+ /* Size of the calibration data in bytes. */
+ uint8_t column_info[MAX_COL_INFO_SIZE];
+ /*
+ * Column info contains the number of columns and the array of columns
+ * in the calibration table. The order in which the columns are provided
+ * here must match the order in which they exist in the calibration
+ * table provided.
+ */
} __packed;
-struct vss_ivocproc_cmd_set_mute_t {
- uint16_t direction;
+struct vss_ivocproc_cmd_register_volume_cal_data_t {
+ uint32_t cal_mem_handle;
/*
- * 0 : TX only.
- * 1 : RX only.
- * 2 : TX and Rx.
- */
- uint16_t mute_flag;
+ * Handle to the shared memory that holds the volume calibration
+ * data.
+ */
+ uint64_t cal_mem_address;
+ /* Location of volume calibration data. */
+ uint32_t cal_mem_size;
+ /* Size of the volume calibration data in bytes. */
+ uint8_t column_info[MAX_COL_INFO_SIZE];
/*
- * Mute, un-mute.
- *
- * 0 : Disable.
- * 1 : Enable.
- */
+ * Column info contains the number of columns and the array of columns
+ * in the calibration table. The order in which the columns are provided
+ * here must match the order in which they exist in the calibration
+ * table provided.
+ */
} __packed;
struct cvp_create_full_ctl_session_cmd {
@@ -999,27 +1049,36 @@
struct vss_ivocproc_cmd_set_volume_index_t cvp_set_vol_idx;
} __packed;
+struct cvp_register_dev_cfg_cmd {
+ struct apr_hdr hdr;
+ struct vss_ivocproc_cmd_register_device_config_t cvp_dev_cfg_data;
+} __packed;
+
+struct cvp_deregister_dev_cfg_cmd {
+ struct apr_hdr hdr;
+} __packed;
+
struct cvp_register_cal_data_cmd {
struct apr_hdr hdr;
- struct vss_ivocproc_cmd_register_calibration_data_t cvp_cal_data;
+ struct vss_ivocproc_cmd_register_calibration_data_v2_t cvp_cal_data;
} __packed;
struct cvp_deregister_cal_data_cmd {
struct apr_hdr hdr;
} __packed;
-struct cvp_register_vol_cal_table_cmd {
+struct cvp_register_vol_cal_data_cmd {
struct apr_hdr hdr;
- struct vss_ivocproc_cmd_register_volume_cal_table_t cvp_vol_cal_tbl;
+ struct vss_ivocproc_cmd_register_volume_cal_data_t cvp_vol_cal_data;
} __packed;
-struct cvp_deregister_vol_cal_table_cmd {
+struct cvp_deregister_vol_cal_data_cmd {
struct apr_hdr hdr;
} __packed;
struct cvp_set_mute_cmd {
struct apr_hdr hdr;
- struct vss_ivocproc_cmd_set_mute_t cvp_set_mute;
+ struct vss_ivolume_cmd_mute_v2_t cvp_set_mute;
} __packed;
/* CB for up-link packets. */
@@ -1130,7 +1189,8 @@
/* APR to CVP in the Q6 */
void *apr_q6_cvp;
- struct ion_client *client;
+ struct mem_map_table cal_mem_map_table;
+ uint32_t cal_mem_handle;
struct cal_mem cvp_cal;
struct cal_mem cvs_cal;