diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 838d64e..c9c541b 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -1806,21 +1806,7 @@ static int azx_free(struct azx *chip)
 	if (chip->remap_addr)
 		iounmap(chip->remap_addr);
 
-	if (chip->azx_dev) {
-		for (i = 0; i < chip->num_streams; i++)
-			if (chip->azx_dev[i].bdl.area) {
-				mark_pages_wc(chip, &chip->azx_dev[i].bdl, false);
-				snd_dma_free_pages(&chip->azx_dev[i].bdl);
-			}
-	}
-	if (chip->rb.area) {
-		mark_pages_wc(chip, &chip->rb, false);
-		snd_dma_free_pages(&chip->rb);
-	}
-	if (chip->posbuf.area) {
-		mark_pages_wc(chip, &chip->posbuf, false);
-		snd_dma_free_pages(&chip->posbuf);
-	}
+	azx_free_stream_pages(chip);
 	if (chip->region_requested)
 		pci_release_regions(chip->pci);
 	pci_disable_device(chip->pci);
@@ -2156,7 +2142,7 @@ static int azx_first_init(struct azx *chip)
 	int dev = chip->dev_index;
 	struct pci_dev *pci = chip->pci;
 	struct snd_card *card = chip->card;
-	int i, err;
+	int err;
 	unsigned short gcap;
 
 #if BITS_PER_LONG != 64
@@ -2268,27 +2254,9 @@ static int azx_first_init(struct azx *chip)
 		return -ENOMEM;
 	}
 
-	for (i = 0; i < chip->num_streams; i++) {
-		dsp_lock_init(&chip->azx_dev[i]);
-		/* allocate memory for the BDL for each stream */
-		err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV,
-					  chip->card->dev,
-					  BDL_SIZE, &chip->azx_dev[i].bdl);
-		if (err < 0) {
-			dev_err(card->dev, "cannot allocate BDL\n");
-			return -ENOMEM;
-		}
-		mark_pages_wc(chip, &chip->azx_dev[i].bdl, true);
-	}
-	/* allocate memory for the position buffer */
-	err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV,
-				  chip->card->dev,
-				  chip->num_streams * 8, &chip->posbuf);
-	if (err < 0) {
-		dev_err(card->dev, "cannot allocate posbuf\n");
-		return -ENOMEM;
-	}
-	mark_pages_wc(chip, &chip->posbuf, true);
+	err = azx_alloc_stream_pages(chip);
+	if (err < 0)
+		return err;
 	/* allocate CORB/RIRB */
 	err = azx_alloc_cmd_io(chip);
 	if (err < 0)
diff --git a/sound/pci/hda/hda_shared.c b/sound/pci/hda/hda_shared.c
index 55b0538..e921154 100644
--- a/sound/pci/hda/hda_shared.c
+++ b/sound/pci/hda/hda_shared.c
@@ -1101,5 +1101,57 @@ int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev)
 	return 1; /* OK, it's fine */
 }
 
+int azx_alloc_stream_pages(struct azx *chip)
+{
+	int i, err;
+	struct snd_card *card = chip->card;
+
+	for (i = 0; i < chip->num_streams; i++) {
+		dsp_lock_init(&chip->azx_dev[i]);
+		/* allocate memory for the BDL for each stream */
+		err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV,
+					  chip->card->dev,
+					  BDL_SIZE, &chip->azx_dev[i].bdl);
+		if (err < 0) {
+			dev_err(card->dev, "cannot allocate BDL\n");
+			return -ENOMEM;
+		}
+		mark_pages_wc(chip, &chip->azx_dev[i].bdl, true);
+	}
+	/* allocate memory for the position buffer */
+	err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV,
+				  chip->card->dev,
+				  chip->num_streams * 8, &chip->posbuf);
+	if (err < 0) {
+		dev_err(card->dev, "cannot allocate posbuf\n");
+		return -ENOMEM;
+	}
+	mark_pages_wc(chip, &chip->posbuf, true);
+	return 0;
+}
+EXPORT_SYMBOL_GPL(azx_alloc_stream_pages);
+
+void azx_free_stream_pages(struct azx *chip)
+{
+	int i;
+	if (chip->azx_dev) {
+		for (i = 0; i < chip->num_streams; i++)
+			if (chip->azx_dev[i].bdl.area) {
+				mark_pages_wc(chip, &chip->azx_dev[i].bdl,
+					      false);
+				snd_dma_free_pages(&chip->azx_dev[i].bdl);
+			}
+	}
+	if (chip->rb.area) {
+		mark_pages_wc(chip, &chip->rb, false);
+		snd_dma_free_pages(&chip->rb);
+	}
+	if (chip->posbuf.area) {
+		mark_pages_wc(chip, &chip->posbuf, false);
+		snd_dma_free_pages(&chip->posbuf);
+	}
+}
+EXPORT_SYMBOL_GPL(azx_free_stream_pages);
+
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("Common HDA driver funcitons");
diff --git a/sound/pci/hda/hda_shared.h b/sound/pci/hda/hda_shared.h
index bc06d34..ff1eeae 100644
--- a/sound/pci/hda/hda_shared.h
+++ b/sound/pci/hda/hda_shared.h
@@ -55,4 +55,8 @@ void azx_stream_stop(struct azx *chip, struct azx_dev *azx_dev);
 #define dsp_is_locked(dev)	0
 #endif
 
+/* Allocation functions. */
+int azx_alloc_stream_pages(struct azx *chip);
+void azx_free_stream_pages(struct azx *chip);
+
 #endif /* __SOUND_HDA_SHARED_H */
