int (*suspend)(struct snd_soc_component *);
        int (*resume)(struct snd_soc_component *);
 
+       /* pcm creation and destruction */
+       int (*pcm_new)(struct snd_soc_pcm_runtime *);
+       void (*pcm_free)(struct snd_pcm *);
+
        /* DT */
        int (*of_xlate_dai_name)(struct snd_soc_component *component,
                                 struct of_phandle_args *args,
        void (*remove)(struct snd_soc_component *);
        int (*suspend)(struct snd_soc_component *);
        int (*resume)(struct snd_soc_component *);
+       int (*pcm_new)(struct snd_soc_pcm_runtime *);
+       void (*pcm_free)(struct snd_pcm *);
 
        /* machine specific init */
        int (*init)(struct snd_soc_component *component);
 
        component->remove = component->driver->remove;
        component->suspend = component->driver->suspend;
        component->resume = component->driver->resume;
+       component->pcm_new = component->driver->pcm_new;
+       component->pcm_free= component->driver->pcm_free;
 
        dapm = &component->dapm;
        dapm->dev = dev;
        platform->driver->remove(platform);
 }
 
+static int snd_soc_platform_drv_pcm_new(struct snd_soc_pcm_runtime *rtd)
+{
+       struct snd_soc_platform *platform = rtd->platform;
+
+       return platform->driver->pcm_new(rtd);
+}
+
+static void snd_soc_platform_drv_pcm_free(struct snd_pcm *pcm)
+{
+       struct snd_soc_pcm_runtime *rtd = pcm->private_data;
+       struct snd_soc_platform *platform = rtd->platform;
+
+       platform->driver->pcm_free(pcm);
+}
+
 /**
  * snd_soc_add_platform - Add a platform to the ASoC core
  * @dev: The parent device for the platform
                platform->component.probe = snd_soc_platform_drv_probe;
        if (platform_drv->remove)
                platform->component.remove = snd_soc_platform_drv_remove;
+       if (platform_drv->pcm_new)
+               platform->component.pcm_new = snd_soc_platform_drv_pcm_new;
+       if (platform_drv->pcm_free)
+               platform->component.pcm_free = snd_soc_platform_drv_pcm_free;
 
 #ifdef CONFIG_DEBUG_FS
        platform->component.debugfs_prefix = "platform";
 
        return ret;
 }
 
+static void soc_pcm_free(struct snd_pcm *pcm)
+{
+       struct snd_soc_pcm_runtime *rtd = pcm->private_data;
+       struct snd_soc_component *component;
+
+       list_for_each_entry(component, &rtd->card->component_dev_list,
+                           card_list) {
+               if (component->pcm_free)
+                       component->pcm_free(pcm);
+       }
+}
+
 /* create a new pcm */
 int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
 {
        struct snd_soc_platform *platform = rtd->platform;
        struct snd_soc_dai *codec_dai;
        struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+       struct snd_soc_component *component;
        struct snd_pcm *pcm;
        char new_name[64];
        int ret = 0, playback = 0, capture = 0;
        if (capture)
                snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &rtd->ops);
 
-       if (platform->driver->pcm_new) {
-               ret = platform->driver->pcm_new(rtd);
-               if (ret < 0) {
-                       dev_err(platform->dev,
-                               "ASoC: pcm constructor failed: %d\n",
-                               ret);
-                       return ret;
+       list_for_each_entry(component, &rtd->card->component_dev_list, card_list) {
+               if (component->pcm_new) {
+                       ret = component->pcm_new(rtd);
+                       if (ret < 0) {
+                               dev_err(component->dev,
+                                       "ASoC: pcm constructor failed: %d\n",
+                                       ret);
+                               return ret;
+                       }
                }
        }
-
-       pcm->private_free = platform->driver->pcm_free;
+       pcm->private_free = soc_pcm_free;
 out:
        dev_info(rtd->card->dev, "%s <-> %s mapping ok\n",
                 (rtd->num_codecs > 1) ? "multicodec" : rtd->codec_dai->name,