Merge remote-tracking branch 'asoc/topic/intel' into asoc-next
[linux-block.git] / sound / soc / intel / skylake / skl-nhlt.c
index bde7f40f29f5c61da3c2794d10a5ace90f69a03a..3b1d2b828c1b6425c06614cce20293265c3c35ed 100644 (file)
@@ -21,6 +21,8 @@
 #include "skl.h"
 #include "skl-i2s.h"
 
+#define NHLT_ACPI_HEADER_SIG   "NHLT"
+
 /* Unique identification for getting NHLT blobs */
 static guid_t osc_guid =
        GUID_INIT(0xA69F886E, 0x6CEB, 0x4594,
@@ -42,10 +44,18 @@ struct nhlt_acpi_table *skl_nhlt_init(struct device *dev)
        obj = acpi_evaluate_dsm(handle, &osc_guid, 1, 1, NULL);
        if (obj && obj->type == ACPI_TYPE_BUFFER) {
                nhlt_ptr = (struct nhlt_resource_desc  *)obj->buffer.pointer;
-               nhlt_table = (struct nhlt_acpi_table *)
+               if (nhlt_ptr->length)
+                       nhlt_table = (struct nhlt_acpi_table *)
                                memremap(nhlt_ptr->min_addr, nhlt_ptr->length,
                                MEMREMAP_WB);
                ACPI_FREE(obj);
+               if (nhlt_table && (strncmp(nhlt_table->header.signature,
+                                       NHLT_ACPI_HEADER_SIG,
+                                       strlen(NHLT_ACPI_HEADER_SIG)) != 0)) {
+                       memunmap(nhlt_table);
+                       dev_err(dev, "NHLT ACPI header signature incorrect\n");
+                       return NULL;
+               }
                return nhlt_table;
        }
 
@@ -111,11 +121,16 @@ static bool skl_check_ep_match(struct device *dev, struct nhlt_endpoint *epnt,
 
        if ((epnt->virtual_bus_id == instance_id) &&
                        (epnt->linktype == link_type) &&
-                       (epnt->direction == dirn) &&
-                       (epnt->device_type == dev_type))
-               return true;
-       else
-               return false;
+                       (epnt->direction == dirn)) {
+               /* do not check dev_type for DMIC link type */
+               if (epnt->linktype == NHLT_LINK_DMIC)
+                       return true;
+
+               if (epnt->device_type == dev_type)
+                       return true;
+       }
+
+       return false;
 }
 
 struct nhlt_specific_cfg