diff options
Diffstat (limited to 'arch/sh/mm')
-rw-r--r-- | arch/sh/mm/pmb.c | 56 |
1 files changed, 32 insertions, 24 deletions
diff --git a/arch/sh/mm/pmb.c b/arch/sh/mm/pmb.c index f2ad6e374b64..cb808a8aaffc 100644 --- a/arch/sh/mm/pmb.c +++ b/arch/sh/mm/pmb.c | |||
@@ -102,24 +102,36 @@ static void pmb_free(struct pmb_entry *pmbe) | |||
102 | } | 102 | } |
103 | 103 | ||
104 | /* | 104 | /* |
105 | * Ensure that the PMB entries match our cache configuration. | ||
106 | * | ||
107 | * When we are in 32-bit address extended mode, CCR.CB becomes | ||
108 | * invalid, so care must be taken to manually adjust cacheable | ||
109 | * translations. | ||
110 | */ | ||
111 | static __always_inline unsigned long pmb_cache_flags(void) | ||
112 | { | ||
113 | unsigned long flags = 0; | ||
114 | |||
115 | #if defined(CONFIG_CACHE_WRITETHROUGH) | ||
116 | flags |= PMB_C | PMB_WT | PMB_UB; | ||
117 | #elif defined(CONFIG_CACHE_WRITEBACK) | ||
118 | flags |= PMB_C; | ||
119 | #endif | ||
120 | |||
121 | return flags; | ||
122 | } | ||
123 | |||
124 | /* | ||
105 | * Must be run uncached. | 125 | * Must be run uncached. |
106 | */ | 126 | */ |
107 | static void set_pmb_entry(struct pmb_entry *pmbe) | 127 | static void set_pmb_entry(struct pmb_entry *pmbe) |
108 | { | 128 | { |
109 | jump_to_uncached(); | 129 | jump_to_uncached(); |
110 | 130 | ||
111 | __raw_writel(pmbe->vpn | PMB_V, mk_pmb_addr(pmbe->entry)); | 131 | pmbe->flags &= ~PMB_CACHE_MASK; |
112 | 132 | pmbe->flags |= pmb_cache_flags(); | |
113 | #ifdef CONFIG_CACHE_WRITETHROUGH | ||
114 | /* | ||
115 | * When we are in 32-bit address extended mode, CCR.CB becomes | ||
116 | * invalid, so care must be taken to manually adjust cacheable | ||
117 | * translations. | ||
118 | */ | ||
119 | if (likely(pmbe->flags & PMB_C)) | ||
120 | pmbe->flags |= PMB_WT; | ||
121 | #endif | ||
122 | 133 | ||
134 | __raw_writel(pmbe->vpn | PMB_V, mk_pmb_addr(pmbe->entry)); | ||
123 | __raw_writel(pmbe->ppn | pmbe->flags | PMB_V, mk_pmb_data(pmbe->entry)); | 135 | __raw_writel(pmbe->ppn | pmbe->flags | PMB_V, mk_pmb_data(pmbe->entry)); |
124 | 136 | ||
125 | back_to_cached(); | 137 | back_to_cached(); |
@@ -163,14 +175,15 @@ long pmb_remap(unsigned long vaddr, unsigned long phys, | |||
163 | 175 | ||
164 | flags = pgprot_val(prot); | 176 | flags = pgprot_val(prot); |
165 | 177 | ||
178 | pmb_flags = PMB_WT | PMB_UB; | ||
179 | |||
166 | /* Convert typical pgprot value to the PMB equivalent */ | 180 | /* Convert typical pgprot value to the PMB equivalent */ |
167 | if (flags & _PAGE_CACHABLE) { | 181 | if (flags & _PAGE_CACHABLE) { |
168 | if (flags & _PAGE_WT) | 182 | pmb_flags |= PMB_C; |
169 | pmb_flags = PMB_WT; | 183 | |
170 | else | 184 | if ((flags & _PAGE_WT) == 0) |
171 | pmb_flags = PMB_C; | 185 | pmb_flags &= ~(PMB_WT | PMB_UB); |
172 | } else | 186 | } |
173 | pmb_flags = PMB_WT | PMB_UB; | ||
174 | 187 | ||
175 | pmbp = NULL; | 188 | pmbp = NULL; |
176 | wanted = size; | 189 | wanted = size; |
@@ -337,13 +350,8 @@ static int pmb_synchronize_mappings(void) | |||
337 | * Update the caching attributes if necessary | 350 | * Update the caching attributes if necessary |
338 | */ | 351 | */ |
339 | if (data_val & PMB_C) { | 352 | if (data_val & PMB_C) { |
340 | #if defined(CONFIG_CACHE_WRITETHROUGH) | 353 | data_val &= ~PMB_CACHE_MASK; |
341 | data_val |= PMB_WT; | 354 | data_val |= pmb_cache_flags(); |
342 | #elif defined(CONFIG_CACHE_WRITEBACK) | ||
343 | data_val &= ~PMB_WT; | ||
344 | #else | ||
345 | data_val &= ~(PMB_C | PMB_WT); | ||
346 | #endif | ||
347 | __raw_writel(data_val, data); | 355 | __raw_writel(data_val, data); |
348 | } | 356 | } |
349 | 357 | ||