From: Takashi Iwai <ti...@suse.de>

[ Upstream commit 78c9be61c3a5cd9e2439fd27a5ffad73a81958c7 ]

Introduce a new flag, uc_buffer, to indicate that the controller
requires the non-cached pages for stream buffers, either as a
chip-specific requirement or specified via snoop=0 option.
This improves the code-readability.

Also, this patch fixes the incorrect behavior for C-Media chip where
the stream buffers were never handled as non-cached due to the check
of driver_type even if you pass snoop=0 option.

Signed-off-by: Takashi Iwai <ti...@suse.de>
Signed-off-by: Sasha Levin <sas...@kernel.org>
---
 sound/pci/hda/hda_controller.h |  1 +
 sound/pci/hda/hda_intel.c      | 11 ++++++++---
 2 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/sound/pci/hda/hda_controller.h b/sound/pci/hda/hda_controller.h
index a68e75b00ea3..53c3cd28bc99 100644
--- a/sound/pci/hda/hda_controller.h
+++ b/sound/pci/hda/hda_controller.h
@@ -160,6 +160,7 @@ struct azx {
        unsigned int msi:1;
        unsigned int probing:1; /* codec probing phase */
        unsigned int snoop:1;
+       unsigned int uc_buffer:1; /* non-cached pages for stream buffers */
        unsigned int align_buffer_size:1;
        unsigned int region_requested:1;
        unsigned int disabled:1; /* disabled by vga_switcheroo */
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 873d9824fbcf..4e38905bc47d 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -410,7 +410,7 @@ static void __mark_pages_wc(struct azx *chip, struct 
snd_dma_buffer *dmab, bool
 #ifdef CONFIG_SND_DMA_SGBUF
        if (dmab->dev.type == SNDRV_DMA_TYPE_DEV_SG) {
                struct snd_sg_buf *sgbuf = dmab->private_data;
-               if (chip->driver_type == AZX_DRIVER_CMEDIA)
+               if (!chip->uc_buffer)
                        return; /* deal with only CORB/RIRB buffers */
                if (on)
                        set_pages_array_wc(sgbuf->page_table, sgbuf->pages);
@@ -1634,6 +1634,7 @@ static void azx_check_snoop_available(struct azx *chip)
                dev_info(chip->card->dev, "Force to %s mode by module option\n",
                         snoop ? "snoop" : "non-snoop");
                chip->snoop = snoop;
+               chip->uc_buffer = !snoop;
                return;
        }
 
@@ -1654,8 +1655,12 @@ static void azx_check_snoop_available(struct azx *chip)
                snoop = false;
 
        chip->snoop = snoop;
-       if (!snoop)
+       if (!snoop) {
                dev_info(chip->card->dev, "Force to non-snoop mode\n");
+               /* C-Media requires non-cached pages only for CORB/RIRB */
+               if (chip->driver_type != AZX_DRIVER_CMEDIA)
+                       chip->uc_buffer = true;
+       }
 }
 
 static void azx_probe_work(struct work_struct *work)
@@ -2094,7 +2099,7 @@ static void pcm_mmap_prepare(struct snd_pcm_substream 
*substream,
 #ifdef CONFIG_X86
        struct azx_pcm *apcm = snd_pcm_substream_chip(substream);
        struct azx *chip = apcm->chip;
-       if (!azx_snoop(chip) && chip->driver_type != AZX_DRIVER_CMEDIA)
+       if (chip->uc_buffer)
                area->vm_page_prot = pgprot_writecombine(area->vm_page_prot);
 #endif
 }
-- 
2.17.1

Reply via email to