diff options
author | Enrik Berkhan <Enrik.Berkhan@ge.com> | 2007-12-24 06:51:31 -0500 |
---|---|---|
committer | Bryan Wu <bryan.wu@analog.com> | 2007-12-24 06:51:31 -0500 |
commit | 76a7f4049277691b9b800a23dc09009374cdaa21 (patch) | |
tree | 1cd3070c59cf43ffbaff2d324d204a3085428e3f /arch/blackfin/mach-bf561 | |
parent | 37931db5bdce35d37a9bdf93082604620ba3341a (diff) |
[Blackfin] arch: fix bug when DMA operation related core B of BF561
- Before DMA'ing data to core B L1 memory, caches have to be flushed.
- Before DMA'ing data from core B L1 memory, caches have to be invalidated.
- Fix lock/unlock.
Signed-off-by: Enrik Berkhan <Enrik.Berkhan@ge.com>
Signed-off-by: Mike Frysinger <michael.frysinger@analog.com>
Signed-off-by: Bryan Wu <bryan.wu@analog.com>
Diffstat (limited to 'arch/blackfin/mach-bf561')
-rw-r--r-- | arch/blackfin/mach-bf561/coreb.c | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/arch/blackfin/mach-bf561/coreb.c b/arch/blackfin/mach-bf561/coreb.c index 5d1d21b4c2a7..1b44e9e6dc3b 100644 --- a/arch/blackfin/mach-bf561/coreb.c +++ b/arch/blackfin/mach-bf561/coreb.c | |||
@@ -33,7 +33,9 @@ | |||
33 | #include <linux/ioport.h> | 33 | #include <linux/ioport.h> |
34 | #include <linux/module.h> | 34 | #include <linux/module.h> |
35 | #include <linux/uaccess.h> | 35 | #include <linux/uaccess.h> |
36 | #include <linux/fs.h> | ||
36 | #include <asm/dma.h> | 37 | #include <asm/dma.h> |
38 | #include <asm/cacheflush.h> | ||
37 | 39 | ||
38 | #define MODULE_VER "v0.1" | 40 | #define MODULE_VER "v0.1" |
39 | 41 | ||
@@ -90,11 +92,12 @@ static ssize_t coreb_write(struct file *file, const char *buf, size_t count, | |||
90 | 92 | ||
91 | coreb_dma_done = 0; | 93 | coreb_dma_done = 0; |
92 | 94 | ||
95 | flush_dcache_range((unsigned long)buf, (unsigned long)(buf+len)); | ||
93 | /* Source Channel */ | 96 | /* Source Channel */ |
94 | set_dma_start_addr(CH_MEM_STREAM2_SRC, (unsigned long)buf); | 97 | set_dma_start_addr(CH_MEM_STREAM2_SRC, (unsigned long)buf); |
95 | set_dma_x_count(CH_MEM_STREAM2_SRC, len); | 98 | set_dma_x_count(CH_MEM_STREAM2_SRC, len); |
96 | set_dma_x_modify(CH_MEM_STREAM2_SRC, sizeof(char)); | 99 | set_dma_x_modify(CH_MEM_STREAM2_SRC, sizeof(char)); |
97 | set_dma_config(CH_MEM_STREAM2_SRC, RESTART); | 100 | set_dma_config(CH_MEM_STREAM2_SRC, 0); |
98 | /* Destination Channel */ | 101 | /* Destination Channel */ |
99 | set_dma_start_addr(CH_MEM_STREAM2_DEST, coreb_base + p); | 102 | set_dma_start_addr(CH_MEM_STREAM2_DEST, coreb_base + p); |
100 | set_dma_x_count(CH_MEM_STREAM2_DEST, len); | 103 | set_dma_x_count(CH_MEM_STREAM2_DEST, len); |
@@ -135,11 +138,12 @@ static ssize_t coreb_read(struct file *file, char *buf, size_t count, | |||
135 | 138 | ||
136 | coreb_dma_done = 0; | 139 | coreb_dma_done = 0; |
137 | 140 | ||
141 | invalidate_dcache_range((unsigned long)buf, (unsigned long)(buf+len)); | ||
138 | /* Source Channel */ | 142 | /* Source Channel */ |
139 | set_dma_start_addr(CH_MEM_STREAM2_SRC, coreb_base + p); | 143 | set_dma_start_addr(CH_MEM_STREAM2_SRC, coreb_base + p); |
140 | set_dma_x_count(CH_MEM_STREAM2_SRC, len); | 144 | set_dma_x_count(CH_MEM_STREAM2_SRC, len); |
141 | set_dma_x_modify(CH_MEM_STREAM2_SRC, sizeof(char)); | 145 | set_dma_x_modify(CH_MEM_STREAM2_SRC, sizeof(char)); |
142 | set_dma_config(CH_MEM_STREAM2_SRC, RESTART); | 146 | set_dma_config(CH_MEM_STREAM2_SRC, 0); |
143 | /* Destination Channel */ | 147 | /* Destination Channel */ |
144 | set_dma_start_addr(CH_MEM_STREAM2_DEST, (unsigned long)buf); | 148 | set_dma_start_addr(CH_MEM_STREAM2_DEST, (unsigned long)buf); |
145 | set_dma_x_count(CH_MEM_STREAM2_DEST, len); | 149 | set_dma_x_count(CH_MEM_STREAM2_DEST, len); |
@@ -266,7 +270,7 @@ static int coreb_ioctl(struct inode *inode, struct file *file, | |||
266 | coreb_status |= COREB_IS_RUNNING; | 270 | coreb_status |= COREB_IS_RUNNING; |
267 | bfin_write_SICA_SYSCR(bfin_read_SICA_SYSCR() & ~0x0020); | 271 | bfin_write_SICA_SYSCR(bfin_read_SICA_SYSCR() & ~0x0020); |
268 | SSYNC(); | 272 | SSYNC(); |
269 | spin_lock_irq(&coreb_lock); | 273 | spin_unlock_irq(&coreb_lock); |
270 | break; | 274 | break; |
271 | #if defined(CONFIG_BF561_COREB_RESET) | 275 | #if defined(CONFIG_BF561_COREB_RESET) |
272 | case CMD_COREB_STOP: | 276 | case CMD_COREB_STOP: |
@@ -275,7 +279,7 @@ static int coreb_ioctl(struct inode *inode, struct file *file, | |||
275 | bfin_write_SICA_SYSCR(bfin_read_SICA_SYSCR() | 0x0020); | 279 | bfin_write_SICA_SYSCR(bfin_read_SICA_SYSCR() | 0x0020); |
276 | bfin_write_SICB_SYSCR(bfin_read_SICB_SYSCR() | 0x0080); | 280 | bfin_write_SICB_SYSCR(bfin_read_SICB_SYSCR() | 0x0080); |
277 | coreb_status &= ~COREB_IS_RUNNING; | 281 | coreb_status &= ~COREB_IS_RUNNING; |
278 | spin_lock_irq(&coreb_lock); | 282 | spin_unlock_irq(&coreb_lock); |
279 | break; | 283 | break; |
280 | case CMD_COREB_RESET: | 284 | case CMD_COREB_RESET: |
281 | printk(KERN_INFO "Resetting Core B\n"); | 285 | printk(KERN_INFO "Resetting Core B\n"); |