diff options
| -rw-r--r-- | sound/pci/hda/hda_intel.c | 40 |
1 files changed, 26 insertions, 14 deletions
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index bf0a0046b130..c78286f6e5d8 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
| @@ -656,29 +656,43 @@ static char *driver_short_names[] = { | |||
| 656 | #define get_azx_dev(substream) (substream->runtime->private_data) | 656 | #define get_azx_dev(substream) (substream->runtime->private_data) |
| 657 | 657 | ||
| 658 | #ifdef CONFIG_X86 | 658 | #ifdef CONFIG_X86 |
| 659 | static void __mark_pages_wc(struct azx *chip, void *addr, size_t size, bool on) | 659 | static void __mark_pages_wc(struct azx *chip, struct snd_dma_buffer *dmab, bool on) |
| 660 | { | 660 | { |
| 661 | int pages; | ||
| 662 | |||
| 661 | if (azx_snoop(chip)) | 663 | if (azx_snoop(chip)) |
| 662 | return; | 664 | return; |
| 663 | if (addr && size) { | 665 | if (!dmab || !dmab->area || !dmab->bytes) |
| 664 | int pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT; | 666 | return; |
| 667 | |||
| 668 | #ifdef CONFIG_SND_DMA_SGBUF | ||
| 669 | if (dmab->dev.type == SNDRV_DMA_TYPE_DEV_SG) { | ||
| 670 | struct snd_sg_buf *sgbuf = dmab->private_data; | ||
| 665 | if (on) | 671 | if (on) |
| 666 | set_memory_wc((unsigned long)addr, pages); | 672 | set_pages_array_wc(sgbuf->page_table, sgbuf->pages); |
| 667 | else | 673 | else |
| 668 | set_memory_wb((unsigned long)addr, pages); | 674 | set_pages_array_wb(sgbuf->page_table, sgbuf->pages); |
| 675 | return; | ||
| 669 | } | 676 | } |
| 677 | #endif | ||
| 678 | |||
| 679 | pages = (dmab->bytes + PAGE_SIZE - 1) >> PAGE_SHIFT; | ||
| 680 | if (on) | ||
| 681 | set_memory_wc((unsigned long)dmab->area, pages); | ||
| 682 | else | ||
| 683 | set_memory_wb((unsigned long)dmab->area, pages); | ||
| 670 | } | 684 | } |
| 671 | 685 | ||
| 672 | static inline void mark_pages_wc(struct azx *chip, struct snd_dma_buffer *buf, | 686 | static inline void mark_pages_wc(struct azx *chip, struct snd_dma_buffer *buf, |
| 673 | bool on) | 687 | bool on) |
| 674 | { | 688 | { |
| 675 | __mark_pages_wc(chip, buf->area, buf->bytes, on); | 689 | __mark_pages_wc(chip, buf, on); |
| 676 | } | 690 | } |
| 677 | static inline void mark_runtime_wc(struct azx *chip, struct azx_dev *azx_dev, | 691 | static inline void mark_runtime_wc(struct azx *chip, struct azx_dev *azx_dev, |
| 678 | struct snd_pcm_runtime *runtime, bool on) | 692 | struct snd_pcm_substream *substream, bool on) |
| 679 | { | 693 | { |
| 680 | if (azx_dev->wc_marked != on) { | 694 | if (azx_dev->wc_marked != on) { |
| 681 | __mark_pages_wc(chip, runtime->dma_area, runtime->dma_bytes, on); | 695 | __mark_pages_wc(chip, snd_pcm_get_dma_buf(substream), on); |
| 682 | azx_dev->wc_marked = on; | 696 | azx_dev->wc_marked = on; |
| 683 | } | 697 | } |
| 684 | } | 698 | } |
| @@ -689,7 +703,7 @@ static inline void mark_pages_wc(struct azx *chip, struct snd_dma_buffer *buf, | |||
| 689 | { | 703 | { |
| 690 | } | 704 | } |
| 691 | static inline void mark_runtime_wc(struct azx *chip, struct azx_dev *azx_dev, | 705 | static inline void mark_runtime_wc(struct azx *chip, struct azx_dev *azx_dev, |
| 692 | struct snd_pcm_runtime *runtime, bool on) | 706 | struct snd_pcm_substream *substream, bool on) |
| 693 | { | 707 | { |
| 694 | } | 708 | } |
| 695 | #endif | 709 | #endif |
| @@ -1968,11 +1982,10 @@ static int azx_pcm_hw_params(struct snd_pcm_substream *substream, | |||
| 1968 | { | 1982 | { |
| 1969 | struct azx_pcm *apcm = snd_pcm_substream_chip(substream); | 1983 | struct azx_pcm *apcm = snd_pcm_substream_chip(substream); |
| 1970 | struct azx *chip = apcm->chip; | 1984 | struct azx *chip = apcm->chip; |
| 1971 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
| 1972 | struct azx_dev *azx_dev = get_azx_dev(substream); | 1985 | struct azx_dev *azx_dev = get_azx_dev(substream); |
| 1973 | int ret; | 1986 | int ret; |
| 1974 | 1987 | ||
| 1975 | mark_runtime_wc(chip, azx_dev, runtime, false); | 1988 | mark_runtime_wc(chip, azx_dev, substream, false); |
| 1976 | azx_dev->bufsize = 0; | 1989 | azx_dev->bufsize = 0; |
| 1977 | azx_dev->period_bytes = 0; | 1990 | azx_dev->period_bytes = 0; |
| 1978 | azx_dev->format_val = 0; | 1991 | azx_dev->format_val = 0; |
| @@ -1980,7 +1993,7 @@ static int azx_pcm_hw_params(struct snd_pcm_substream *substream, | |||
| 1980 | params_buffer_bytes(hw_params)); | 1993 | params_buffer_bytes(hw_params)); |
| 1981 | if (ret < 0) | 1994 | if (ret < 0) |
| 1982 | return ret; | 1995 | return ret; |
| 1983 | mark_runtime_wc(chip, azx_dev, runtime, true); | 1996 | mark_runtime_wc(chip, azx_dev, substream, true); |
| 1984 | return ret; | 1997 | return ret; |
| 1985 | } | 1998 | } |
| 1986 | 1999 | ||
| @@ -1989,7 +2002,6 @@ static int azx_pcm_hw_free(struct snd_pcm_substream *substream) | |||
| 1989 | struct azx_pcm *apcm = snd_pcm_substream_chip(substream); | 2002 | struct azx_pcm *apcm = snd_pcm_substream_chip(substream); |
| 1990 | struct azx_dev *azx_dev = get_azx_dev(substream); | 2003 | struct azx_dev *azx_dev = get_azx_dev(substream); |
| 1991 | struct azx *chip = apcm->chip; | 2004 | struct azx *chip = apcm->chip; |
| 1992 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
| 1993 | struct hda_pcm_stream *hinfo = apcm->hinfo[substream->stream]; | 2005 | struct hda_pcm_stream *hinfo = apcm->hinfo[substream->stream]; |
| 1994 | 2006 | ||
| 1995 | /* reset BDL address */ | 2007 | /* reset BDL address */ |
| @@ -2002,7 +2014,7 @@ static int azx_pcm_hw_free(struct snd_pcm_substream *substream) | |||
| 2002 | 2014 | ||
| 2003 | snd_hda_codec_cleanup(apcm->codec, hinfo, substream); | 2015 | snd_hda_codec_cleanup(apcm->codec, hinfo, substream); |
| 2004 | 2016 | ||
| 2005 | mark_runtime_wc(chip, azx_dev, runtime, false); | 2017 | mark_runtime_wc(chip, azx_dev, substream, false); |
| 2006 | return snd_pcm_lib_free_pages(substream); | 2018 | return snd_pcm_lib_free_pages(substream); |
| 2007 | } | 2019 | } |
| 2008 | 2020 | ||
