aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda
diff options
context:
space:
mode:
authorDylan Reid <dgreid@chromium.org>2014-02-28 18:41:20 -0500
committerTakashi Iwai <tiwai@suse.de>2014-03-01 05:21:51 -0500
commitb419b35be45f858830e9e0e44741d8de91b3df07 (patch)
treefdfd1a9ff1008c8dd3c9e0180fd0dd5aa36f404c /sound/pci/hda
parente62a42aebd7c97977d8ae0bca8de40d26254a1cd (diff)
ALSA: hda - Move snd page allocation to ops
Break out the allocation of pages for DMA and PCM buffers to ops in the chip structure. This is done to allow for architecture specific work-arounds to be added. Currently mark_pages_wc is used by hda_intel. This avoids needing to move that x86-specific code to a common area shared with hda platform drivers. Signed-off-by: Dylan Reid <dgreid@chromium.org> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/hda')
-rw-r--r--sound/pci/hda/hda_intel.c141
-rw-r--r--sound/pci/hda/hda_priv.h11
2 files changed, 98 insertions, 54 deletions
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index ebbeefe203fd..fa3a04c7771e 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -297,7 +297,10 @@ static char *driver_short_names[] = {
297}; 297};
298 298
299/* for pcm support */ 299/* for pcm support */
300#define get_azx_dev(substream) (substream->runtime->private_data) 300static inline struct azx_dev *get_azx_dev(struct snd_pcm_substream *substream)
301{
302 return substream->runtime->private_data;
303}
301 304
302#ifdef CONFIG_X86 305#ifdef CONFIG_X86
303static void __mark_pages_wc(struct azx *chip, struct snd_dma_buffer *dmab, bool on) 306static void __mark_pages_wc(struct azx *chip, struct snd_dma_buffer *dmab, bool on)
@@ -366,15 +369,11 @@ static int azx_alloc_cmd_io(struct azx *chip)
366 int err; 369 int err;
367 370
368 /* single page (at least 4096 bytes) must suffice for both ringbuffes */ 371 /* single page (at least 4096 bytes) must suffice for both ringbuffes */
369 err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, 372 err = chip->ops->dma_alloc_pages(chip, SNDRV_DMA_TYPE_DEV,
370 chip->card->dev, 373 PAGE_SIZE, &chip->rb);
371 PAGE_SIZE, &chip->rb); 374 if (err < 0)
372 if (err < 0) {
373 dev_err(chip->card->dev, "cannot allocate CORB/RIRB\n"); 375 dev_err(chip->card->dev, "cannot allocate CORB/RIRB\n");
374 return err; 376 return err;
375 }
376 mark_pages_wc(chip, &chip->rb, true);
377 return 0;
378} 377}
379 378
380static void azx_init_cmd_io(struct azx *chip) 379static void azx_init_cmd_io(struct azx *chip)
@@ -1716,26 +1715,18 @@ static int azx_pcm_hw_params(struct snd_pcm_substream *substream,
1716{ 1715{
1717 struct azx_pcm *apcm = snd_pcm_substream_chip(substream); 1716 struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
1718 struct azx *chip = apcm->chip; 1717 struct azx *chip = apcm->chip;
1719 struct azx_dev *azx_dev = get_azx_dev(substream);
1720 int ret; 1718 int ret;
1721 1719
1722 dsp_lock(azx_dev); 1720 dsp_lock(get_azx_dev(substream));
1723 if (dsp_is_locked(azx_dev)) { 1721 if (dsp_is_locked(get_azx_dev(substream))) {
1724 ret = -EBUSY; 1722 ret = -EBUSY;
1725 goto unlock; 1723 goto unlock;
1726 } 1724 }
1727 1725
1728 mark_runtime_wc(chip, azx_dev, substream, false); 1726 ret = chip->ops->substream_alloc_pages(chip, substream,
1729 azx_dev->bufsize = 0; 1727 params_buffer_bytes(hw_params));
1730 azx_dev->period_bytes = 0; 1728unlock:
1731 azx_dev->format_val = 0; 1729 dsp_unlock(get_azx_dev(substream));
1732 ret = snd_pcm_lib_malloc_pages(substream,
1733 params_buffer_bytes(hw_params));
1734 if (ret < 0)
1735 goto unlock;
1736 mark_runtime_wc(chip, azx_dev, substream, true);
1737 unlock:
1738 dsp_unlock(azx_dev);
1739 return ret; 1730 return ret;
1740} 1731}
1741 1732
@@ -1745,6 +1736,7 @@ static int azx_pcm_hw_free(struct snd_pcm_substream *substream)
1745 struct azx_dev *azx_dev = get_azx_dev(substream); 1736 struct azx_dev *azx_dev = get_azx_dev(substream);
1746 struct azx *chip = apcm->chip; 1737 struct azx *chip = apcm->chip;
1747 struct hda_pcm_stream *hinfo = apcm->hinfo[substream->stream]; 1738 struct hda_pcm_stream *hinfo = apcm->hinfo[substream->stream];
1739 int err;
1748 1740
1749 /* reset BDL address */ 1741 /* reset BDL address */
1750 dsp_lock(azx_dev); 1742 dsp_lock(azx_dev);
@@ -1759,10 +1751,10 @@ static int azx_pcm_hw_free(struct snd_pcm_substream *substream)
1759 1751
1760 snd_hda_codec_cleanup(apcm->codec, hinfo, substream); 1752 snd_hda_codec_cleanup(apcm->codec, hinfo, substream);
1761 1753
1762 mark_runtime_wc(chip, azx_dev, substream, false); 1754 err = chip->ops->substream_free_pages(chip, substream);
1763 azx_dev->prepared = 0; 1755 azx_dev->prepared = 0;
1764 dsp_unlock(azx_dev); 1756 dsp_unlock(azx_dev);
1765 return snd_pcm_lib_free_pages(substream); 1757 return err;
1766} 1758}
1767 1759
1768static int azx_pcm_prepare(struct snd_pcm_substream *substream) 1760static int azx_pcm_prepare(struct snd_pcm_substream *substream)
@@ -2398,13 +2390,11 @@ static int azx_load_dsp_prepare(struct hda_bus *bus, unsigned int format,
2398 azx_dev->locked = 1; 2390 azx_dev->locked = 1;
2399 spin_unlock_irq(&chip->reg_lock); 2391 spin_unlock_irq(&chip->reg_lock);
2400 2392
2401 err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV_SG, 2393 err = chip->ops->dma_alloc_pages(chip, SNDRV_DMA_TYPE_DEV_SG,
2402 chip->card->dev, 2394 byte_size, bufp);
2403 byte_size, bufp);
2404 if (err < 0) 2395 if (err < 0)
2405 goto err_alloc; 2396 goto err_alloc;
2406 2397
2407 mark_pages_wc(chip, bufp, true);
2408 azx_dev->bufsize = byte_size; 2398 azx_dev->bufsize = byte_size;
2409 azx_dev->period_bytes = byte_size; 2399 azx_dev->period_bytes = byte_size;
2410 azx_dev->format_val = format; 2400 azx_dev->format_val = format;
@@ -2426,8 +2416,7 @@ static int azx_load_dsp_prepare(struct hda_bus *bus, unsigned int format,
2426 return azx_dev->stream_tag; 2416 return azx_dev->stream_tag;
2427 2417
2428 error: 2418 error:
2429 mark_pages_wc(chip, bufp, false); 2419 chip->ops->dma_free_pages(chip, bufp);
2430 snd_dma_free_pages(bufp);
2431 err_alloc: 2420 err_alloc:
2432 spin_lock_irq(&chip->reg_lock); 2421 spin_lock_irq(&chip->reg_lock);
2433 if (azx_dev->opened) 2422 if (azx_dev->opened)
@@ -2469,8 +2458,7 @@ static void azx_load_dsp_cleanup(struct hda_bus *bus,
2469 azx_dev->period_bytes = 0; 2458 azx_dev->period_bytes = 0;
2470 azx_dev->format_val = 0; 2459 azx_dev->format_val = 0;
2471 2460
2472 mark_pages_wc(chip, dmab, false); 2461 chip->ops->dma_free_pages(chip, dmab);
2473 snd_dma_free_pages(dmab);
2474 dmab->area = NULL; 2462 dmab->area = NULL;
2475 2463
2476 spin_lock_irq(&chip->reg_lock); 2464 spin_lock_irq(&chip->reg_lock);
@@ -2879,19 +2867,14 @@ static int azx_free(struct azx *chip)
2879 2867
2880 if (chip->azx_dev) { 2868 if (chip->azx_dev) {
2881 for (i = 0; i < chip->num_streams; i++) 2869 for (i = 0; i < chip->num_streams; i++)
2882 if (chip->azx_dev[i].bdl.area) { 2870 if (chip->azx_dev[i].bdl.area)
2883 mark_pages_wc(chip, &chip->azx_dev[i].bdl, false); 2871 chip->ops->dma_free_pages(
2884 snd_dma_free_pages(&chip->azx_dev[i].bdl); 2872 chip, &chip->azx_dev[i].bdl);
2885 } 2873 }
2886 } 2874 if (chip->rb.area)
2887 if (chip->rb.area) { 2875 chip->ops->dma_free_pages(chip, &chip->rb);
2888 mark_pages_wc(chip, &chip->rb, false); 2876 if (chip->posbuf.area)
2889 snd_dma_free_pages(&chip->rb); 2877 chip->ops->dma_free_pages(chip, &chip->posbuf);
2890 }
2891 if (chip->posbuf.area) {
2892 mark_pages_wc(chip, &chip->posbuf, false);
2893 snd_dma_free_pages(&chip->posbuf);
2894 }
2895 if (chip->region_requested) 2878 if (chip->region_requested)
2896 pci_release_regions(chip->pci); 2879 pci_release_regions(chip->pci);
2897 pci_disable_device(chip->pci); 2880 pci_disable_device(chip->pci);
@@ -3343,24 +3326,21 @@ static int azx_first_init(struct azx *chip)
3343 for (i = 0; i < chip->num_streams; i++) { 3326 for (i = 0; i < chip->num_streams; i++) {
3344 dsp_lock_init(&chip->azx_dev[i]); 3327 dsp_lock_init(&chip->azx_dev[i]);
3345 /* allocate memory for the BDL for each stream */ 3328 /* allocate memory for the BDL for each stream */
3346 err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, 3329 err = chip->ops->dma_alloc_pages(chip, SNDRV_DMA_TYPE_DEV,
3347 chip->card->dev, 3330 BDL_SIZE,
3348 BDL_SIZE, &chip->azx_dev[i].bdl); 3331 &chip->azx_dev[i].bdl);
3349 if (err < 0) { 3332 if (err < 0) {
3350 dev_err(card->dev, "cannot allocate BDL\n"); 3333 dev_err(card->dev, "cannot allocate BDL\n");
3351 return -ENOMEM; 3334 return -ENOMEM;
3352 } 3335 }
3353 mark_pages_wc(chip, &chip->azx_dev[i].bdl, true);
3354 } 3336 }
3355 /* allocate memory for the position buffer */ 3337 /* allocate memory for the position buffer */
3356 err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, 3338 err = chip->ops->dma_alloc_pages(chip, SNDRV_DMA_TYPE_DEV,
3357 chip->card->dev, 3339 chip->num_streams * 8, &chip->posbuf);
3358 chip->num_streams * 8, &chip->posbuf);
3359 if (err < 0) { 3340 if (err < 0) {
3360 dev_err(card->dev, "cannot allocate posbuf\n"); 3341 dev_err(card->dev, "cannot allocate posbuf\n");
3361 return -ENOMEM; 3342 return -ENOMEM;
3362 } 3343 }
3363 mark_pages_wc(chip, &chip->posbuf, true);
3364 /* allocate CORB/RIRB */ 3344 /* allocate CORB/RIRB */
3365 err = azx_alloc_cmd_io(chip); 3345 err = azx_alloc_cmd_io(chip);
3366 if (err < 0) 3346 if (err < 0)
@@ -3479,6 +3459,55 @@ static int disable_msi_reset_irq(struct azx *chip)
3479 return 0; 3459 return 0;
3480} 3460}
3481 3461
3462/* DMA page allocation helpers. */
3463static int dma_alloc_pages(struct azx *chip,
3464 int type,
3465 size_t size,
3466 struct snd_dma_buffer *buf)
3467{
3468 int err;
3469
3470 err = snd_dma_alloc_pages(type,
3471 chip->card->dev,
3472 size, buf);
3473 if (err < 0)
3474 return err;
3475 mark_pages_wc(chip, buf, true);
3476 return 0;
3477}
3478
3479static void dma_free_pages(struct azx *chip, struct snd_dma_buffer *buf)
3480{
3481 mark_pages_wc(chip, buf, false);
3482 snd_dma_free_pages(buf);
3483}
3484
3485static int substream_alloc_pages(struct azx *chip,
3486 struct snd_pcm_substream *substream,
3487 size_t size)
3488{
3489 struct azx_dev *azx_dev = get_azx_dev(substream);
3490 int ret;
3491
3492 mark_runtime_wc(chip, azx_dev, substream, false);
3493 azx_dev->bufsize = 0;
3494 azx_dev->period_bytes = 0;
3495 azx_dev->format_val = 0;
3496 ret = snd_pcm_lib_malloc_pages(substream, size);
3497 if (ret < 0)
3498 return ret;
3499 mark_runtime_wc(chip, azx_dev, substream, true);
3500 return 0;
3501}
3502
3503static int substream_free_pages(struct azx *chip,
3504 struct snd_pcm_substream *substream)
3505{
3506 struct azx_dev *azx_dev = get_azx_dev(substream);
3507 mark_runtime_wc(chip, azx_dev, substream, false);
3508 return snd_pcm_lib_free_pages(substream);
3509}
3510
3482static const struct hda_controller_ops pci_hda_ops = { 3511static const struct hda_controller_ops pci_hda_ops = {
3483 .writel = pci_azx_writel, 3512 .writel = pci_azx_writel,
3484 .readl = pci_azx_readl, 3513 .readl = pci_azx_readl,
@@ -3487,6 +3516,10 @@ static const struct hda_controller_ops pci_hda_ops = {
3487 .writeb = pci_azx_writeb, 3516 .writeb = pci_azx_writeb,
3488 .readb = pci_azx_readb, 3517 .readb = pci_azx_readb,
3489 .disable_msi_reset_irq = disable_msi_reset_irq, 3518 .disable_msi_reset_irq = disable_msi_reset_irq,
3519 .dma_alloc_pages = dma_alloc_pages,
3520 .dma_free_pages = dma_free_pages,
3521 .substream_alloc_pages = substream_alloc_pages,
3522 .substream_free_pages = substream_free_pages,
3490}; 3523};
3491 3524
3492static int azx_probe(struct pci_dev *pci, 3525static int azx_probe(struct pci_dev *pci,
diff --git a/sound/pci/hda/hda_priv.h b/sound/pci/hda/hda_priv.h
index 0a56e8e18a5a..10bcec127319 100644
--- a/sound/pci/hda/hda_priv.h
+++ b/sound/pci/hda/hda_priv.h
@@ -298,6 +298,17 @@ struct hda_controller_ops {
298 u8 (*readb)(u8 *addr); 298 u8 (*readb)(u8 *addr);
299 /* Disable msi if supported, PCI only */ 299 /* Disable msi if supported, PCI only */
300 int (*disable_msi_reset_irq)(struct azx *); 300 int (*disable_msi_reset_irq)(struct azx *);
301 /* Allocation ops */
302 int (*dma_alloc_pages)(struct azx *chip,
303 int type,
304 size_t size,
305 struct snd_dma_buffer *buf);
306 void (*dma_free_pages)(struct azx *chip, struct snd_dma_buffer *buf);
307 int (*substream_alloc_pages)(struct azx *chip,
308 struct snd_pcm_substream *substream,
309 size_t size);
310 int (*substream_free_pages)(struct azx *chip,
311 struct snd_pcm_substream *substream);
301}; 312};
302 313
303struct azx_pcm { 314struct azx_pcm {