diff options
author | Michael Hennerich <michael.hennerich@analog.com> | 2010-06-16 05:12:10 -0400 |
---|---|---|
committer | Mike Frysinger <vapier@gentoo.org> | 2010-08-06 12:55:50 -0400 |
commit | d1401e1dc22606a91f577ad3dfd68ae7e60e0357 (patch) | |
tree | 6c59463c60fd4ada2b5d4974afaa30be7059c67f /arch/blackfin/mach-common | |
parent | 502c8a0e07450ff886b80a11150a123bae92f3f7 (diff) |
Blackfin: fix DMA/cache bug when resuming from suspend to RAM
The dma_memcpy() function takes care of flushing different caches for us.
Normally this is what we want, but when resuming from mem, we don't yet
have caches enabled. If these functions happen to be placed into L1 mem
(which is what we're trying to relocate), then things aren't going to
work. So define a non-cache dma_memcpy() variant to utilize in situations
like this.
Signed-off-by: Michael Hennerich <michael.hennerich@analog.com>
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Diffstat (limited to 'arch/blackfin/mach-common')
-rw-r--r-- | arch/blackfin/mach-common/pm.c | 17 |
1 files changed, 9 insertions, 8 deletions
diff --git a/arch/blackfin/mach-common/pm.c b/arch/blackfin/mach-common/pm.c index ea7f95f6bb4c..09c1fb410748 100644 --- a/arch/blackfin/mach-common/pm.c +++ b/arch/blackfin/mach-common/pm.c | |||
@@ -61,10 +61,11 @@ void bfin_pm_suspend_standby_enter(void) | |||
61 | 61 | ||
62 | int bf53x_suspend_l1_mem(unsigned char *memptr) | 62 | int bf53x_suspend_l1_mem(unsigned char *memptr) |
63 | { | 63 | { |
64 | dma_memcpy(memptr, (const void *) L1_CODE_START, L1_CODE_LENGTH); | 64 | dma_memcpy_nocache(memptr, (const void *) L1_CODE_START, |
65 | dma_memcpy(memptr + L1_CODE_LENGTH, (const void *) L1_DATA_A_START, | 65 | L1_CODE_LENGTH); |
66 | L1_DATA_A_LENGTH); | 66 | dma_memcpy_nocache(memptr + L1_CODE_LENGTH, |
67 | dma_memcpy(memptr + L1_CODE_LENGTH + L1_DATA_A_LENGTH, | 67 | (const void *) L1_DATA_A_START, L1_DATA_A_LENGTH); |
68 | dma_memcpy_nocache(memptr + L1_CODE_LENGTH + L1_DATA_A_LENGTH, | ||
68 | (const void *) L1_DATA_B_START, L1_DATA_B_LENGTH); | 69 | (const void *) L1_DATA_B_START, L1_DATA_B_LENGTH); |
69 | memcpy(memptr + L1_CODE_LENGTH + L1_DATA_A_LENGTH + | 70 | memcpy(memptr + L1_CODE_LENGTH + L1_DATA_A_LENGTH + |
70 | L1_DATA_B_LENGTH, (const void *) L1_SCRATCH_START, | 71 | L1_DATA_B_LENGTH, (const void *) L1_SCRATCH_START, |
@@ -75,10 +76,10 @@ int bf53x_suspend_l1_mem(unsigned char *memptr) | |||
75 | 76 | ||
76 | int bf53x_resume_l1_mem(unsigned char *memptr) | 77 | int bf53x_resume_l1_mem(unsigned char *memptr) |
77 | { | 78 | { |
78 | dma_memcpy((void *) L1_CODE_START, memptr, L1_CODE_LENGTH); | 79 | dma_memcpy_nocache((void *) L1_CODE_START, memptr, L1_CODE_LENGTH); |
79 | dma_memcpy((void *) L1_DATA_A_START, memptr + L1_CODE_LENGTH, | 80 | dma_memcpy_nocache((void *) L1_DATA_A_START, memptr + L1_CODE_LENGTH, |
80 | L1_DATA_A_LENGTH); | 81 | L1_DATA_A_LENGTH); |
81 | dma_memcpy((void *) L1_DATA_B_START, memptr + L1_CODE_LENGTH + | 82 | dma_memcpy_nocache((void *) L1_DATA_B_START, memptr + L1_CODE_LENGTH + |
82 | L1_DATA_A_LENGTH, L1_DATA_B_LENGTH); | 83 | L1_DATA_A_LENGTH, L1_DATA_B_LENGTH); |
83 | memcpy((void *) L1_SCRATCH_START, memptr + L1_CODE_LENGTH + | 84 | memcpy((void *) L1_SCRATCH_START, memptr + L1_CODE_LENGTH + |
84 | L1_DATA_A_LENGTH + L1_DATA_B_LENGTH, L1_SCRATCH_LENGTH); | 85 | L1_DATA_A_LENGTH + L1_DATA_B_LENGTH, L1_SCRATCH_LENGTH); |
@@ -167,7 +168,7 @@ int bfin_pm_suspend_mem_enter(void) | |||
167 | _disable_icplb(); | 168 | _disable_icplb(); |
168 | bf53x_suspend_l1_mem(memptr); | 169 | bf53x_suspend_l1_mem(memptr); |
169 | 170 | ||
170 | do_hibernate(wakeup | vr_wakeup); /* Goodbye */ | 171 | do_hibernate(wakeup | vr_wakeup); /* See you later! */ |
171 | 172 | ||
172 | bf53x_resume_l1_mem(memptr); | 173 | bf53x_resume_l1_mem(memptr); |
173 | 174 | ||