diff options
author | Michal Simek <monstr@monstr.eu> | 2010-02-08 06:13:10 -0500 |
---|---|---|
committer | Michal Simek <monstr@monstr.eu> | 2010-03-11 08:08:33 -0500 |
commit | d79f3b06a9e40b382bd5d5ae8dea9b3210eda9ce (patch) | |
tree | d0e49b835c40cde89f8af1b641df6baf0b16dd82 /arch/microblaze/kernel | |
parent | 407c1da07d5afa001ed0fdb8f379c00bbd09990a (diff) |
microblaze: Preliminary support for dma drivers
I found several problems for ll_temac driver and on system with WB.
This early fix should fix it. I will clean this patch before I will add
it to mainline
Signed-off-by: Michal Simek <monstr@monstr.eu>
Diffstat (limited to 'arch/microblaze/kernel')
-rw-r--r-- | arch/microblaze/kernel/dma.c | 18 |
1 files changed, 12 insertions, 6 deletions
diff --git a/arch/microblaze/kernel/dma.c b/arch/microblaze/kernel/dma.c index 64bc39f40ba7..f230a8de0bcd 100644 --- a/arch/microblaze/kernel/dma.c +++ b/arch/microblaze/kernel/dma.c | |||
@@ -21,10 +21,10 @@ | |||
21 | * default the offset is PCI_DRAM_OFFSET. | 21 | * default the offset is PCI_DRAM_OFFSET. |
22 | */ | 22 | */ |
23 | 23 | ||
24 | static inline void __dma_sync_page(void *vaddr, unsigned long offset, | 24 | static inline void __dma_sync_page(void *paddr, unsigned long offset, |
25 | size_t size, enum dma_data_direction direction) | 25 | size_t size, enum dma_data_direction direction) |
26 | { | 26 | { |
27 | unsigned long start = virt_to_phys(vaddr); | 27 | unsigned long start = (unsigned long)paddr; |
28 | 28 | ||
29 | switch (direction) { | 29 | switch (direction) { |
30 | case DMA_TO_DEVICE: | 30 | case DMA_TO_DEVICE: |
@@ -79,10 +79,12 @@ static int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl, | |||
79 | struct scatterlist *sg; | 79 | struct scatterlist *sg; |
80 | int i; | 80 | int i; |
81 | 81 | ||
82 | /* FIXME this part of code is untested */ | ||
82 | for_each_sg(sgl, sg, nents, i) { | 83 | for_each_sg(sgl, sg, nents, i) { |
83 | sg->dma_address = sg_phys(sg) + get_dma_direct_offset(dev); | 84 | sg->dma_address = sg_phys(sg) + get_dma_direct_offset(dev); |
84 | sg->dma_length = sg->length; | 85 | sg->dma_length = sg->length; |
85 | __dma_sync_page(sg_page(sg), sg->offset, sg->length, direction); | 86 | __dma_sync_page(page_to_phys(sg_page(sg)), sg->offset, |
87 | sg->length, direction); | ||
86 | } | 88 | } |
87 | 89 | ||
88 | return nents; | 90 | return nents; |
@@ -107,7 +109,7 @@ static inline dma_addr_t dma_direct_map_page(struct device *dev, | |||
107 | struct dma_attrs *attrs) | 109 | struct dma_attrs *attrs) |
108 | { | 110 | { |
109 | BUG_ON(direction == DMA_NONE); | 111 | BUG_ON(direction == DMA_NONE); |
110 | __dma_sync_page(page, offset, size, direction); | 112 | __dma_sync_page(page_to_phys(page), offset, size, direction); |
111 | return page_to_phys(page) + offset + get_dma_direct_offset(dev); | 113 | return page_to_phys(page) + offset + get_dma_direct_offset(dev); |
112 | } | 114 | } |
113 | 115 | ||
@@ -117,8 +119,12 @@ static inline void dma_direct_unmap_page(struct device *dev, | |||
117 | enum dma_data_direction direction, | 119 | enum dma_data_direction direction, |
118 | struct dma_attrs *attrs) | 120 | struct dma_attrs *attrs) |
119 | { | 121 | { |
120 | /* There is not necessary to do cache cleanup */ | 122 | /* There is not necessary to do cache cleanup |
121 | /* __dma_sync_page(dma_address, 0 , size, direction); */ | 123 | * |
124 | * phys_to_virt is here because in __dma_sync_page is __virt_to_phys and | ||
125 | * dma_address is physical address | ||
126 | */ | ||
127 | __dma_sync_page((void *)dma_address, 0 , size, direction); | ||
122 | } | 128 | } |
123 | 129 | ||
124 | struct dma_map_ops dma_direct_ops = { | 130 | struct dma_map_ops dma_direct_ops = { |