Skip to content

Commit

Permalink
arch/sh: make the DMA mapping operations observe dev->dma_pfn_offset
Browse files Browse the repository at this point in the history
Some devices may have a non-zero DMA offset, i.e an offset between the
DMA address and the physical address. Such an offset can be encoded
into the dma_pfn_offset field of "struct device", but the SuperH
implementation of the DMA mapping API does not observe this
information.

This commit fixes that by ensuring the DMA address is properly
calculated depending on this DMA offset.

Signed-off-by: Thomas Petazzoni <[email protected]>
Signed-off-by: Rich Felker <[email protected]>
  • Loading branch information
tpetazzoni authored and Rich Felker committed Apr 12, 2018
1 parent bc05aa6 commit ce88313
Show file tree
Hide file tree
Showing 2 changed files with 7 additions and 4 deletions.
7 changes: 5 additions & 2 deletions arch/sh/kernel/dma-nommu.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ static dma_addr_t nommu_map_page(struct device *dev, struct page *page,
enum dma_data_direction dir,
unsigned long attrs)
{
dma_addr_t addr = page_to_phys(page) + offset;
dma_addr_t addr = page_to_phys(page) + offset
- PFN_PHYS(dev->dma_pfn_offset);

WARN_ON(size == 0);

Expand All @@ -36,12 +37,14 @@ static int nommu_map_sg(struct device *dev, struct scatterlist *sg,
WARN_ON(nents == 0 || sg[0].length == 0);

for_each_sg(sg, s, nents, i) {
dma_addr_t offset = PFN_PHYS(dev->dma_pfn_offset);

BUG_ON(!sg_page(s));

if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC))
sh_sync_dma_for_device(sg_virt(s), s->length, dir);

s->dma_address = sg_phys(s);
s->dma_address = sg_phys(s) - offset;
s->dma_length = s->length;
}

Expand Down
4 changes: 2 additions & 2 deletions arch/sh/mm/consistent.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ void *dma_generic_alloc_coherent(struct device *dev, size_t size,

split_page(pfn_to_page(virt_to_phys(ret) >> PAGE_SHIFT), order);

*dma_handle = virt_to_phys(ret);
*dma_handle = virt_to_phys(ret) - PFN_PHYS(dev->dma_pfn_offset);

return ret_nocache;
}
Expand All @@ -69,7 +69,7 @@ void dma_generic_free_coherent(struct device *dev, size_t size,
unsigned long attrs)
{
int order = get_order(size);
unsigned long pfn = dma_handle >> PAGE_SHIFT;
unsigned long pfn = (dma_handle >> PAGE_SHIFT) + dev->dma_pfn_offset;
int k;

for (k = 0; k < (1 << order); k++)
Expand Down

0 comments on commit ce88313

Please sign in to comment.