diff options
-rw-r--r-- | sound/soc/codecs/tlv320aic3x-i2c.c | 4 | ||||
-rw-r--r-- | sound/soc/codecs/tlv320aic3x-spi.c | 4 | ||||
-rw-r--r-- | sound/soc/codecs/tlv320aic3x.c | 3 | ||||
-rw-r--r-- | sound/soc/codecs/tlv320aic3x.h | 2 | ||||
-rw-r--r-- | sound/soc/sh/rcar/core.c | 1 | ||||
-rw-r--r-- | sound/soc/soc-core.c | 3 | ||||
-rw-r--r-- | sound/soc/soc-topology.c | 34 | ||||
-rw-r--r-- | sound/soc/soc-utils.c | 13 |
8 files changed, 52 insertions, 12 deletions
diff --git a/sound/soc/codecs/tlv320aic3x-i2c.c b/sound/soc/codecs/tlv320aic3x-i2c.c index cd0558ed4dd4..2f272bc3f5da 100644 --- a/sound/soc/codecs/tlv320aic3x-i2c.c +++ b/sound/soc/codecs/tlv320aic3x-i2c.c @@ -32,7 +32,9 @@ static int aic3x_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *i static int aic3x_i2c_remove(struct i2c_client *i2c) { - return aic3x_remove(&i2c->dev); + aic3x_remove(&i2c->dev); + + return 0; } static const struct i2c_device_id aic3x_i2c_id[] = { diff --git a/sound/soc/codecs/tlv320aic3x-spi.c b/sound/soc/codecs/tlv320aic3x-spi.c index 8c7b6bb9223f..494e84402232 100644 --- a/sound/soc/codecs/tlv320aic3x-spi.c +++ b/sound/soc/codecs/tlv320aic3x-spi.c @@ -37,7 +37,9 @@ static int aic3x_spi_probe(struct spi_device *spi) static int aic3x_spi_remove(struct spi_device *spi) { - return aic3x_remove(&spi->dev); + aic3x_remove(&spi->dev); + + return 0; } static const struct spi_device_id aic3x_spi_id[] = { diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index 7731593a5509..d53037b1509d 100644 --- a/sound/soc/codecs/tlv320aic3x.c +++ b/sound/soc/codecs/tlv320aic3x.c @@ -1870,7 +1870,7 @@ err: } EXPORT_SYMBOL(aic3x_probe); -int aic3x_remove(struct device *dev) +void aic3x_remove(struct device *dev) { struct aic3x_priv *aic3x = dev_get_drvdata(dev); @@ -1881,7 +1881,6 @@ int aic3x_remove(struct device *dev) gpio_set_value(aic3x->gpio_reset, 0); gpio_free(aic3x->gpio_reset); } - return 0; } EXPORT_SYMBOL(aic3x_remove); diff --git a/sound/soc/codecs/tlv320aic3x.h b/sound/soc/codecs/tlv320aic3x.h index 7e0063913017..14298f9e6d9b 100644 --- a/sound/soc/codecs/tlv320aic3x.h +++ b/sound/soc/codecs/tlv320aic3x.h @@ -14,7 +14,7 @@ struct regmap_config; extern const struct regmap_config aic3x_regmap; int aic3x_probe(struct device *dev, struct regmap *regmap, kernel_ulong_t driver_data); -int aic3x_remove(struct device *dev); +void aic3x_remove(struct device *dev); #define AIC3X_MODEL_3X 0 #define AIC3X_MODEL_33 1 diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index 978bd0406729..6a8fe0da7670 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c @@ -1225,6 +1225,7 @@ int rsnd_node_count(struct rsnd_priv *priv, struct device_node *node, char *name if (i < 0) { dev_err(dev, "strange node numbering (%s)", of_node_full_name(node)); + of_node_put(np); return 0; } i++; diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 94f1548b8a32..dcf6be4c4aaa 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1342,9 +1342,6 @@ static void soc_remove_component(struct snd_soc_component *component, if (probed) snd_soc_component_remove(component); - /* For framework level robustness */ - snd_soc_component_set_jack(component, NULL, NULL); - list_del_init(&component->card_list); snd_soc_dapm_free(snd_soc_component_get_dapm(component)); soc_cleanup_component_debugfs(component); diff --git a/sound/soc/soc-topology.c b/sound/soc/soc-topology.c index 7a4559ddf903..557e22c5254c 100644 --- a/sound/soc/soc-topology.c +++ b/sound/soc/soc-topology.c @@ -351,7 +351,7 @@ static int soc_tplg_add_kcontrol(struct soc_tplg *tplg, struct snd_soc_component *comp = tplg->comp; return soc_tplg_add_dcontrol(comp->card->snd_card, - comp->dev, k, comp->name_prefix, comp, kcontrol); + tplg->dev, k, comp->name_prefix, comp, kcontrol); } /* remove a mixer kcontrol */ @@ -1591,11 +1591,28 @@ static int soc_tplg_dapm_widget_elems_load(struct soc_tplg *tplg, struct snd_soc_tplg_dapm_widget *widget = (struct snd_soc_tplg_dapm_widget *) tplg->pos; int ret; + /* + * check if widget itself fits within topology file + * use sizeof instead of widget->size, as we can't be sure + * it is set properly yet (file may end before it is present) + */ + if (soc_tplg_get_offset(tplg) + sizeof(*widget) >= tplg->fw->size) { + dev_err(tplg->dev, "ASoC: invalid widget data size\n"); + return -EINVAL; + } + + /* check if widget has proper size */ if (le32_to_cpu(widget->size) != sizeof(*widget)) { dev_err(tplg->dev, "ASoC: invalid widget size\n"); return -EINVAL; } + /* check if widget private data fits within topology file */ + if (soc_tplg_get_offset(tplg) + le32_to_cpu(widget->priv.size) >= tplg->fw->size) { + dev_err(tplg->dev, "ASoC: invalid widget private data size\n"); + return -EINVAL; + } + ret = soc_tplg_dapm_widget_create(tplg, widget); if (ret < 0) { dev_err(tplg->dev, "ASoC: failed to load widget %s\n", @@ -2438,6 +2455,7 @@ static int soc_tplg_manifest_load(struct soc_tplg *tplg, _manifest = manifest; } else { abi_match = false; + ret = manifest_new_ver(tplg, manifest, &_manifest); if (ret < 0) return ret; @@ -2468,6 +2486,14 @@ static int soc_valid_header(struct soc_tplg *tplg, return -EINVAL; } + if (soc_tplg_get_hdr_offset(tplg) + hdr->payload_size >= tplg->fw->size) { + dev_err(tplg->dev, + "ASoC: invalid header of type %d at offset %ld payload_size %d\n", + le32_to_cpu(hdr->type), soc_tplg_get_hdr_offset(tplg), + hdr->payload_size); + return -EINVAL; + } + /* big endian firmware objects not supported atm */ if (le32_to_cpu(hdr->magic) == SOC_TPLG_MAGIC_BIG_ENDIAN) { dev_err(tplg->dev, @@ -2642,17 +2668,17 @@ int snd_soc_tplg_component_load(struct snd_soc_component *comp, /* * check if we have sane parameters: * comp - needs to exist to keep and reference data while parsing - * comp->dev - used for resource management and prints * comp->card - used for setting card related parameters + * comp->card->dev - used for resource management and prints * fw - we need it, as it is the very thing we parse */ - if (!comp || !comp->dev || !comp->card || !fw) + if (!comp || !comp->card || !comp->card->dev || !fw) return -EINVAL; /* setup parsing context */ memset(&tplg, 0, sizeof(tplg)); tplg.fw = fw; - tplg.dev = comp->dev; + tplg.dev = comp->card->dev; tplg.comp = comp; if (ops) { tplg.ops = ops; diff --git a/sound/soc/soc-utils.c b/sound/soc/soc-utils.c index 299b5d6ebfd1..a4efe7e52a8b 100644 --- a/sound/soc/soc-utils.c +++ b/sound/soc/soc-utils.c @@ -63,10 +63,23 @@ static const struct snd_pcm_hardware dummy_dma_hardware = { .periods_max = 128, }; + +static const struct snd_soc_component_driver dummy_platform; + static int dummy_dma_open(struct snd_soc_component *component, struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + int i; + + /* + * If there are other components associated with rtd, we shouldn't + * override their hwparams + */ + for_each_rtd_components(rtd, i, component) { + if (component->driver == &dummy_platform) + return 0; + } /* BE's dont need dummy params */ if (!rtd->dai_link->no_pcm) |