aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/spi
diff options
context:
space:
mode:
authorCharles Keepax <ckeepax@opensource.wolfsonmicro.com>2014-11-17 04:14:32 -0500
committerMark Brown <broonie@kernel.org>2014-11-24 13:58:08 -0500
commit9e8987acf051e48fc0e228b6f38c47a75352c58b (patch)
tree5717c3a7539baa4e4810a62f43970d0077f40b7f /drivers/spi
parent617100c2711691e07728d3201fbcfa845a7c36d5 (diff)
spi: spi-mxs: Fix mapping from vmalloc-ed buffer to scatter list
We can only use page_address on memory that has been mapped using kmap, when the buffer passed to the SPI has been allocated by vmalloc the page has not necessarily been mapped through kmap. This means sometimes page_address will return NULL causing the pointer we pass to sg_init_one to be invalid. Currently, this issue doesn't show up on the MXS architecture as the defconfig defines CONFIG_HIGHMEM=n which means all pages are mapped. For the sake of robustness though it is best to correct the issue. As we only call page_address so that we can pass a virtual address to sg_init_one which will eventually call virt_to_page on it, fix this by calling sg_set_page directly rather then relying on the sg_init_one helper. Note this patch is only build tested as I don't have an MXS system to test on. Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com> Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'drivers/spi')
-rw-r--r--drivers/spi/spi-mxs.c10
1 files changed, 5 insertions, 5 deletions
diff --git a/drivers/spi/spi-mxs.c b/drivers/spi/spi-mxs.c
index a9e72f9d385e..06a11546a1a7 100644
--- a/drivers/spi/spi-mxs.c
+++ b/drivers/spi/spi-mxs.c
@@ -182,7 +182,6 @@ static int mxs_spi_txrx_dma(struct mxs_spi *spi,
182 int min, ret; 182 int min, ret;
183 u32 ctrl0; 183 u32 ctrl0;
184 struct page *vm_page; 184 struct page *vm_page;
185 void *sg_buf;
186 struct { 185 struct {
187 u32 pio[4]; 186 u32 pio[4];
188 struct scatterlist sg; 187 struct scatterlist sg;
@@ -232,13 +231,14 @@ static int mxs_spi_txrx_dma(struct mxs_spi *spi,
232 ret = -ENOMEM; 231 ret = -ENOMEM;
233 goto err_vmalloc; 232 goto err_vmalloc;
234 } 233 }
235 sg_buf = page_address(vm_page) + 234
236 ((size_t)buf & ~PAGE_MASK); 235 sg_init_table(&dma_xfer[sg_count].sg, 1);
236 sg_set_page(&dma_xfer[sg_count].sg, vm_page,
237 min, offset_in_page(buf));
237 } else { 238 } else {
238 sg_buf = buf; 239 sg_init_one(&dma_xfer[sg_count].sg, buf, min);
239 } 240 }
240 241
241 sg_init_one(&dma_xfer[sg_count].sg, sg_buf, min);
242 ret = dma_map_sg(ssp->dev, &dma_xfer[sg_count].sg, 1, 242 ret = dma_map_sg(ssp->dev, &dma_xfer[sg_count].sg, 1,
243 (flags & TXRX_WRITE) ? DMA_TO_DEVICE : DMA_FROM_DEVICE); 243 (flags & TXRX_WRITE) ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
244 244