Merge "msm: Add support for 8092 in makefile" into msm-3.4
diff --git a/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt b/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt
index f082a0f..0eb186e 100644
--- a/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt
+++ b/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt
@@ -202,3 +202,55 @@
qcom,msm-ocmem-audio-ib = <471859200>;
};
+* MSM8974 ASoC Machine driver
+
+Required properties:
+- compatible : "qcom,msm8974-audio-taiko"
+- qcom,model : The user-visible name of this sound card.
+- qcom,audio-routing : A list of the connections between audio components.
+ Each entry is a pair of strings, the first being the connection's sink,
+ the second being the connection's source.
+- qcom,cdc-mclk-gpios : GPIO on which mclk signal is comming.
+- taiko-mclk-clk : phandle to PMIC8941 clkdiv1 node.
+- qcom,taiko-mclk-clk-freq : Taiko mclk Freq in Hz. currently only 9600000Hz
+ is supported.
+
+Example:
+
+sound {
+ compatible = "qcom,msm8974-audio-taiko";
+ qcom,model = "msm8974-taiko-snd-card";
+
+ qcom,audio-routing =
+ "RX_BIAS", "MCLK",
+ "LDO_H", "MCLK",
+ "HEADPHONE", "LDO_H",
+ "Ext Spk Bottom Pos", "LINEOUT1",
+ "Ext Spk Bottom Neg", "LINEOUT3",
+ "Ext Spk Top Pos", "LINEOUT2",
+ "Ext Spk Top Neg", "LINEOUT4",
+ "AMIC1", "MIC BIAS1 Internal1",
+ "MIC BIAS1 Internal1", "Handset Mic",
+ "AMIC2", "MIC BIAS2 External",
+ "MIC BIAS2 External", "Headset Mic",
+ "AMIC3", "MIC BIAS3 Internal1",
+ "MIC BIAS3 Internal1", "ANCRight Headset Mic",
+ "AMIC4", "MIC BIAS1 Internal2",
+ "MIC BIAS1 Internal2", "ANCLeft Headset Mic",
+ "DMIC1", "MIC BIAS1 External",
+ "MIC BIAS1 External", "Digital Mic1",
+ "DMIC2", "MIC BIAS1 External",
+ "MIC BIAS1 External", "Digital Mic2",
+ "DMIC3", "MIC BIAS3 External",
+ "MIC BIAS3 External", "Digital Mic3",
+ "DMIC4", "MIC BIAS3 External",
+ "MIC BIAS3 External", "Digital Mic4",
+ "DMIC5", "MIC BIAS4 External",
+ "MIC BIAS4 External", "Digital Mic5",
+ "DMIC6", "MIC BIAS4 External",
+ "MIC BIAS4 External", "Digital Mic6";
+
+ qcom,cdc-mclk-gpios = <&pm8941_gpios 15 0>;
+ taiko-mclk-clk = <&pm8941_clkdiv1>;
+ qcom,taiko-mclk-clk-freq = <9600000>;
+};
diff --git a/arch/arm/boot/dts/msm8974-clock.dtsi b/arch/arm/boot/dts/msm8974-clock.dtsi
index bdc5d9b..043346f 100644
--- a/arch/arm/boot/dts/msm8974-clock.dtsi
+++ b/arch/arm/boot/dts/msm8974-clock.dtsi
@@ -15,6 +15,7 @@
qcom,pm8941@0 {
pm8941_clkdiv1: clkdiv@5b00 {
+ qcom,cxo-div = <2>;
};
pm8941_clkdiv2: clkdiv@5c00 {
diff --git a/arch/arm/boot/dts/msm8974-gpio.dtsi b/arch/arm/boot/dts/msm8974-gpio.dtsi
index b36859e..caea36c 100644
--- a/arch/arm/boot/dts/msm8974-gpio.dtsi
+++ b/arch/arm/boot/dts/msm8974-gpio.dtsi
@@ -86,6 +86,13 @@
gpio@ce00 {
status = "ok";
+ qcom,mode = <1>;
+ qcom,output-type = <0>;
+ qcom,pull = <5>;
+ qcom,vin-sel = <2>;
+ qcom,out-strength = <3>;
+ qcom,src-select = <2>;
+ qcom,master-en = <1>;
};
gpio@cf00 {
diff --git a/arch/arm/boot/dts/msm8974-mdss.dtsi b/arch/arm/boot/dts/msm8974-mdss.dtsi
index dbaa492..0382021 100644
--- a/arch/arm/boot/dts/msm8974-mdss.dtsi
+++ b/arch/arm/boot/dts/msm8974-mdss.dtsi
@@ -29,6 +29,30 @@
vreg-supply = <&pm8941_l2>;
};
+ qcom,hdmi_tx@fd922100 {
+ cell-index = <0>;
+ compatible = "qcom,hdmi-tx";
+ reg = <0xfd922100 0x35C>,
+ <0xfd922500 0x7C>,
+ <0xfc4b8000 0x60F0>;
+ reg-names = "core_physical", "phy_physical", "qfprom_physical";
+
+ hpd-5v-supply = <&pm8941_mvs2>;
+ core-vdda-supply = <&pm8941_l12>;
+ core-vcc-supply = <&pm8941_s3>;
+ qcom,hdmi-tx-supply-names = "hpd-5v", "core-vdda", "core-vcc";
+ qcom,hdmi-tx-supply-type = <0 1 1>;
+ qcom,hdmi-tx-min-voltage-level = <0 1800000 1800000>;
+ qcom,hdmi-tx-max-voltage-level = <0 1800000 1800000>;
+ qcom,hdmi-tx-op-mode = <0 1800000 0>;
+
+ gpios = <&msmgpio 31 0>,
+ <&msmgpio 32 0>,
+ <&msmgpio 33 0>,
+ <&msmgpio 34 0>;
+ qcom,hdmi-tx-gpio-names = "cec-pin", "hpd-ddc-clk", "hpd-ddc-data", "hpd-pin";
+ };
+
qcom,mdss_wb_panel {
compatible = "qcom,mdss_wb";
qcom,mdss_pan_res = <640 480>;
diff --git a/arch/arm/boot/dts/msm8974.dtsi b/arch/arm/boot/dts/msm8974.dtsi
index 9d2ded1..fcc5070 100644
--- a/arch/arm/boot/dts/msm8974.dtsi
+++ b/arch/arm/boot/dts/msm8974.dtsi
@@ -279,6 +279,44 @@
};
};
+ sound {
+ compatible = "qcom,msm8974-audio-taiko";
+ qcom,model = "msm8974-taiko-snd-card";
+
+ qcom,audio-routing =
+ "RX_BIAS", "MCLK",
+ "LDO_H", "MCLK",
+ "HEADPHONE", "LDO_H",
+ "Ext Spk Bottom Pos", "LINEOUT1",
+ "Ext Spk Bottom Neg", "LINEOUT3",
+ "Ext Spk Top Pos", "LINEOUT2",
+ "Ext Spk Top Neg", "LINEOUT4",
+ "AMIC1", "MIC BIAS1 Internal1",
+ "MIC BIAS1 Internal1", "Handset Mic",
+ "AMIC2", "MIC BIAS2 External",
+ "MIC BIAS2 External", "Headset Mic",
+ "AMIC3", "MIC BIAS3 Internal1",
+ "MIC BIAS3 Internal1", "ANCRight Headset Mic",
+ "AMIC4", "MIC BIAS1 Internal2",
+ "MIC BIAS1 Internal2", "ANCLeft Headset Mic",
+ "DMIC1", "MIC BIAS1 External",
+ "MIC BIAS1 External", "Digital Mic1",
+ "DMIC2", "MIC BIAS1 External",
+ "MIC BIAS1 External", "Digital Mic2",
+ "DMIC3", "MIC BIAS3 External",
+ "MIC BIAS3 External", "Digital Mic3",
+ "DMIC4", "MIC BIAS3 External",
+ "MIC BIAS3 External", "Digital Mic4",
+ "DMIC5", "MIC BIAS4 External",
+ "MIC BIAS4 External", "Digital Mic5",
+ "DMIC6", "MIC BIAS4 External",
+ "MIC BIAS4 External", "Digital Mic6";
+
+ qcom,cdc-mclk-gpios = <&pm8941_gpios 15 0>;
+ taiko-mclk-clk = <&pm8941_clkdiv1>;
+ qcom,taiko-mclk-clk-freq = <9600000>;
+ };
+
spmi_bus: qcom,spmi@fc4c0000 {
cell-index = <0>;
compatible = "qcom,spmi-pmic-arb";
diff --git a/arch/arm/mach-msm/board-8974-gpiomux.c b/arch/arm/mach-msm/board-8974-gpiomux.c
index 74c503d..fd2329f 100644
--- a/arch/arm/mach-msm/board-8974-gpiomux.c
+++ b/arch/arm/mach-msm/board-8974-gpiomux.c
@@ -126,6 +126,56 @@
},
};
+
+static struct gpiomux_setting hdmi_suspend_cfg = {
+ .func = GPIOMUX_FUNC_GPIO,
+ .drv = GPIOMUX_DRV_2MA,
+ .pull = GPIOMUX_PULL_DOWN,
+};
+
+static struct gpiomux_setting hdmi_active_1_cfg = {
+ .func = GPIOMUX_FUNC_1,
+ .drv = GPIOMUX_DRV_2MA,
+ .pull = GPIOMUX_PULL_UP,
+};
+
+static struct gpiomux_setting hdmi_active_2_cfg = {
+ .func = GPIOMUX_FUNC_1,
+ .drv = GPIOMUX_DRV_16MA,
+ .pull = GPIOMUX_PULL_DOWN,
+};
+
+static struct msm_gpiomux_config msm_hdmi_configs[] __initdata = {
+ {
+ .gpio = 31,
+ .settings = {
+ [GPIOMUX_ACTIVE] = &hdmi_active_1_cfg,
+ [GPIOMUX_SUSPENDED] = &hdmi_suspend_cfg,
+ },
+ },
+ {
+ .gpio = 32,
+ .settings = {
+ [GPIOMUX_ACTIVE] = &hdmi_active_1_cfg,
+ [GPIOMUX_SUSPENDED] = &hdmi_suspend_cfg,
+ },
+ },
+ {
+ .gpio = 33,
+ .settings = {
+ [GPIOMUX_ACTIVE] = &hdmi_active_1_cfg,
+ [GPIOMUX_SUSPENDED] = &hdmi_suspend_cfg,
+ },
+ },
+ {
+ .gpio = 34,
+ .settings = {
+ [GPIOMUX_ACTIVE] = &hdmi_active_2_cfg,
+ [GPIOMUX_SUSPENDED] = &hdmi_suspend_cfg,
+ },
+ },
+};
+
static struct msm_gpiomux_config msm_blsp_configs[] __initdata = {
#if defined(CONFIG_KS8851) || defined(CONFIG_KS8851_MODULE)
{
@@ -394,4 +444,6 @@
msm_gpiomux_install(msm_sensor_configs, ARRAY_SIZE(msm_sensor_configs));
msm_gpiomux_install(msm_taiko_config, ARRAY_SIZE(msm_taiko_config));
+
+ msm_gpiomux_install(msm_hdmi_configs, ARRAY_SIZE(msm_hdmi_configs));
}
diff --git a/arch/arm/mach-msm/qdsp6v2/rtac.c b/arch/arm/mach-msm/qdsp6v2/rtac.c
index 8808375..82aa14c 100644
--- a/arch/arm/mach-msm/qdsp6v2/rtac.c
+++ b/arch/arm/mach-msm/qdsp6v2/rtac.c
@@ -768,7 +768,8 @@
goto done;
}
- if (copy_from_user(&payload_size, buf + sizeof(u32), sizeof(u32))) {
+ if (copy_from_user(&payload_size, buf + sizeof(payload_size),
+ sizeof(payload_size))) {
pr_err("%s: Could not copy payload size from user buffer\n",
__func__);
goto done;
@@ -780,7 +781,8 @@
goto done;
}
- if (copy_from_user(&dest_port, buf + 2 * sizeof(u32), sizeof(u32))) {
+ if (copy_from_user(&dest_port, buf + 2 * sizeof(dest_port),
+ sizeof(dest_port))) {
pr_err("%s: Could not copy port id from user buffer\n",
__func__);
goto done;
diff --git a/drivers/gpu/msm/a3xx_reg.h b/drivers/gpu/msm/a3xx_reg.h
index 6fe316a..05c7967 100644
--- a/drivers/gpu/msm/a3xx_reg.h
+++ b/drivers/gpu/msm/a3xx_reg.h
@@ -77,6 +77,9 @@
#define A3XX_CP_PFP_UCODE_DATA 0x1CA
#define A3XX_CP_ROQ_ADDR 0x1CC
#define A3XX_CP_ROQ_DATA 0x1CD
+#define A3XX_CP_MERCIU_ADDR 0x1D1
+#define A3XX_CP_MERCIU_DATA 0x1D2
+#define A3XX_CP_MERCIU_DATA2 0x1D3
#define A3XX_CP_MEQ_ADDR 0x1DA
#define A3XX_CP_MEQ_DATA 0x1DB
#define A3XX_CP_HW_FAULT 0x45C
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index d99d398..7317702 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -1094,7 +1094,7 @@
static int
adreno_ocmem_gmem_malloc(struct adreno_device *adreno_dev)
{
- if (adreno_dev->gpurev != ADRENO_REV_A330)
+ if (!adreno_is_a330(adreno_dev))
return 0;
/* OCMEM is only needed once, do not support consective allocation */
@@ -1115,7 +1115,7 @@
static void
adreno_ocmem_gmem_free(struct adreno_device *adreno_dev)
{
- if (adreno_dev->gpurev != ADRENO_REV_A330)
+ if (!adreno_is_a330(adreno_dev))
return;
if (adreno_dev->ocmem_hdl == NULL)
diff --git a/drivers/gpu/msm/adreno.h b/drivers/gpu/msm/adreno.h
index d151255..66402fe 100644
--- a/drivers/gpu/msm/adreno.h
+++ b/drivers/gpu/msm/adreno.h
@@ -165,6 +165,9 @@
extern const unsigned int a3xx_registers[];
extern const unsigned int a3xx_registers_count;
+extern const unsigned int a330_registers[];
+extern const unsigned int a330_registers_count;
+
extern unsigned int hang_detect_regs[];
extern const unsigned int hang_detect_regs_count;
@@ -252,6 +255,11 @@
return (adreno_dev->gpurev == ADRENO_REV_A320);
}
+static inline int adreno_is_a330(struct adreno_device *adreno_dev)
+{
+ return (adreno_dev->gpurev == ADRENO_REV_A330);
+}
+
static inline int adreno_rb_ctxtswitch(unsigned int *cmd)
{
return (cmd[0] == cp_nop_packet(1) &&
diff --git a/drivers/gpu/msm/adreno_a2xx_snapshot.c b/drivers/gpu/msm/adreno_a2xx_snapshot.c
index 2368264..282440c 100644
--- a/drivers/gpu/msm/adreno_a2xx_snapshot.c
+++ b/drivers/gpu/msm/adreno_a2xx_snapshot.c
@@ -232,6 +232,7 @@
int *remain, int hang)
{
struct kgsl_device *device = &adreno_dev->dev;
+ struct kgsl_snapshot_registers_list list;
struct kgsl_snapshot_registers regs;
unsigned int pmoverride;
@@ -248,10 +249,13 @@
regs.count = a225_registers_count;
}
+ list.registers = ®s;
+ list.count = 1;
+
/* Master set of (non debug) registers */
snapshot = kgsl_snapshot_add_section(device,
KGSL_SNAPSHOT_SECTION_REGS, snapshot, remain,
- kgsl_snapshot_dump_regs, ®s);
+ kgsl_snapshot_dump_regs, &list);
/* CP_STATE_DEBUG indexed registers */
snapshot = kgsl_snapshot_indexed_registers(device, snapshot,
diff --git a/drivers/gpu/msm/adreno_a3xx.c b/drivers/gpu/msm/adreno_a3xx.c
index 4b3263d..4ae2fa8 100644
--- a/drivers/gpu/msm/adreno_a3xx.c
+++ b/drivers/gpu/msm/adreno_a3xx.c
@@ -69,6 +69,14 @@
const unsigned int a3xx_registers_count = ARRAY_SIZE(a3xx_registers) / 2;
+/* The set of additional registers to be dumped for A330 */
+
+const unsigned int a330_registers[] = {
+ 0x1d0, 0x1d0, 0x1d4, 0x1d4, 0x453, 0x453,
+};
+
+const unsigned int a330_registers_count = ARRAY_SIZE(a330_registers) / 2;
+
/* Simple macro to facilitate bit setting in the gmem2sys and sys2gmem
* functions.
*/
@@ -2698,7 +2706,7 @@
struct kgsl_device *device = &adreno_dev->dev;
/* Set up 16 deep read/write request queues */
- if (adreno_dev->gpurev == ADRENO_REV_A330) {
+ if (adreno_is_a330(adreno_dev)) {
adreno_regwrite(device, A3XX_VBIF_IN_RD_LIM_CONF0, 0x18181818);
adreno_regwrite(device, A3XX_VBIF_IN_RD_LIM_CONF1, 0x18181818);
adreno_regwrite(device, A3XX_VBIF_OUT_RD_LIM_CONF0, 0x18181818);
@@ -2781,7 +2789,7 @@
A3XX_RBBM_CLOCK_CTL_DEFAULT);
/* Set the OCMEM base address for A330 */
- if (adreno_dev->gpurev == ADRENO_REV_A330) {
+ if (adreno_is_a330(adreno_dev)) {
adreno_regwrite(device, A3XX_RB_GMEM_BASE_ADDR,
(unsigned int)(adreno_dev->ocmem_base >> 14));
}
diff --git a/drivers/gpu/msm/adreno_a3xx_snapshot.c b/drivers/gpu/msm/adreno_a3xx_snapshot.c
index a3bee4d..d49fc23 100644
--- a/drivers/gpu/msm/adreno_a3xx_snapshot.c
+++ b/drivers/gpu/msm/adreno_a3xx_snapshot.c
@@ -156,28 +156,68 @@
return DEBUG_SECTION_SZ(size);
}
-#define CP_ROQ_SIZE 128
+/* This is the ROQ buffer size on both the A305 and A320 */
+#define A320_CP_ROQ_SIZE 128
+/* This is the ROQ buffer size on the A330 */
+#define A330_CP_ROQ_SIZE 512
static int a3xx_snapshot_cp_roq(struct kgsl_device *device, void *snapshot,
int remain, void *priv)
{
+ struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
struct kgsl_snapshot_debug *header = snapshot;
unsigned int *data = snapshot + sizeof(*header);
- int i;
+ int i, size;
- if (remain < DEBUG_SECTION_SZ(CP_ROQ_SIZE)) {
+ /* The size of the ROQ buffer is core dependent */
+ size = adreno_is_a330(adreno_dev) ?
+ A330_CP_ROQ_SIZE : A320_CP_ROQ_SIZE;
+
+ if (remain < DEBUG_SECTION_SZ(size)) {
SNAPSHOT_ERR_NOMEM(device, "CP ROQ DEBUG");
return 0;
}
header->type = SNAPSHOT_DEBUG_CP_ROQ;
- header->size = CP_ROQ_SIZE;
+ header->size = size;
adreno_regwrite(device, A3XX_CP_ROQ_ADDR, 0x0);
- for (i = 0; i < CP_ROQ_SIZE; i++)
+ for (i = 0; i < size; i++)
adreno_regread(device, A3XX_CP_ROQ_DATA, &data[i]);
- return DEBUG_SECTION_SZ(CP_ROQ_SIZE);
+ return DEBUG_SECTION_SZ(size);
+}
+
+#define A330_CP_MERCIU_QUEUE_SIZE 32
+
+static int a330_snapshot_cp_merciu(struct kgsl_device *device, void *snapshot,
+ int remain, void *priv)
+{
+ struct kgsl_snapshot_debug *header = snapshot;
+ unsigned int *data = snapshot + sizeof(*header);
+ int i, size;
+
+ /* The MERCIU data is two dwords per entry */
+ size = A330_CP_MERCIU_QUEUE_SIZE << 1;
+
+ if (remain < DEBUG_SECTION_SZ(size)) {
+ SNAPSHOT_ERR_NOMEM(device, "CP MERCIU DEBUG");
+ return 0;
+ }
+
+ header->type = SNAPSHOT_DEBUG_CP_MERCIU;
+ header->size = size;
+
+ adreno_regwrite(device, A3XX_CP_MERCIU_ADDR, 0x0);
+
+ for (i = 0; i < A330_CP_MERCIU_QUEUE_SIZE; i++) {
+ adreno_regread(device, A3XX_CP_MERCIU_DATA,
+ &data[(i * 2)]);
+ adreno_regread(device, A3XX_CP_MERCIU_DATA2,
+ &data[(i * 2) + 1]);
+ }
+
+ return DEBUG_SECTION_SZ(size);
}
#define DEBUGFS_BLOCK_SIZE 0x40
@@ -265,15 +305,26 @@
int *remain, int hang)
{
struct kgsl_device *device = &adreno_dev->dev;
- struct kgsl_snapshot_registers regs;
+ struct kgsl_snapshot_registers_list list;
+ struct kgsl_snapshot_registers regs[2];
- regs.regs = (unsigned int *) a3xx_registers;
- regs.count = a3xx_registers_count;
+ regs[0].regs = (unsigned int *) a3xx_registers;
+ regs[0].count = a3xx_registers_count;
+
+ list.registers = regs;
+ list.count = 1;
+
+ /* For A330, append the additional list of new registers to grab */
+ if (adreno_is_a330(adreno_dev)) {
+ regs[1].regs = (unsigned int *) a330_registers;
+ regs[1].count = a330_registers_count;
+ list.count++;
+ }
/* Master set of (non debug) registers */
snapshot = kgsl_snapshot_add_section(device,
KGSL_SNAPSHOT_SECTION_REGS, snapshot, remain,
- kgsl_snapshot_dump_regs, ®s);
+ kgsl_snapshot_dump_regs, &list);
/* CP_STATE_DEBUG indexed registers */
snapshot = kgsl_snapshot_indexed_registers(device, snapshot,
@@ -322,6 +373,12 @@
KGSL_SNAPSHOT_SECTION_DEBUG, snapshot, remain,
a3xx_snapshot_cp_roq, NULL);
+ if (adreno_is_a330(adreno_dev)) {
+ snapshot = kgsl_snapshot_add_section(device,
+ KGSL_SNAPSHOT_SECTION_DEBUG, snapshot, remain,
+ a330_snapshot_cp_merciu, NULL);
+ }
+
snapshot = a3xx_snapshot_debugbus(device, snapshot, remain);
/* Enable Clock gating */
diff --git a/drivers/gpu/msm/adreno_postmortem.c b/drivers/gpu/msm/adreno_postmortem.c
index 261e518..620b82c 100644
--- a/drivers/gpu/msm/adreno_postmortem.c
+++ b/drivers/gpu/msm/adreno_postmortem.c
@@ -869,9 +869,14 @@
else if (adreno_is_a225(adreno_dev))
adreno_dump_regs(device, a225_registers,
a225_registers_count);
- else if (adreno_is_a3xx(adreno_dev))
+ else if (adreno_is_a3xx(adreno_dev)) {
adreno_dump_regs(device, a3xx_registers,
a3xx_registers_count);
+
+ if (adreno_is_a330(adreno_dev))
+ adreno_dump_regs(device, a330_registers,
+ a330_registers_count);
+ }
}
error_vfree:
diff --git a/drivers/gpu/msm/kgsl_snapshot.c b/drivers/gpu/msm/kgsl_snapshot.c
index abaa8ce..a2ab5b1 100644
--- a/drivers/gpu/msm/kgsl_snapshot.c
+++ b/drivers/gpu/msm/kgsl_snapshot.c
@@ -414,18 +414,24 @@
int kgsl_snapshot_dump_regs(struct kgsl_device *device, void *snapshot,
int remain, void *priv)
{
+ struct kgsl_snapshot_registers_list *list = priv;
+
struct kgsl_snapshot_regs *header = snapshot;
- struct kgsl_snapshot_registers *regs = priv;
+ struct kgsl_snapshot_registers *regs;
unsigned int *data = snapshot + sizeof(*header);
- int count = 0, i, j;
+ int count = 0, i, j, k;
/* Figure out how many registers we are going to dump */
- for (i = 0; i < regs->count; i++) {
- int start = regs->regs[i * 2];
- int end = regs->regs[i * 2 + 1];
+ for (i = 0; i < list->count; i++) {
+ regs = &(list->registers[i]);
- count += (end - start + 1);
+ for (j = 0; j < regs->count; j++) {
+ int start = regs->regs[j * 2];
+ int end = regs->regs[j * 2 + 1];
+
+ count += (end - start + 1);
+ }
}
if (remain < (count * 8) + sizeof(*header)) {
@@ -433,16 +439,20 @@
return 0;
}
- for (i = 0; i < regs->count; i++) {
- unsigned int start = regs->regs[i * 2];
- unsigned int end = regs->regs[i * 2 + 1];
- for (j = start; j <= end; j++) {
- unsigned int val;
+ for (i = 0; i < list->count; i++) {
+ regs = &(list->registers[i]);
+ for (j = 0; j < regs->count; j++) {
+ unsigned int start = regs->regs[j * 2];
+ unsigned int end = regs->regs[j * 2 + 1];
- kgsl_regread(device, j, &val);
- *data++ = j;
- *data++ = val;
+ for (k = start; k <= end; k++) {
+ unsigned int val;
+
+ kgsl_regread(device, k, &val);
+ *data++ = k;
+ *data++ = val;
+ }
}
}
diff --git a/drivers/gpu/msm/kgsl_snapshot.h b/drivers/gpu/msm/kgsl_snapshot.h
index d54afcf..6d81bcf 100644
--- a/drivers/gpu/msm/kgsl_snapshot.h
+++ b/drivers/gpu/msm/kgsl_snapshot.h
@@ -144,6 +144,7 @@
#define SNAPSHOT_DEBUG_CP_PFP_RAM 9
#define SNAPSHOT_DEBUG_CP_ROQ 10
#define SNAPSHOT_DEBUG_SHADER_MEMORY 11
+#define SNAPSHOT_DEBUG_CP_MERCIU 12
struct kgsl_snapshot_debug {
int type; /* Type identifier for the attached tata */
@@ -240,12 +241,22 @@
/* A common helper function to dump a range of registers. This will be used in
* the GPU specific devices like this:
*
- * struct kgsl_snapshot_registers priv;
- * priv.regs = registers_array;;
- * priv.count = num_registers;
+ * struct kgsl_snapshot_registers_list list;
+ * struct kgsl_snapshot_registers priv[2];
+ *
+ * priv[0].regs = registers_array;;
+ * priv[o].count = num_registers;
+ * priv[1].regs = registers_array_new;;
+ * priv[1].count = num_registers_new;
+ *
+ * list.registers = priv;
+ * list.count = 2;
*
* kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_REGS, snapshot,
- * remain, kgsl_snapshot_dump_regs, &priv).
+ * remain, kgsl_snapshot_dump_regs, &list).
+ *
+ * Pass in a struct pointing to a list of register definitions as described
+ * below:
*
* Pass in an array of register range pairs in the form of:
* start reg, stop reg
@@ -257,6 +268,13 @@
int count; /* Number of entries in the array */
};
+struct kgsl_snapshot_registers_list {
+ /* Pointer to an array of register lists */
+ struct kgsl_snapshot_registers *registers;
+ /* Number of registers lists in the array */
+ int count;
+};
+
int kgsl_snapshot_dump_regs(struct kgsl_device *device, void *snapshot,
int remain, void *priv);
diff --git a/drivers/usb/host/ehci-msm-hsic.c b/drivers/usb/host/ehci-msm-hsic.c
index 2126ff0..86b2d45 100644
--- a/drivers/usb/host/ehci-msm-hsic.c
+++ b/drivers/usb/host/ehci-msm-hsic.c
@@ -35,6 +35,7 @@
#include <linux/usb/msm_hsusb.h>
#include <linux/gpio.h>
#include <linux/spinlock.h>
+#include <linux/irq.h>
#include <mach/msm_bus.h>
#include <mach/clk.h>
@@ -1365,12 +1366,16 @@
/* configure wakeup irq */
if (mehci->wakeup_irq) {
+ /* In case if wakeup gpio is pulled high at this point
+ * remote wakeup interrupt fires right after request_irq.
+ * Remote wake up interrupt only needs to be enabled when
+ * HSIC bus goes to suspend.
+ */
+ irq_set_status_flags(mehci->wakeup_irq, IRQ_NOAUTOEN);
ret = request_irq(mehci->wakeup_irq, msm_hsic_wakeup_irq,
IRQF_TRIGGER_HIGH,
"msm_hsic_wakeup", mehci);
- if (!ret) {
- disable_irq_nosync(mehci->wakeup_irq);
- } else {
+ if (ret) {
dev_err(&pdev->dev, "request_irq(%d) failed: %d\n",
mehci->wakeup_irq, ret);
mehci->wakeup_irq = 0;
diff --git a/drivers/video/msm/mdp4_overlay_dsi_cmd.c b/drivers/video/msm/mdp4_overlay_dsi_cmd.c
index 6f78305..c788c33 100644
--- a/drivers/video/msm/mdp4_overlay_dsi_cmd.c
+++ b/drivers/video/msm/mdp4_overlay_dsi_cmd.c
@@ -293,7 +293,7 @@
/* Blt */
if (vctrl->blt_wait)
need_dmap_wait = 1;
- else if (vctrl->ov_koff != vctrl->ov_done) {
+ if (vctrl->ov_koff != vctrl->ov_done) {
INIT_COMPLETION(vctrl->ov_comp);
need_ov_wait = 1;
}
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_errors.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_errors.c
index a2327d5..3620f1a 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_errors.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_errors.c
@@ -766,6 +766,6 @@
break;
}
if (string)
- DDL_MSG_ERROR("Recoverable Error code = 0x%x : %s",
+ DDL_MSG_LOW("Recoverable Error code = 0x%x : %s",
error_code, string);
}
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_helper.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_helper.c
index dfbee84..00addbe 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_helper.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_helper.c
@@ -471,7 +471,7 @@
ddl = ddl_context->current_ddl[1];
else {
DDL_MSG_LOW("STATE-CRITICAL-FRMRUN");
- DDL_MSG_ERROR("Unexpected channel ID = %d", channel_id);
+ DDL_MSG_LOW("Unexpected channel ID = %d", channel_id);
ddl = NULL;
}
return ddl;
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.c
index 416b497..07b2fe2 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_shared_mem.c
@@ -947,7 +947,7 @@
VIDC_SM_EXTENDED_PAR_HEIGHT_SHFT);
break;
default:
- DDL_MSG_HIGH("Incorrect Aspect Ratio.");
+ DDL_MSG_LOW("Incorrect Aspect Ratio.");
aspect_ratio_info->par_width = 1;
aspect_ratio_info->par_height = 1;
break;
@@ -1005,7 +1005,7 @@
VIDC_SM_EXTENDED_PAR_HEIGHT_SHFT);
break;
default:
- DDL_MSG_HIGH("Incorrect Aspect Ratio.");
+ DDL_MSG_LOW("Incorrect Aspect Ratio.");
aspect_ratio_info->par_width = 1;
aspect_ratio_info->par_height = 1;
break;
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.c
index 90114f7..5897a33 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.c
@@ -427,7 +427,7 @@
time_data->ddl_t1 = act_time;
DDL_MSG_LOW("\n%s(): Start Time (%u)", func_name, act_time);
} else if (vidc_msg_timing) {
- DDL_MSG_TIME("\n%s(): Timer already started! St(%u) Act(%u)",
+ DDL_MSG_LOW("\n%s(): Timer already started! St(%u) Act(%u)",
func_name, time_data->ddl_t1, act_time);
}
}
diff --git a/sound/soc/msm/msm8974.c b/sound/soc/msm/msm8974.c
index 45b69ea..c7820dd 100644
--- a/sound/soc/msm/msm8974.c
+++ b/sound/soc/msm/msm8974.c
@@ -13,11 +13,11 @@
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/gpio.h>
-#include <linux/mfd/pm8xxx/pm8921.h>
+#include <linux/of_gpio.h>
#include <linux/platform_device.h>
-#include <linux/gpio.h>
-#include <linux/mfd/pm8xxx/pm8921.h>
#include <linux/slab.h>
+#include <linux/mfd/pm8xxx/pm8921.h>
+#include <linux/qpnp/clkdiv.h>
#include <sound/core.h>
#include <sound/soc.h>
#include <sound/soc-dapm.h>
@@ -28,7 +28,7 @@
#include <qdsp6v2/msm-pcm-routing-v2.h>
#include "../codecs/wcd9320.h"
-/* 8974 machine driver */
+#define DRV_NAME "msm8974-asoc-taiko"
#define PM8921_GPIO_BASE NR_GPIO_IRQS
#define PM8921_GPIO_PM_TO_SYS(pm_gpio) (pm_gpio - 1 + PM8921_GPIO_BASE)
@@ -57,6 +57,11 @@
#define TABLA_MBHC_DEF_BUTTONS 8
#define TABLA_MBHC_DEF_RLOADS 5
+struct msm8974_asoc_mach_data {
+ int mclk_gpio;
+ u32 mclk_freq;
+};
+
/* Shared channel numbers for Slimbus ports that connect APQ to MDM. */
enum {
SLIM_1_RX_1 = 145, /* BT-SCO and USB TX */
@@ -76,12 +81,13 @@
static int msm_slim_0_tx_ch = 1;
static int msm_btsco_rate = BTSCO_RATE_8KHZ;
-static int msm_headset_gpios_configured;
static struct snd_soc_jack hs_jack;
static struct snd_soc_jack button_jack;
static struct mutex cdc_mclk_mutex;
+static struct q_clkdiv *codec_clk;
+static int clk_users;
static void msm_enable_ext_spk_amp_gpio(u32 spk_amp_gpio)
{
@@ -309,16 +315,67 @@
return 0;
}
-static int msm_mclk_event(struct snd_soc_dapm_widget *w,
+static int msm8974_enable_codec_ext_clk(struct snd_soc_codec *codec, int enable,
+ bool dapm)
+{
+ int ret = 0;
+ pr_debug("%s: enable = %d clk_users = %d\n",
+ __func__, enable, clk_users);
+
+ mutex_lock(&cdc_mclk_mutex);
+ if (enable) {
+ if (!codec_clk) {
+ dev_err(codec->dev, "%s: did not get Taiko MCLK\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ clk_users++;
+ if (clk_users != 1)
+ return ret;
+
+ ret = qpnp_clkdiv_enable(codec_clk);
+ if (ret) {
+ dev_err(codec->dev, "%s: Error enabling taiko MCLK\n",
+ __func__);
+ return -ENODEV;
+ }
+ taiko_mclk_enable(codec, 1, dapm);
+ } else {
+ if (clk_users > 0) {
+ clk_users--;
+ if (clk_users == 0) {
+ taiko_mclk_enable(codec, 0, dapm);
+ qpnp_clkdiv_disable(codec_clk);
+ }
+ } else {
+ pr_err("%s: Error releasing Tabla MCLK\n", __func__);
+ ret = -EINVAL;
+ }
+ }
+ mutex_unlock(&cdc_mclk_mutex);
+ return ret;
+}
+
+static int msm8974_mclk_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
+ pr_debug("%s: event = %d\n", __func__, event);
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ return msm8974_enable_codec_ext_clk(w->codec, 1, true);
+ case SND_SOC_DAPM_POST_PMD:
+ return msm8974_enable_codec_ext_clk(w->codec, 0, true);
+ }
+
return 0;
}
-static const struct snd_soc_dapm_widget msm_dapm_widgets[] = {
+static const struct snd_soc_dapm_widget msm8974_dapm_widgets[] = {
SND_SOC_DAPM_SUPPLY("MCLK", SND_SOC_NOPM, 0, 0,
- msm_mclk_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+ msm8974_mclk_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
SND_SOC_DAPM_SPK("Ext Spk Bottom Pos", msm_spkramp_event),
SND_SOC_DAPM_SPK("Ext Spk Bottom Neg", msm_spkramp_event),
@@ -328,7 +385,6 @@
SND_SOC_DAPM_MIC("Handset Mic", NULL),
SND_SOC_DAPM_MIC("Headset Mic", NULL),
- SND_SOC_DAPM_MIC("Digital Mic1", NULL),
SND_SOC_DAPM_MIC("ANCRight Headset Mic", NULL),
SND_SOC_DAPM_MIC("ANCLeft Headset Mic", NULL),
@@ -338,92 +394,6 @@
SND_SOC_DAPM_MIC("Digital Mic4", NULL),
SND_SOC_DAPM_MIC("Digital Mic5", NULL),
SND_SOC_DAPM_MIC("Digital Mic6", NULL),
-
-};
-
-static const struct snd_soc_dapm_route common_audio_map[] = {
-
- {"RX_BIAS", NULL, "MCLK"},
- {"LDO_H", NULL, "MCLK"},
-
- /* Speaker path */
- {"Ext Spk Bottom Pos", NULL, "LINEOUT1"},
- {"Ext Spk Bottom Neg", NULL, "LINEOUT3"},
-
- {"Ext Spk Top Pos", NULL, "LINEOUT2"},
- {"Ext Spk Top Neg", NULL, "LINEOUT4"},
-
- /* Microphone path */
- {"AMIC1", NULL, "MIC BIAS1 Internal1"},
- {"MIC BIAS1 Internal1", NULL, "Handset Mic"},
-
- {"AMIC2", NULL, "MIC BIAS2 External"},
- {"MIC BIAS2 External", NULL, "Headset Mic"},
-
- /**
- * AMIC3 and AMIC4 inputs are connected to ANC microphones
- * These mics are biased differently on CDP and FLUID
- * routing entries below are based on bias arrangement
- * on FLUID.
- */
- {"AMIC3", NULL, "MIC BIAS3 Internal1"},
- {"MIC BIAS3 Internal1", NULL, "ANCRight Headset Mic"},
-
- {"AMIC4", NULL, "MIC BIAS1 Internal2"},
- {"MIC BIAS1 Internal2", NULL, "ANCLeft Headset Mic"},
-
- {"HEADPHONE", NULL, "LDO_H"},
-
- /**
- * The digital Mic routes are setup considering
- * fluid as default device.
- */
-
- /**
- * Digital Mic1. Front Bottom left Digital Mic on Fluid and MTP.
- * Digital Mic GM5 on CDP mainboard.
- * Conncted to DMIC2 Input on Tabla codec.
- */
- {"DMIC2", NULL, "MIC BIAS1 External"},
- {"MIC BIAS1 External", NULL, "Digital Mic1"},
-
- /**
- * Digital Mic2. Front Bottom right Digital Mic on Fluid and MTP.
- * Digital Mic GM6 on CDP mainboard.
- * Conncted to DMIC1 Input on Tabla codec.
- */
- {"DMIC1", NULL, "MIC BIAS1 External"},
- {"MIC BIAS1 External", NULL, "Digital Mic2"},
-
- /**
- * Digital Mic3. Back Bottom Digital Mic on Fluid.
- * Digital Mic GM1 on CDP mainboard.
- * Conncted to DMIC4 Input on Tabla codec.
- */
- {"DMIC4", NULL, "MIC BIAS3 External"},
- {"MIC BIAS3 External", NULL, "Digital Mic3"},
-
- /**
- * Digital Mic4. Back top Digital Mic on Fluid.
- * Digital Mic GM2 on CDP mainboard.
- * Conncted to DMIC3 Input on Tabla codec.
- */
- {"DMIC3", NULL, "MIC BIAS3 External"},
- {"MIC BIAS3 External", NULL, "Digital Mic4"},
-
- /**
- * Digital Mic5. Front top Digital Mic on Fluid.
- * Digital Mic GM3 on CDP mainboard.
- * Conncted to DMIC5 Input on Tabla codec.
- */
- {"DMIC5", NULL, "MIC BIAS4 External"},
- {"MIC BIAS4 External", NULL, "Digital Mic5"},
-
- /* Tabla digital Mic6 - back bottom digital Mic on Liquid and
- * bottom mic on CDP. FLUID/MTP do not have dmic6 installed.
- */
- {"DMIC6", NULL, "MIC BIAS4 External"},
- {"MIC BIAS4 External", NULL, "Digital Mic6"},
};
static const char *const spk_function[] = {"Off", "On"};
@@ -671,11 +641,8 @@
if (err < 0)
return err;
- snd_soc_dapm_new_controls(dapm, msm_dapm_widgets,
- ARRAY_SIZE(msm_dapm_widgets));
-
- snd_soc_dapm_add_routes(dapm, common_audio_map,
- ARRAY_SIZE(common_audio_map));
+ snd_soc_dapm_new_controls(dapm, msm8974_dapm_widgets,
+ ARRAY_SIZE(msm8974_dapm_widgets));
snd_soc_dapm_enable_pin(dapm, "Ext Spk Bottom Pos");
snd_soc_dapm_enable_pin(dapm, "Ext Spk Bottom Neg");
@@ -790,7 +757,7 @@
};
/* Digital audio interface glue - connects codec <---> CPU */
-static struct snd_soc_dai_link msm_dai[] = {
+static struct snd_soc_dai_link msm8974_dai[] = {
/* FrontEnd DAI Links */
{
.name = "MSM8974 Media1",
@@ -954,58 +921,148 @@
},
};
-static struct snd_soc_card snd_soc_card_msm = {
+struct snd_soc_card snd_soc_card_msm8974 = {
.name = "msm8974-taiko-snd-card",
- .dai_link = msm_dai,
- .num_links = ARRAY_SIZE(msm_dai),
+ .dai_link = msm8974_dai,
+ .num_links = ARRAY_SIZE(msm8974_dai),
};
-static struct platform_device *msm_snd_device;
-
-static void msm_free_headset_mic_gpios(void)
+static int msm8974_prepare_codec_mclk(struct snd_soc_card *card)
{
- if (msm_headset_gpios_configured) {
- gpio_free(PM8921_GPIO_PM_TO_SYS(23));
- gpio_free(PM8921_GPIO_PM_TO_SYS(35));
- }
-}
-
-static int __init msm_audio_init(void)
-{
- int ret = 0;
-
- mutex_init(&cdc_mclk_mutex);
- if (!machine_is_msm8974_sim()) {
- pr_info("%s: Not msm8974 machine type\n", __func__);
- return -ENODEV;
- }
- msm_snd_device = platform_device_alloc("soc-audio", 0);
- if (!msm_snd_device) {
- pr_err("Platform device allocation failed\n");
- return -ENOMEM;
+ struct msm8974_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card);
+ int ret;
+ if (pdata->mclk_gpio) {
+ ret = gpio_request(pdata->mclk_gpio, "TAIKO_CODEC_PMIC_MCLK");
+ if (ret) {
+ dev_err(card->dev,
+ "%s: Failed to request taiko mclk gpio %d\n",
+ __func__, pdata->mclk_gpio);
+ return ret;
+ }
}
- platform_set_drvdata(msm_snd_device, &snd_soc_card_msm);
- ret = platform_device_add(msm_snd_device);
+ codec_clk = qpnp_clkdiv_get(card->dev, "taiko-mclk");
+ if (IS_ERR(codec_clk)) {
+ dev_err(card->dev,
+ "%s: Failed to request taiko mclk from pmic %ld\n",
+ __func__, PTR_ERR(codec_clk));
+ return -ENODEV ;
+ }
+
+ ret = qpnp_clkdiv_config(codec_clk, Q_CLKDIV_XO_DIV_2);
if (ret) {
- platform_device_put(msm_snd_device);
- return ret;
+ dev_err(card->dev, "%s: Failed to set taiko mclk to %u\n",
+ __func__, pdata->mclk_gpio);
+ return ret;
}
- return ret;
-
+ return 0;
}
-module_init(msm_audio_init);
-static void __exit msm_audio_exit(void)
+static __devinit int msm8974_asoc_machine_probe(struct platform_device *pdev)
{
- if (!machine_is_msm8974_sim()) {
- pr_err("%s: Not the right machine type\n", __func__);
- return ;
+ struct snd_soc_card *card = &snd_soc_card_msm8974;
+ struct msm8974_asoc_mach_data *pdata;
+ int ret;
+
+ if (!pdev->dev.of_node) {
+ dev_err(&pdev->dev, "No platform supplied from device tree\n");
+ return -EINVAL;
}
- msm_free_headset_mic_gpios();
- platform_device_unregister(msm_snd_device);
+
+ pdata = devm_kzalloc(&pdev->dev,
+ sizeof(struct msm8974_asoc_mach_data), GFP_KERNEL);
+ if (!pdata) {
+ dev_err(&pdev->dev, "Can't allocate msm8974_asoc_mach_data\n");
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ card->dev = &pdev->dev;
+ platform_set_drvdata(pdev, card);
+ snd_soc_card_set_drvdata(card, pdata);
+
+ ret = snd_soc_of_parse_card_name(card, "qcom,model");
+ if (ret)
+ goto err;
+
+ ret = snd_soc_of_parse_audio_routing(card,
+ "qcom,audio-routing");
+ if (ret)
+ goto err;
+
+ ret = of_property_read_u32(pdev->dev.of_node,
+ "qcom,taiko-mclk-clk-freq", &pdata->mclk_freq);
+ if (ret) {
+ dev_err(&pdev->dev, "Looking up %s property in node %s failed",
+ "qcom,taiko-mclk-clk-freq",
+ pdev->dev.of_node->full_name);
+ goto err;
+ }
+
+ if (pdata->mclk_freq != 9600000) {
+ dev_err(&pdev->dev, "unsupported taiko mclk freq %u\n",
+ pdata->mclk_freq);
+ ret = -EINVAL;
+ goto err;
+ }
+
+ pdata->mclk_gpio = of_get_named_gpio(pdev->dev.of_node,
+ "qcom,cdc-mclk-gpios", 0);
+ if (pdata->mclk_gpio < 0) {
+ dev_err(&pdev->dev,
+ "Looking up %s property in node %s failed %d\n",
+ "qcom, cdc-mclk-gpios", pdev->dev.of_node->full_name,
+ pdata->mclk_gpio);
+ ret = -ENODEV;
+ goto err;
+ }
+
+ ret = msm8974_prepare_codec_mclk(card);
+ if (ret)
+ goto err;
+
+ ret = snd_soc_register_card(card);
+ if (ret) {
+ dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
+ ret);
+ goto err;
+ }
+ mutex_init(&cdc_mclk_mutex);
+ return 0;
+err:
+ devm_kfree(&pdev->dev, pdata);
+ return ret;
}
-module_exit(msm_audio_exit);
+
+static int __devexit msm8974_asoc_machine_remove(struct platform_device *pdev)
+{
+ struct snd_soc_card *card = platform_get_drvdata(pdev);
+ struct msm8974_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card);
+
+ gpio_free(pdata->mclk_gpio);
+ snd_soc_unregister_card(card);
+
+ return 0;
+}
+
+static const struct of_device_id msm8974_asoc_machine_of_match[] = {
+ { .compatible = "qcom,msm8974-audio-taiko", },
+ {},
+};
+
+static struct platform_driver msm8974_asoc_machine_driver = {
+ .driver = {
+ .name = DRV_NAME,
+ .owner = THIS_MODULE,
+ .pm = &snd_soc_pm_ops,
+ .of_match_table = msm8974_asoc_machine_of_match,
+ },
+ .probe = msm8974_asoc_machine_probe,
+ .remove = __devexit_p(msm8974_asoc_machine_remove),
+};
+module_platform_driver(msm8974_asoc_machine_driver);
MODULE_DESCRIPTION("ALSA SoC msm");
MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:" DRV_NAME);
+MODULE_DEVICE_TABLE(of, msm8974_asoc_machine_of_match);
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index 65cee5d..f989b17 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -2046,6 +2046,8 @@
be_disconnect(fe, SNDRV_PCM_STREAM_PLAYBACK);
}
+ fe_path_put(&list);
+
capture:
/* skip if FE doesn't have capture capability */
if (!fe->cpu_dai->driver->capture.channels_min)