Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

spi: rockchip-sfc: Fix DMA-API usage

Use DMA-API dma_map_single() call for getting the DMA address of the
transfer buffer instead of hacking with virt_to_phys().

This fixes the following DMA-API debug warning:
------------[ cut here ]------------
DMA-API: rockchip-sfc fe300000.spi: device driver tries to sync DMA memory it has not allocated [device address=0x000000000cf70000] [size=288 bytes]
WARNING: kernel/dma/debug.c:1106 at check_sync+0x1d8/0x690, CPU#2: systemd-udevd/151
Modules linked in: ...
Hardware name: Hardkernel ODROID-M1 (DT)
pstate: 604000c9 (nZCv daIF +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
pc : check_sync+0x1d8/0x690
lr : check_sync+0x1d8/0x690
..
Call trace:
check_sync+0x1d8/0x690 (P)
debug_dma_sync_single_for_cpu+0x84/0x8c
__dma_sync_single_for_cpu+0x88/0x234
rockchip_sfc_exec_mem_op+0x4a0/0x798 [spi_rockchip_sfc]
spi_mem_exec_op+0x408/0x498
spi_nor_read_data+0x170/0x184
spi_nor_read_sfdp+0x74/0xe4
spi_nor_parse_sfdp+0x120/0x11f0
spi_nor_sfdp_init_params_deprecated+0x3c/0x8c
spi_nor_scan+0x690/0xf88
spi_nor_probe+0xe4/0x304
spi_mem_probe+0x6c/0xa8
spi_probe+0x94/0xd4
really_probe+0xbc/0x298
...

Fixes: b69386fcbc60 ("spi: rockchip-sfc: Using normal memory for dma")
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Link: https://patch.msgid.link/20251003114239.431114-1-m.szyprowski@samsung.com
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

Marek Szyprowski and committed by
Mark Brown
ee795e82 4092fc5f

+11 -1
+11 -1
drivers/spi/spi-rockchip-sfc.c
··· 704 704 ret = -ENOMEM; 705 705 goto err_dma; 706 706 } 707 - sfc->dma_buffer = virt_to_phys(sfc->buffer); 707 + sfc->dma_buffer = dma_map_single(dev, sfc->buffer, 708 + sfc->max_iosize, DMA_BIDIRECTIONAL); 709 + if (dma_mapping_error(dev, sfc->dma_buffer)) { 710 + ret = -ENOMEM; 711 + goto err_dma_map; 712 + } 708 713 } 709 714 710 715 ret = devm_spi_register_controller(dev, host); ··· 720 715 721 716 return 0; 722 717 err_register: 718 + dma_unmap_single(dev, sfc->dma_buffer, sfc->max_iosize, 719 + DMA_BIDIRECTIONAL); 720 + err_dma_map: 723 721 free_pages((unsigned long)sfc->buffer, get_order(sfc->max_iosize)); 724 722 err_dma: 725 723 pm_runtime_get_sync(dev); ··· 744 736 struct spi_controller *host = sfc->host; 745 737 746 738 spi_unregister_controller(host); 739 + dma_unmap_single(&pdev->dev, sfc->dma_buffer, sfc->max_iosize, 740 + DMA_BIDIRECTIONAL); 747 741 free_pages((unsigned long)sfc->buffer, get_order(sfc->max_iosize)); 748 742 749 743 clk_disable_unprepare(sfc->clk);