{
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
u32 size;
+ u32 abi_version;
size = le32_to_cpu(man->priv.size);
return 0;
}
- if (size == SOF_TPLG_ABI_SIZE) {
- dev_info(sdev->dev,
- "Topology: ABI %d:%d:%d Kernel ABI %d:%d:%d\n",
- man->priv.data[0], man->priv.data[1],
- man->priv.data[2], SOF_ABI_MAJOR, SOF_ABI_MINOR,
- SOF_ABI_PATCH);
- if (SOF_ABI_VER(man->priv.data[0], man->priv.data[1],
- man->priv.data[2]) <= SOF_ABI_VERSION)
- return 0;
+ if (size != SOF_TPLG_ABI_SIZE) {
+ dev_err(sdev->dev, "error: invalid topology ABI size\n");
+ return -EINVAL;
}
- dev_err(sdev->dev,
- "error: Incompatible ABI version %d:%d:%d\n",
- man->priv.data[0], man->priv.data[1], man->priv.data[2]);
- return -EINVAL;
+
+ dev_info(sdev->dev,
+ "Topology: ABI %d:%d:%d Kernel ABI %d:%d:%d\n",
+ man->priv.data[0], man->priv.data[1],
+ man->priv.data[2], SOF_ABI_MAJOR, SOF_ABI_MINOR,
+ SOF_ABI_PATCH);
+
+ abi_version = SOF_ABI_VER(man->priv.data[0],
+ man->priv.data[1],
+ man->priv.data[2]);
+
+ if (SOF_ABI_VERSION_INCOMPATIBLE(SOF_ABI_VERSION, abi_version)) {
+ dev_err(sdev->dev, "error: incompatible topology ABI version\n");
+ return -EINVAL;
+ }
+
+ if (abi_version > SOF_ABI_VERSION) {
+ if (!IS_ENABLED(CONFIG_SND_SOC_SOF_STRICT_ABI_CHECKS)) {
+ dev_warn(sdev->dev, "warn: topology ABI is more recent than kernel\n");
+ } else {
+ dev_err(sdev->dev, "error: topology ABI is more recent than kernel\n");
+ return -EINVAL;
+ }
+ }
+
+ return 0;
}
/* vendor specific kcontrol handlers available for binding */