summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sound/soc/codecs/tlv320aic3x-i2c.c4
-rw-r--r--sound/soc/codecs/tlv320aic3x-spi.c4
-rw-r--r--sound/soc/codecs/tlv320aic3x.c3
-rw-r--r--sound/soc/codecs/tlv320aic3x.h2
-rw-r--r--sound/soc/sh/rcar/core.c1
-rw-r--r--sound/soc/soc-core.c3
-rw-r--r--sound/soc/soc-topology.c34
-rw-r--r--sound/soc/soc-utils.c13
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)