@@ -620,6 +620,52 @@ static const struct snd_malloc_ops snd_dma_noncontig_ops = {
620620 .get_chunk_size = snd_dma_noncontig_get_chunk_size ,
621621};
622622
623+ /* x86-specific SG-buffer with WC pages */
624+ #ifdef CONFIG_SND_DMA_SGBUF
625+ #define sg_wc_address (it ) ((unsigned long)page_address(sg_page_iter_page(it)))
626+
627+ static void * snd_dma_sg_wc_alloc (struct snd_dma_buffer * dmab , size_t size )
628+ {
629+ void * p = snd_dma_noncontig_alloc (dmab , size );
630+ struct sg_table * sgt = dmab -> private_data ;
631+ struct sg_page_iter iter ;
632+
633+ if (!p )
634+ return NULL ;
635+ for_each_sgtable_page (sgt , & iter , 0 )
636+ set_memory_wc (sg_wc_address (& iter ), 1 );
637+ return p ;
638+ }
639+
640+ static void snd_dma_sg_wc_free (struct snd_dma_buffer * dmab )
641+ {
642+ struct sg_table * sgt = dmab -> private_data ;
643+ struct sg_page_iter iter ;
644+
645+ for_each_sgtable_page (sgt , & iter , 0 )
646+ set_memory_wb (sg_wc_address (& iter ), 1 );
647+ snd_dma_noncontig_free (dmab );
648+ }
649+
650+ static int snd_dma_sg_wc_mmap (struct snd_dma_buffer * dmab ,
651+ struct vm_area_struct * area )
652+ {
653+ area -> vm_page_prot = pgprot_writecombine (area -> vm_page_prot );
654+ return dma_mmap_noncontiguous (dmab -> dev .dev , area ,
655+ dmab -> bytes , dmab -> private_data );
656+ }
657+
658+ static const struct snd_malloc_ops snd_dma_sg_wc_ops = {
659+ .alloc = snd_dma_sg_wc_alloc ,
660+ .free = snd_dma_sg_wc_free ,
661+ .mmap = snd_dma_sg_wc_mmap ,
662+ .sync = snd_dma_noncontig_sync ,
663+ .get_addr = snd_dma_noncontig_get_addr ,
664+ .get_page = snd_dma_noncontig_get_page ,
665+ .get_chunk_size = snd_dma_noncontig_get_chunk_size ,
666+ };
667+ #endif /* CONFIG_SND_DMA_SGBUF */
668+
623669/*
624670 * Non-coherent pages allocator
625671 */
@@ -679,14 +725,13 @@ static const struct snd_malloc_ops *dma_ops[] = {
679725 [SNDRV_DMA_TYPE_DEV_WC ] = & snd_dma_wc_ops ,
680726 [SNDRV_DMA_TYPE_NONCONTIG ] = & snd_dma_noncontig_ops ,
681727 [SNDRV_DMA_TYPE_NONCOHERENT ] = & snd_dma_noncoherent_ops ,
728+ #ifdef CONFIG_SND_DMA_SGBUF
729+ [SNDRV_DMA_TYPE_DEV_WC_SG ] = & snd_dma_sg_wc_ops ,
730+ #endif
682731#ifdef CONFIG_GENERIC_ALLOCATOR
683732 [SNDRV_DMA_TYPE_DEV_IRAM ] = & snd_dma_iram_ops ,
684733#endif /* CONFIG_GENERIC_ALLOCATOR */
685734#endif /* CONFIG_HAS_DMA */
686- #ifdef CONFIG_SND_DMA_SGBUF
687- [SNDRV_DMA_TYPE_DEV_SG ] = & snd_dma_sg_ops ,
688- [SNDRV_DMA_TYPE_DEV_WC_SG ] = & snd_dma_sg_ops ,
689- #endif
690735};
691736
692737static const struct snd_malloc_ops * snd_dma_get_ops (struct snd_dma_buffer * dmab )
0 commit comments