Merge remote-tracking branch 'asoc/topic/rcar' into asoc-next
[sfrench/cifs-2.6.git] / sound / soc / soc-core.c
index 9ba1837810171f14782b4da155b6c3b071e6ffc0..921622a019448394687655034f52befb4abfd6ec 100644 (file)
@@ -69,6 +69,20 @@ static int pmdown_time = 5000;
 module_param(pmdown_time, int, 0);
 MODULE_PARM_DESC(pmdown_time, "DAPM stream powerdown time (msecs)");
 
+/* If a DMI filed contain strings in this blacklist (e.g.
+ * "Type2 - Board Manufacturer" or  "Type1 - TBD by OEM"), it will be taken
+ * as invalid and dropped when setting the card long name from DMI info.
+ */
+static const char * const dmi_blacklist[] = {
+       "To be filled by OEM",
+       "TBD by OEM",
+       "Default String",
+       "Board Manufacturer",
+       "Board Vendor Name",
+       "Board Product Name",
+       NULL,   /* terminator */
+};
+
 /* returns the minimum number of bytes needed to represent
  * a particular given value */
 static int min_bytes_needed(unsigned long val)
@@ -1934,6 +1948,22 @@ static void cleanup_dmi_name(char *name)
        name[j] = '\0';
 }
 
+/* Check if a DMI field is valid, i.e. not containing any string
+ * in the black list.
+ */
+static int is_dmi_valid(const char *field)
+{
+       int i = 0;
+
+       while (dmi_blacklist[i]) {
+               if (strstr(field, dmi_blacklist[i]))
+                       return 0;
+               i++;
+       }
+
+       return 1;
+}
+
 /**
  * snd_soc_set_dmi_name() - Register DMI names to card
  * @card: The card to register DMI names
@@ -1976,17 +2006,18 @@ int snd_soc_set_dmi_name(struct snd_soc_card *card, const char *flavour)
 
        /* make up dmi long name as: vendor.product.version.board */
        vendor = dmi_get_system_info(DMI_BOARD_VENDOR);
-       if (!vendor) {
+       if (!vendor || !is_dmi_valid(vendor)) {
                dev_warn(card->dev, "ASoC: no DMI vendor name!\n");
                return 0;
        }
 
+
        snprintf(card->dmi_longname, sizeof(card->snd_card->longname),
                         "%s", vendor);
        cleanup_dmi_name(card->dmi_longname);
 
        product = dmi_get_system_info(DMI_PRODUCT_NAME);
-       if (product) {
+       if (product && is_dmi_valid(product)) {
                len = strlen(card->dmi_longname);
                snprintf(card->dmi_longname + len,
                         longname_buf_size - len,
@@ -2000,7 +2031,7 @@ int snd_soc_set_dmi_name(struct snd_soc_card *card, const char *flavour)
                 * name in the product version field
                 */
                product_version = dmi_get_system_info(DMI_PRODUCT_VERSION);
-               if (product_version) {
+               if (product_version && is_dmi_valid(product_version)) {
                        len = strlen(card->dmi_longname);
                        snprintf(card->dmi_longname + len,
                                 longname_buf_size - len,
@@ -2013,7 +2044,7 @@ int snd_soc_set_dmi_name(struct snd_soc_card *card, const char *flavour)
        }
 
        board = dmi_get_system_info(DMI_BOARD_NAME);
-       if (board) {
+       if (board && is_dmi_valid(board)) {
                len = strlen(card->dmi_longname);
                snprintf(card->dmi_longname + len,
                         longname_buf_size - len,
@@ -2287,6 +2318,9 @@ static int soc_cleanup_card_resources(struct snd_soc_card *card)
        list_for_each_entry(rtd, &card->rtd_list, list)
                flush_delayed_work(&rtd->delayed_work);
 
+       /* free the ALSA card at first; this syncs with pending operations */
+       snd_card_free(card->snd_card);
+
        /* remove and free each DAI */
        soc_remove_dai_links(card);
        soc_remove_pcm_runtimes(card);
@@ -2301,9 +2335,7 @@ static int soc_cleanup_card_resources(struct snd_soc_card *card)
        if (card->remove)
                card->remove(card);
 
-       snd_card_free(card->snd_card);
        return 0;
-
 }
 
 /* removes a socdev */