diff options
| author | Michael Trimarchi <michael@amarulasolutions.com> | 2014-09-18 14:38:09 -0400 |
|---|---|---|
| committer | Mark Brown <broonie@kernel.org> | 2014-09-22 21:58:48 -0400 |
| commit | 85151461f114f2fca386bb8ae6de185461d35d87 (patch) | |
| tree | 27dff020ff42f7eb5f063a476a6106a033d57b25 | |
| parent | 7d1311b93e58ed55f3a31cc8f94c4b8fe988a2b9 (diff) | |
ASoC: fsl_ssi: fix kernel panic in probe function
code can raise a panic when the ssi_private->pdev is null
[...]
/*
* If codec-handle property is missing from SSI node, we assume
* that the machine driver uses new binding which does not require
* SSI driver to trigger machine driver's probe.
*/
if (!of_get_property(np, "codec-handle", NULL))
goto done;
[...]
ssi_private->pdev =
platform_device_register_data(&pdev->dev, name, 0, NULL, 0);
[...]
done:
if (ssi_private->dai_fmt)
_fsl_ssi_set_dai_fmt(ssi_private, ssi_private->dai_fmt);
Proposal was to not use ssi_private->pdev->dev here but adding a new parameter
of *dev pointer to this _set_dai_fmt() -- passing pdev->dev in probe() and
cpu_dai->dev in fsl_ssi_set_dai_fmt().
Signed-off-by: Michael Trimarchi <michael@amarulasolutions.com>
Reported-by: Jean-Michel Hautbois <jean-michel.hautbois@vodalys.com>
Acked-by: Nicolin Chen <nicoleotsuka@gmail.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
| -rw-r--r-- | sound/soc/fsl/fsl_ssi.c | 12 |
1 files changed, 7 insertions, 5 deletions
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index 87eb5776a39b..de6ab06f58a5 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c | |||
| @@ -748,8 +748,9 @@ static int fsl_ssi_hw_free(struct snd_pcm_substream *substream, | |||
| 748 | return 0; | 748 | return 0; |
| 749 | } | 749 | } |
| 750 | 750 | ||
| 751 | static int _fsl_ssi_set_dai_fmt(struct fsl_ssi_private *ssi_private, | 751 | static int _fsl_ssi_set_dai_fmt(struct device *dev, |
| 752 | unsigned int fmt) | 752 | struct fsl_ssi_private *ssi_private, |
| 753 | unsigned int fmt) | ||
| 753 | { | 754 | { |
| 754 | struct regmap *regs = ssi_private->regs; | 755 | struct regmap *regs = ssi_private->regs; |
| 755 | u32 strcr = 0, stcr, srcr, scr, mask; | 756 | u32 strcr = 0, stcr, srcr, scr, mask; |
| @@ -758,7 +759,7 @@ static int _fsl_ssi_set_dai_fmt(struct fsl_ssi_private *ssi_private, | |||
| 758 | ssi_private->dai_fmt = fmt; | 759 | ssi_private->dai_fmt = fmt; |
| 759 | 760 | ||
| 760 | if (fsl_ssi_is_i2s_master(ssi_private) && IS_ERR(ssi_private->baudclk)) { | 761 | if (fsl_ssi_is_i2s_master(ssi_private) && IS_ERR(ssi_private->baudclk)) { |
| 761 | dev_err(&ssi_private->pdev->dev, "baudclk is missing which is necessary for master mode\n"); | 762 | dev_err(dev, "baudclk is missing which is necessary for master mode\n"); |
| 762 | return -EINVAL; | 763 | return -EINVAL; |
| 763 | } | 764 | } |
| 764 | 765 | ||
| @@ -913,7 +914,7 @@ static int fsl_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) | |||
| 913 | { | 914 | { |
| 914 | struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(cpu_dai); | 915 | struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(cpu_dai); |
| 915 | 916 | ||
| 916 | return _fsl_ssi_set_dai_fmt(ssi_private, fmt); | 917 | return _fsl_ssi_set_dai_fmt(cpu_dai->dev, ssi_private, fmt); |
| 917 | } | 918 | } |
| 918 | 919 | ||
| 919 | /** | 920 | /** |
| @@ -1387,7 +1388,8 @@ static int fsl_ssi_probe(struct platform_device *pdev) | |||
| 1387 | 1388 | ||
| 1388 | done: | 1389 | done: |
| 1389 | if (ssi_private->dai_fmt) | 1390 | if (ssi_private->dai_fmt) |
| 1390 | _fsl_ssi_set_dai_fmt(ssi_private, ssi_private->dai_fmt); | 1391 | _fsl_ssi_set_dai_fmt(&pdev->dev, ssi_private, |
| 1392 | ssi_private->dai_fmt); | ||
| 1391 | 1393 | ||
| 1392 | return 0; | 1394 | return 0; |
| 1393 | 1395 | ||
