diff options
Diffstat (limited to 'arch/arm/mm/cache-feroceon-l2.c')
-rw-r--r-- | arch/arm/mm/cache-feroceon-l2.c | 42 |
1 files changed, 25 insertions, 17 deletions
diff --git a/arch/arm/mm/cache-feroceon-l2.c b/arch/arm/mm/cache-feroceon-l2.c index 7b5a25d81576..13cdae8b0d44 100644 --- a/arch/arm/mm/cache-feroceon-l2.c +++ b/arch/arm/mm/cache-feroceon-l2.c | |||
@@ -48,11 +48,12 @@ static inline void l2_clean_mva_range(unsigned long start, unsigned long end) | |||
48 | * L2 is PIPT and range operations only do a TLB lookup on | 48 | * L2 is PIPT and range operations only do a TLB lookup on |
49 | * the start address. | 49 | * the start address. |
50 | */ | 50 | */ |
51 | BUG_ON((start ^ end) & ~(PAGE_SIZE - 1)); | 51 | BUG_ON((start ^ end) >> PAGE_SHIFT); |
52 | 52 | ||
53 | raw_local_irq_save(flags); | 53 | raw_local_irq_save(flags); |
54 | __asm__("mcr p15, 1, %0, c15, c9, 4" : : "r" (start)); | 54 | __asm__("mcr p15, 1, %0, c15, c9, 4\n\t" |
55 | __asm__("mcr p15, 1, %0, c15, c9, 5" : : "r" (end)); | 55 | "mcr p15, 1, %1, c15, c9, 5" |
56 | : : "r" (start), "r" (end)); | ||
56 | raw_local_irq_restore(flags); | 57 | raw_local_irq_restore(flags); |
57 | } | 58 | } |
58 | 59 | ||
@@ -80,11 +81,12 @@ static inline void l2_inv_mva_range(unsigned long start, unsigned long end) | |||
80 | * L2 is PIPT and range operations only do a TLB lookup on | 81 | * L2 is PIPT and range operations only do a TLB lookup on |
81 | * the start address. | 82 | * the start address. |
82 | */ | 83 | */ |
83 | BUG_ON((start ^ end) & ~(PAGE_SIZE - 1)); | 84 | BUG_ON((start ^ end) >> PAGE_SHIFT); |
84 | 85 | ||
85 | raw_local_irq_save(flags); | 86 | raw_local_irq_save(flags); |
86 | __asm__("mcr p15, 1, %0, c15, c11, 4" : : "r" (start)); | 87 | __asm__("mcr p15, 1, %0, c15, c11, 4\n\t" |
87 | __asm__("mcr p15, 1, %0, c15, c11, 5" : : "r" (end)); | 88 | "mcr p15, 1, %1, c15, c11, 5" |
89 | : : "r" (start), "r" (end)); | ||
88 | raw_local_irq_restore(flags); | 90 | raw_local_irq_restore(flags); |
89 | } | 91 | } |
90 | 92 | ||
@@ -205,7 +207,7 @@ static void feroceon_l2_flush_range(unsigned long start, unsigned long end) | |||
205 | * time. These are necessary because the L2 cache can only be enabled | 207 | * time. These are necessary because the L2 cache can only be enabled |
206 | * or disabled while the L1 Dcache and Icache are both disabled. | 208 | * or disabled while the L1 Dcache and Icache are both disabled. |
207 | */ | 209 | */ |
208 | static void __init invalidate_and_disable_dcache(void) | 210 | static int __init flush_and_disable_dcache(void) |
209 | { | 211 | { |
210 | u32 cr; | 212 | u32 cr; |
211 | 213 | ||
@@ -217,7 +219,9 @@ static void __init invalidate_and_disable_dcache(void) | |||
217 | flush_cache_all(); | 219 | flush_cache_all(); |
218 | set_cr(cr & ~CR_C); | 220 | set_cr(cr & ~CR_C); |
219 | raw_local_irq_restore(flags); | 221 | raw_local_irq_restore(flags); |
222 | return 1; | ||
220 | } | 223 | } |
224 | return 0; | ||
221 | } | 225 | } |
222 | 226 | ||
223 | static void __init enable_dcache(void) | 227 | static void __init enable_dcache(void) |
@@ -225,18 +229,17 @@ static void __init enable_dcache(void) | |||
225 | u32 cr; | 229 | u32 cr; |
226 | 230 | ||
227 | cr = get_cr(); | 231 | cr = get_cr(); |
228 | if (!(cr & CR_C)) | 232 | set_cr(cr | CR_C); |
229 | set_cr(cr | CR_C); | ||
230 | } | 233 | } |
231 | 234 | ||
232 | static void __init __invalidate_icache(void) | 235 | static void __init __invalidate_icache(void) |
233 | { | 236 | { |
234 | int dummy; | 237 | int dummy; |
235 | 238 | ||
236 | __asm__ __volatile__("mcr p15, 0, %0, c7, c5, 0\n" : "=r" (dummy)); | 239 | __asm__ __volatile__("mcr p15, 0, %0, c7, c5, 0" : "=r" (dummy)); |
237 | } | 240 | } |
238 | 241 | ||
239 | static void __init invalidate_and_disable_icache(void) | 242 | static int __init invalidate_and_disable_icache(void) |
240 | { | 243 | { |
241 | u32 cr; | 244 | u32 cr; |
242 | 245 | ||
@@ -244,7 +247,9 @@ static void __init invalidate_and_disable_icache(void) | |||
244 | if (cr & CR_I) { | 247 | if (cr & CR_I) { |
245 | set_cr(cr & ~CR_I); | 248 | set_cr(cr & ~CR_I); |
246 | __invalidate_icache(); | 249 | __invalidate_icache(); |
250 | return 1; | ||
247 | } | 251 | } |
252 | return 0; | ||
248 | } | 253 | } |
249 | 254 | ||
250 | static void __init enable_icache(void) | 255 | static void __init enable_icache(void) |
@@ -252,8 +257,7 @@ static void __init enable_icache(void) | |||
252 | u32 cr; | 257 | u32 cr; |
253 | 258 | ||
254 | cr = get_cr(); | 259 | cr = get_cr(); |
255 | if (!(cr & CR_I)) | 260 | set_cr(cr | CR_I); |
256 | set_cr(cr | CR_I); | ||
257 | } | 261 | } |
258 | 262 | ||
259 | static inline u32 read_extra_features(void) | 263 | static inline u32 read_extra_features(void) |
@@ -291,13 +295,17 @@ static void __init enable_l2(void) | |||
291 | 295 | ||
292 | u = read_extra_features(); | 296 | u = read_extra_features(); |
293 | if (!(u & 0x00400000)) { | 297 | if (!(u & 0x00400000)) { |
298 | int i, d; | ||
299 | |||
294 | printk(KERN_INFO "Feroceon L2: Enabling L2\n"); | 300 | printk(KERN_INFO "Feroceon L2: Enabling L2\n"); |
295 | 301 | ||
296 | invalidate_and_disable_dcache(); | 302 | d = flush_and_disable_dcache(); |
297 | invalidate_and_disable_icache(); | 303 | i = invalidate_and_disable_icache(); |
298 | write_extra_features(u | 0x00400000); | 304 | write_extra_features(u | 0x00400000); |
299 | enable_icache(); | 305 | if (i) |
300 | enable_dcache(); | 306 | enable_icache(); |
307 | if (d) | ||
308 | enable_dcache(); | ||
301 | } | 309 | } |
302 | } | 310 | } |
303 | 311 | ||