diff options
author | Shengjiu Wang <shengjiu.wang@nxp.com> | 2020-05-22 12:02:12 +0800 |
---|---|---|
committer | Shengjiu Wang <shengjiu.wang@nxp.com> | 2020-05-22 15:03:29 +0800 |
commit | 466976dd766969d62a0f95c0ccb6f68caa87c587 (patch) | |
tree | f819c4bc74156a473f62247c8bec833ceb253b38 | |
parent | c18ff376db6529818037a66b2cafaa3f512577d8 (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.c | 21 |
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; } |