diff options
author | Enric Balletbo i Serra <enric.balletbo@collabora.com> | 2016-05-09 12:46:31 +0200 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2016-05-30 16:19:41 +0100 |
commit | 5f22449344d9db35bcaf19c8e1bb4062188aeb09 (patch) | |
tree | 87623603e93df5a9932e0f63597a48dd60edbfda /sound/soc/rockchip | |
parent | 170abcaae8bec0a53f2f7708a83119ec42fb09e2 (diff) | |
download | linux-5f22449344d9db35bcaf19c8e1bb4062188aeb09.tar.bz2 |
ASoC: rockchip-max98090: Fix NULL pointer dereference while accessing to jack.
Commit f2ed6b07645e ("ASoC: Make aux_dev more like a generic
component") caused a regression on this driver, since now a
kernel oops is seen when rockchip-mac98090 driver is loaded.
That commit changed the probing of aux_devs before checking
new DAI links, so for this driver rk_98090_headset_init is
called before rk_init and then the kernel oops due a NULL
pointer dereference inside rk_98090_headset_init function
since there is a call that tries to access the jack pointer
which has not been allocated yet.
This is the call chain that causes the crash:
rk_98090_headset_init
-> ts3a227e_enable_jack_detect
-> snd_jack_set_key
rk_init
-> snd_soc_card_jack_new
This patch moves the new jack object creation from rk_init
to rk_98090_headset_init function making sure the jack is
created before is accessed.
Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound/soc/rockchip')
-rw-r--r-- | sound/soc/rockchip/rockchip_max98090.c | 50 |
1 files changed, 27 insertions, 23 deletions
diff --git a/sound/soc/rockchip/rockchip_max98090.c b/sound/soc/rockchip/rockchip_max98090.c index 543610282cdb..abb64a553967 100644 --- a/sound/soc/rockchip/rockchip_max98090.c +++ b/sound/soc/rockchip/rockchip_max98090.c @@ -114,43 +114,27 @@ static int rk_aif1_hw_params(struct snd_pcm_substream *substream, return ret; } -static int rk_init(struct snd_soc_pcm_runtime *runtime) -{ - /* Enable Headset and 4 Buttons Jack detection */ - return snd_soc_card_jack_new(runtime->card, "Headset Jack", - SND_JACK_HEADSET | - SND_JACK_BTN_0 | SND_JACK_BTN_1 | - SND_JACK_BTN_2 | SND_JACK_BTN_3, - &headset_jack, - headset_jack_pins, - ARRAY_SIZE(headset_jack_pins)); -} - -static int rk_98090_headset_init(struct snd_soc_component *component) -{ - return ts3a227e_enable_jack_detect(component, &headset_jack); -} - static struct snd_soc_ops rk_aif1_ops = { .hw_params = rk_aif1_hw_params, }; -static struct snd_soc_aux_dev rk_98090_headset_dev = { - .name = "Headset Chip", - .init = rk_98090_headset_init, -}; - static struct snd_soc_dai_link rk_dailink = { .name = "max98090", .stream_name = "Audio", .codec_dai_name = "HiFi", - .init = rk_init, .ops = &rk_aif1_ops, /* set max98090 as slave */ .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS, }; +static int rk_98090_headset_init(struct snd_soc_component *component); + +static struct snd_soc_aux_dev rk_98090_headset_dev = { + .name = "Headset Chip", + .init = rk_98090_headset_init, +}; + static struct snd_soc_card snd_soc_card_rk = { .name = "ROCKCHIP-I2S", .owner = THIS_MODULE, @@ -166,6 +150,26 @@ static struct snd_soc_card snd_soc_card_rk = { .num_controls = ARRAY_SIZE(rk_mc_controls), }; +static int rk_98090_headset_init(struct snd_soc_component *component) +{ + int ret; + + /* Enable Headset and 4 Buttons Jack detection */ + ret = snd_soc_card_jack_new(&snd_soc_card_rk, "Headset Jack", + SND_JACK_HEADSET | + SND_JACK_BTN_0 | SND_JACK_BTN_1 | + SND_JACK_BTN_2 | SND_JACK_BTN_3, + &headset_jack, + headset_jack_pins, + ARRAY_SIZE(headset_jack_pins)); + if (ret) + return ret; + + ret = ts3a227e_enable_jack_detect(component, &headset_jack); + + return ret; +} + static int snd_rk_mc_probe(struct platform_device *pdev) { int ret = 0; |