summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShengjiu Wang <shengjiu.wang@nxp.com>2020-05-22 12:02:12 +0800
committerShengjiu Wang <shengjiu.wang@nxp.com>2020-05-22 15:03:29 +0800
commit466976dd766969d62a0f95c0ccb6f68caa87c587 (patch)
treef819c4bc74156a473f62247c8bec833ceb253b38
parentc18ff376db6529818037a66b2cafaa3f512577d8 (diff)
MLK-24132: ASoC: fsl_micfil: Fix kernel panic when hwvad is disabled
The reason is that we access the register when power is disabled reproduce command: echo 8 > /sys/devices/platform/soc@0/30c00000.bus/30c00000.spba-bus/30ca0000.micfil/hwvad/enable [ 332.838518] SError Interrupt on CPU2, code 0xbf000002 -- SError [ 332.838521] CPU: 2 PID: 1383 Comm: sh Tainted: G O 5.4.24-2.1.0+g2ad925d15481 #1 [ 332.838523] Hardware name: NXP i.MX8MPlus EVK board (DT) [ 332.838525] pstate: 20000085 (nzCv daIf -PAN -UAO) [ 332.838526] pc : regcache_sync_block+0x7c/0x258 [ 332.838528] lr : regcache_sync_block+0xf0/0x258 [ 332.838531] sp : ffff800012bf3be0 [ 332.838532] x29: ffff800012bf3be0 x28: 0000000000000000 [ 332.838535] x27: 0000000000000000 x26: 0000000000000001 [ 332.838541] x25: ffff00017753ed00 x24: 0000000000000000 [ 332.838546] x23: ffff00017706d400 x22: 000000000000002b [ 332.838550] x21: ffff00017753f100 x20: ffff000177538c00 [ 332.838554] x19: 0000000000000001 x18: 0000000000000000 [ 332.838559] x17: 0000000000000000 x16: 0000000000000000 [ 332.838564] x15: 0000000000000000 x14: 0000000000000000 [ 332.838567] x13: 0000000000000000 x12: 0000000000000000 [ 332.838572] x11: ffff800012bf3d50 x10: ffff000173c0e900 [ 332.838577] x9 : ffff00017706d870 x8 : 0000000000000000 [ 332.838582] x7 : 00000000000000a8 x6 : 0000000000000000 [ 332.838587] x5 : 0000000000000000 x4 : ffff800010769d88 [ 332.838592] x3 : ffff80001076d278 x2 : 0000000008000000 [ 332.838597] x1 : ffff800023c10000 x0 : 0000000000000000 [ 332.838603] Kernel panic - not syncing: Asynchronous SError Interrupt [ 332.838605] CPU: 2 PID: 1383 Comm: sh Tainted: G O 5.4.24-2.1.0+g2ad925d15481 #1 [ 332.838606] Hardware name: NXP i.MX8MPlus EVK board (DT) [ 332.838608] Call trace: [ 332.838609] dump_backtrace+0x0/0x140 [ 332.838612] show_stack+0x14/0x20 [ 332.838613] dump_stack+0xb4/0xf8 [ 332.838617] panic+0x158/0x324 [ 332.838618] nmi_panic+0x84/0x88 [ 332.838621] arm64_serror_panic+0x74/0x80 [ 332.838622] do_serror+0x80/0x138 [ 332.838623] el1_error+0x84/0xf8 [ 332.838627] regcache_sync_block+0x7c/0x258 [ 332.838628] regcache_rbtree_sync+0x60/0xb0 [ 332.838629] regcache_sync+0xac/0x140 [ 332.838633] disable_hwvad+0x3c/0x1f0 [ 332.838634] micfil_hwvad_handler+0x78/0x170 [ 332.838635] kobj_attr_store+0x14/0x28 [ 332.838637] sysfs_kf_write+0x40/0x50 [ 332.838640] kernfs_fop_write+0xf8/0x210 [ 332.838641] __vfs_write+0x18/0x40 [ 332.838642] vfs_write+0xdc/0x1c8 [ 332.838646] ksys_write+0x68/0xf0 [ 332.838647] __arm64_sys_write+0x18/0x20 [ 332.838648] el0_svc_common.constprop.0+0x68/0x160 [ 332.838651] el0_svc_handler+0x20/0x80 [ 332.838653] el0_svc+0x8/0xc [ 332.838972] SMP: stopping secondary CPUs [ 332.838974] Kernel Offset: disabled [ 332.838975] CPU features: 0x0002,2000200c [ 332.838976] Memory Limit: none Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com> Reviewed-by: Viorel Suman <viorel.suman@nxp.com>
-rw-r--r--sound/soc/fsl/fsl_micfil.c21
1 files changed, 10 insertions, 11 deletions
diff --git a/sound/soc/fsl/fsl_micfil.c b/sound/soc/fsl/fsl_micfil.c
index 97187737d1a3..a04376768832 100644
--- a/sound/soc/fsl/fsl_micfil.c
+++ b/sound/soc/fsl/fsl_micfil.c
@@ -2066,14 +2066,6 @@ static int disable_hwvad(struct device *dev, bool sync)
int ret = 0;
u32 state;
- /* This is required because if an arecord was done,
- * suspend function will mark regmap as cache only
- * and reads/writes in volatile regs will fail
- */
- regcache_cache_only(micfil->regmap, false);
- regcache_mark_dirty(micfil->regmap);
- regcache_sync(micfil->regmap);
-
/* disable is called with sync = false only from
* system suspend and in this case, you should not
* change the hwvad_state so we know at system_resume
@@ -2087,6 +2079,14 @@ static int disable_hwvad(struct device *dev, bool sync)
state = atomic_read(&micfil->hwvad_state);
if (state == MICFIL_HWVAD_ON) {
+ /* This is required because if an arecord was done,
+ * suspend function will mark regmap as cache only
+ * and reads/writes in volatile regs will fail
+ */
+ regcache_cache_only(micfil->regmap, false);
+ regcache_mark_dirty(micfil->regmap);
+ regcache_sync(micfil->regmap);
+
/* Voice Activity Detector Reset */
ret |= regmap_update_bits(micfil->regmap,
REG_MICFIL_VAD0_CTRL1,
@@ -2135,14 +2135,13 @@ static int disable_hwvad(struct device *dev, bool sync)
0);
}
+ if (sync)
+ pm_runtime_put_sync(dev);
} else {
ret = -EPERM;
dev_err(dev, "HWVAD is not enabled %d\n", ret);
}
- if (sync)
- pm_runtime_put_sync(dev);
-
return ret;
}