aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2011-01-11 01:02:59 -0500
committerPaul Mundt <lethal@linux-sh.org>2011-01-11 01:02:59 -0500
commitefb3e34b6176d30c4fe8635fa8e1beb6280cc2cd (patch)
treee5ed3fee988e3816a9f4ea47bf83970a010cb83e /arch/sh
parent11e1ed6e88616be5489a43bc6297d9bb8464908b (diff)
sh: Fix up legacy PTEA space attribute mapping.
When p3_ioremap() was converted to ioremap_prot() there was some breakage introduced where the 29-bit segmentation logic would trap the area range and return an identity mapping without having allowed the area specification to force mapping through page tables. This wires up a PCC mask for pgprot verification to work out whether to short-circuit the identity mapping on legacy parts, restoring the previous behaviour. Reported-by: Nobuhiro Iwamatsu <iwamatsu@nigauri.org> Cc: stable@kernel.org Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh')
-rw-r--r--arch/sh/include/asm/io.h10
-rw-r--r--arch/sh/include/asm/pgtable_32.h7
2 files changed, 15 insertions, 2 deletions
diff --git a/arch/sh/include/asm/io.h b/arch/sh/include/asm/io.h
index 70c1186b5088..28c5aa58bb45 100644
--- a/arch/sh/include/asm/io.h
+++ b/arch/sh/include/asm/io.h
@@ -290,7 +290,15 @@ __ioremap_29bit(phys_addr_t offset, unsigned long size, pgprot_t prot)
290 * mapping must be done by the PMB or by using page tables. 290 * mapping must be done by the PMB or by using page tables.
291 */ 291 */
292 if (likely(PXSEG(offset) < P3SEG && PXSEG(last_addr) < P3SEG)) { 292 if (likely(PXSEG(offset) < P3SEG && PXSEG(last_addr) < P3SEG)) {
293 if (unlikely(pgprot_val(prot) & _PAGE_CACHABLE)) 293 u64 flags = pgprot_val(prot);
294
295 /*
296 * Anything using the legacy PTEA space attributes needs
297 * to be kicked down to page table mappings.
298 */
299 if (unlikely(flags & _PAGE_PCC_MASK))
300 return NULL;
301 if (unlikely(flags & _PAGE_CACHABLE))
294 return (void __iomem *)P1SEGADDR(offset); 302 return (void __iomem *)P1SEGADDR(offset);
295 303
296 return (void __iomem *)P2SEGADDR(offset); 304 return (void __iomem *)P2SEGADDR(offset);
diff --git a/arch/sh/include/asm/pgtable_32.h b/arch/sh/include/asm/pgtable_32.h
index 3cbedd21fd83..b799fe71114c 100644
--- a/arch/sh/include/asm/pgtable_32.h
+++ b/arch/sh/include/asm/pgtable_32.h
@@ -76,6 +76,10 @@
76/* Wrapper for extended mode pgprot twiddling */ 76/* Wrapper for extended mode pgprot twiddling */
77#define _PAGE_EXT(x) ((unsigned long long)(x) << 32) 77#define _PAGE_EXT(x) ((unsigned long long)(x) << 32)
78 78
79#ifdef CONFIG_X2TLB
80#define _PAGE_PCC_MASK 0x00000000 /* No legacy PTEA support */
81#else
82
79/* software: moves to PTEA.TC (Timing Control) */ 83/* software: moves to PTEA.TC (Timing Control) */
80#define _PAGE_PCC_AREA5 0x00000000 /* use BSC registers for area5 */ 84#define _PAGE_PCC_AREA5 0x00000000 /* use BSC registers for area5 */
81#define _PAGE_PCC_AREA6 0x80000000 /* use BSC registers for area6 */ 85#define _PAGE_PCC_AREA6 0x80000000 /* use BSC registers for area6 */
@@ -89,7 +93,8 @@
89#define _PAGE_PCC_ATR8 0x60000000 /* Attribute Memory space, 8 bit bus */ 93#define _PAGE_PCC_ATR8 0x60000000 /* Attribute Memory space, 8 bit bus */
90#define _PAGE_PCC_ATR16 0x60000001 /* Attribute Memory space, 6 bit bus */ 94#define _PAGE_PCC_ATR16 0x60000001 /* Attribute Memory space, 6 bit bus */
91 95
92#ifndef CONFIG_X2TLB 96#define _PAGE_PCC_MASK 0xe0000001
97
93/* copy the ptea attributes */ 98/* copy the ptea attributes */
94static inline unsigned long copy_ptea_attributes(unsigned long x) 99static inline unsigned long copy_ptea_attributes(unsigned long x)
95{ 100{