diff options
author | Takashi Iwai <tiwai@suse.de> | 2018-08-08 22:23:30 +0200 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2018-08-28 13:56:47 +0200 |
commit | fc478143693d8750dca5e35d03d497bdd0202b3f (patch) | |
tree | 7cb5ecbc2ef070c9746ebcf35017f7bb62ab593e /sound/pci/hda/hda_intel.c | |
parent | 78c9be61c3a5cd9e2439fd27a5ffad73a81958c7 (diff) | |
download | linux-fc478143693d8750dca5e35d03d497bdd0202b3f.tar.bz2 |
ALSA: hda: Use new non-cached allocation for non-snoop mode
Now the ALSA memory allocator helper supports the new non-cached
pages, let's use the new type, SNDRV_DMA_TYPE_DEV_UC_SG, for HD-audio
driver. This allows us to reduce lots of codes.
As another positive side-effect by this patch, the long-standing issue
with non-snoop mode playing in the non-mmap mode is fixed. The core
memalloc helper does the proper pgprot setup for non-cached pages for
vmap(), which was missing in the past.
Reported-and-tested-by: Hans Hu <HansHu@zhaoxin.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/hda/hda_intel.c')
-rw-r--r-- | sound/pci/hda/hda_intel.c | 81 |
1 files changed, 4 insertions, 77 deletions
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index e5482fd21568..03ddd1abb44d 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -397,61 +397,6 @@ static char *driver_short_names[] = { [AZX_DRIVER_GENERIC] = "HD-Audio Generic", }; -#ifdef CONFIG_X86 -static void __mark_pages_wc(struct azx *chip, struct snd_dma_buffer *dmab, bool on) -{ - int pages; - - if (azx_snoop(chip)) - return; - if (!dmab || !dmab->area || !dmab->bytes) - return; - -#ifdef CONFIG_SND_DMA_SGBUF - if (dmab->dev.type == SNDRV_DMA_TYPE_DEV_SG) { - struct snd_sg_buf *sgbuf = dmab->private_data; - if (!chip->uc_buffer) - return; /* deal with only CORB/RIRB buffers */ - if (on) - set_pages_array_wc(sgbuf->page_table, sgbuf->pages); - else - set_pages_array_wb(sgbuf->page_table, sgbuf->pages); - return; - } -#endif - - pages = (dmab->bytes + PAGE_SIZE - 1) >> PAGE_SHIFT; - if (on) - set_memory_wc((unsigned long)dmab->area, pages); - else - set_memory_wb((unsigned long)dmab->area, pages); -} - -static inline void mark_pages_wc(struct azx *chip, struct snd_dma_buffer *buf, - bool on) -{ - __mark_pages_wc(chip, buf, on); -} -static inline void mark_runtime_wc(struct azx *chip, struct azx_dev *azx_dev, - struct snd_pcm_substream *substream, bool on) -{ - if (azx_dev->wc_marked != on) { - __mark_pages_wc(chip, snd_pcm_get_dma_buf(substream), on); - azx_dev->wc_marked = on; - } -} -#else -/* NOP for other archs */ -static inline void mark_pages_wc(struct azx *chip, struct snd_dma_buffer *buf, - bool on) -{ -} -static inline void mark_runtime_wc(struct azx *chip, struct azx_dev *azx_dev, - struct snd_pcm_substream *substream, bool on) -{ -} -#endif - static int azx_acquire_irq(struct azx *chip, int do_disconnect); /* @@ -2054,22 +1999,14 @@ static int dma_alloc_pages(struct hdac_bus *bus, struct snd_dma_buffer *buf) { struct azx *chip = bus_to_azx(bus); - int err; - err = snd_dma_alloc_pages(type, - bus->dev, - size, buf); - if (err < 0) - return err; - mark_pages_wc(chip, buf, true); - return 0; + if (!azx_snoop(chip) && type == SNDRV_DMA_TYPE_DEV) + type = SNDRV_DMA_TYPE_DEV_UC; + return snd_dma_alloc_pages(type, bus->dev, size, buf); } static void dma_free_pages(struct hdac_bus *bus, struct snd_dma_buffer *buf) { - struct azx *chip = bus_to_azx(bus); - - mark_pages_wc(chip, buf, false); snd_dma_free_pages(buf); } @@ -2077,22 +2014,12 @@ static int substream_alloc_pages(struct azx *chip, struct snd_pcm_substream *substream, size_t size) { - struct azx_dev *azx_dev = get_azx_dev(substream); - int ret; - - mark_runtime_wc(chip, azx_dev, substream, false); - ret = snd_pcm_lib_malloc_pages(substream, size); - if (ret < 0) - return ret; - mark_runtime_wc(chip, azx_dev, substream, true); - return 0; + return snd_pcm_lib_malloc_pages(substream, size); } static int substream_free_pages(struct azx *chip, struct snd_pcm_substream *substream) { - struct azx_dev *azx_dev = get_azx_dev(substream); - mark_runtime_wc(chip, azx_dev, substream, false); return snd_pcm_lib_free_pages(substream); } |