Skip to contentSkip to conversation

uvesafb,vesafb: create write-combining or write-back PAT entries

PATCH In review Thomas Schlichter 3 participants 7 messages Nov 27, 2010 – Feb 6, 2011

Subsystems (15)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 uvesafb,vesafb: create write-combining or write-back PAT entries

Hi,

with an PAT-enabled kernel (tested with 2.6.35, but the problem is still present in current -tip), when using uvesafb or vesafb, these drivers will create uncached-minus PAT entries for the framebuffer memory because they use ioremap() (not the *_cached or *_wc variants). When the framebuffer memory intersects with the video RAM used by Xorg, the complete video RAM will be mapped uncached-minus what results in a serve performance penalty.

Here are the correct MTRR entries created by uvesafb:

schlicht@netbook:~$ cat /proc/mtrr
reg00: base=0x000000000 ( 0MB), size= 2048MB, count=1: write-back
reg01: base=0x06ff00000 ( 1791MB), size= 1MB, count=1: uncachable
reg02: base=0x070000000 ( 1792MB), size= 256MB, count=1: uncachable
reg03: base=0x0d0000000 ( 3328MB), size= 16MB, count=1: write-combining

And here are the problematic PAT entries:

schlicht@netbook:~$ sudo cat /sys/kernel/debug/x86/pat_memtype_list
PAT memtype list:
write-back @ 0x0-0x1000
uncached-minus @ 0x6fedd000-0x6fee3000
uncached-minus @ 0x6fee2000-0x6fee3000
uncached-minus @ 0x6fee2000-0x6fee3000
uncached-minus @ 0x6fee2000-0x6fee3000
uncached-minus @ 0x6fee2000-0x6fee3000
uncached-minus @ 0x6fee2000-0x6fee3000
uncached-minus @ 0x6fee2000-0x6fee3000
uncached-minus @ 0x6fee2000-0x6fee3000
uncached-minus @ 0x6fee3000-0x6fee4000
uncached-minus @ 0x6fee3000-0x6fee4000
uncached-minus @ 0x6fee3000-0x6fee4000
uncached-minus @ 0xd0000000-0xe0000000 <-- created by xserver-xorg
uncached-minus @ 0xd0000000-0xd1194000 <-- created by uvesafb
uncached-minus @ 0xf4000000-0xf4009000
uncached-minus @ 0xf4200000-0xf4400000
uncached-minus @ 0xf5000000-0xf5010000
uncached-minus @ 0xf5100000-0xf5104000
uncached-minus @ 0xf5400000-0xf5404000
uncached-minus @ 0xf5404000-0xf5405000
uncached-minus @ 0xf5404000-0xf5405000
uncached-minus @ 0xfed00000-0xfed01000

Therefore I created the attached patch for uvesafb which uses ioremap_wc() to create the correct PAT entries, as shown below:

schlicht@netbook:~$ sudo cat /sys/kernel/debug/x86/pat_memtype_list
PAT memtype list:
write-back @ 0x0-0x1000
uncached-minus @ 0x6fedd000-0x6fee3000
uncached-minus @ 0x6fee2000-0x6fee3000
uncached-minus @ 0x6fee2000-0x6fee3000
uncached-minus @ 0x6fee2000-0x6fee3000
uncached-minus @ 0x6fee2000-0x6fee3000
uncached-minus @ 0x6fee2000-0x6fee3000
uncached-minus @ 0x6fee2000-0x6fee3000
uncached-minus @ 0x6fee2000-0x6fee3000
uncached-minus @ 0x6fee3000-0x6fee4000
uncached-minus @ 0x6fee3000-0x6fee4000
uncached-minus @ 0x6fee3000-0x6fee4000
write-combining @ 0xd0000000-0xe0000000
write-combining @ 0xd0000000-0xd1194000
uncached-minus @ 0xf4000000-0xf4009000
uncached-minus @ 0xf4200000-0xf4400000
uncached-minus @ 0xf5000000-0xf5010000
uncached-minus @ 0xf5100000-0xf5104000
uncached-minus @ 0xf5400000-0xf5404000
uncached-minus @ 0xf5404000-0xf5405000
uncached-minus @ 0xf5404000-0xf5405000
uncached-minus @ 0xfed00000-0xfed01000

This results in a performance gain, objectively measurable with e.g. x11perf -comppixwin10 -comppixwin100 -comppixwin500:
1: x11perf_xaa.log
2: x11perf_xaa_patched.log

1 2 Operation
-------- ----------------- -----------------
124000.0 202000.0 ( 1.63) Composite 10x10 from pixmap to window
3340.0 24400.0 ( 7.31) Composite 100x100 from pixmap to window
131.0 1150.0 ( 8.78) Composite 500x500 from pixmap to window

You can see the serve performance gain when composing larger pixmaps to window.
Please consider applying the attached patches for uvesafb and vesafb.

These patches (for -tip) replace the ioremap() function with the variants matching the mtrr-parameter. To create "write-back" PAT entries, the ioremap_cache() function must be called after creating the MTRR entries, and the ioremap_cache() region must completely fit into the MTRR region, this is why the MTRR region size is now rounded up to the next power-of-two.

Thank you very much!

Kind regards,
Thomas

drivers/video/vesafb.c +29 -15
index 6a069d0..a99bbe8 100644
@@ -303,19 +303,6 @@ static int __init vesafb_probe(struct platform_device *dev)
 	info->apertures->ranges[0].base = screen_info.lfb_base;
 	info->apertures->ranges[0].size = size_total;
 
-	info->screen_base = ioremap(vesafb_fix.smem_start, vesafb_fix.smem_len);
-	if (!info->screen_base) {
-		printk(KERN_ERR
-		       "vesafb: abort, cannot ioremap video memory 0x%x @ 0x%lx\n",
-			vesafb_fix.smem_len, vesafb_fix.smem_start);
-		err = -EIO;
-		goto err;
-	}
-
-	printk(KERN_INFO "vesafb: framebuffer at 0x%lx, mapped to 0x%p, "
-	       "using %dk, total %dk\n",
-	       vesafb_fix.smem_start, info->screen_base,
-	       size_remap/1024, size_total/1024);
 	printk(KERN_INFO "vesafb: mode is %dx%dx%d, linelength=%d, pages=%d\n",
 	       vesafb_defined.xres, vesafb_defined.yres, vesafb_defined.bits_per_pixel, vesafb_fix.line_length, screen_info.pages);
 
@@ -438,8 +425,7 @@ static int __init vesafb_probe(struct platform_device *dev)
 			int rc;
 
 			/* Find the largest power-of-two */
-			while (temp_size & (temp_size - 1))
-				temp_size &= (temp_size - 1);
+			temp_size = roundup_pow_of_two(temp_size);
 
 			/* Try and find a power of two to add */
 			do {
@@ -451,6 +437,34 @@ static int __init vesafb_probe(struct platform_device *dev)
 	}
 #endif
 	
+	switch (mtrr) {
+	case 1: /* uncachable */
+		info->screen_base = ioremap_nocache(vesafb_fix.smem_start, vesafb_fix.smem_len);
+		break;
+	case 2: /* write-back */
+		info->screen_base = ioremap_cache(vesafb_fix.smem_start, vesafb_fix.smem_len);
+		break;
+	case 3: /* write-combining */
+		info->screen_base = ioremap_wc(vesafb_fix.smem_start, vesafb_fix.smem_len);
+		break;
+	case 4: /* write-through */
+	default:
+		info->screen_base = ioremap(vesafb_fix.smem_start, vesafb_fix.smem_len);
+		break;
+	}
+	if (!info->screen_base) {
+		printk(KERN_ERR
+		       "vesafb: abort, cannot ioremap video memory 0x%x @ 0x%lx\n",
+			vesafb_fix.smem_len, vesafb_fix.smem_start);
+		err = -EIO;
+		goto err;
+	}
+
+	printk(KERN_INFO "vesafb: framebuffer at 0x%lx, mapped to 0x%p, "
+	       "using %dk, total %dk\n",
+	       vesafb_fix.smem_start, info->screen_base,
+	       size_remap/1024, size_total/1024);
+
 	info->fbops = &vesafb_ops;
 	info->var = vesafb_defined;
 	info->fix = vesafb_fix;
drivers/video/uvesafb.c +28 -14

83 lines not on this page · raw message

#1 lore raw
Quoted 4 lines · Thomas Schlichter
drivers/video/uvesafb.c +0 -0
index 52ec095..5a34bc8 100644

...

Quoted 11 lines
drivers/video/uvesafb.c +10 -1
-	info->screen_base = ioremap(info->fix.smem_start, info->fix.smem_len);
+	uvesafb_init_mtrr(info);
+
+	switch (mtrr) {
+	case 1: /* uncachable */
+		info->screen_base = ioremap_nocache(info->fix.smem_start, info->fix.smem_len);
+		break;
+	case 2: /* write-back */
+		info->screen_base = ioremap_cache(info->fix.smem_start, info->fix.smem_len);
+		break;
+	case 3: /* write-combining */

drivers/video/uvesafb.c static int __devinit uvesafb_probe(struct platform_device *dev) · line 1771

Quoted 10 lines
drivers/video/uvesafb.c +7 -0
+		info->screen_base = ioremap_wc(info->fix.smem_start, info->fix.smem_len);
+		break;
+	case 4: /* write-through */
+	default:
+		info->screen_base = ioremap(info->fix.smem_start, info->fix.smem_len);
+		break;
+	}
 
 	if (!info->screen_base) {
 		printk(KERN_ERR

uvesafb presently has no special architecture dependencies, but ioremap_wc() is not as of yet a wholly generic interface. Some architectures that don't set ARCH_HAS_IOREMAP_WC get it by virtue of the asm-generic/iomap.h include, and most of the nommu architectures will stub it in via asm-generic/io.h, but this still leaves quite a long list of platforms that don't handle it at all.

Your options at this point are either to establish ioremap_wc() as a generic API, and layer this patch on top of that, or rework uvesafb_init_mtrr() to do the actual broken-out remapping and rework it in to something like a uvesafb_remap(), where you bury the MTRR details under CONFIG_MTRR.

While there's probably value in exposing ioremap_wc() as a generic interface, you're never going to hit any of the non-default ioremap() calls on platforms lacking MTRRs anyways, so special-casing it is ok.

#2 lore raw

Sorry for answering this late, unfortunately I was quite busy with my daily work...

Am Dienstag 30 November 2010, um 07:10:51 schrieb Paul Mundt:

Quoted 13 lines

uvesafb presently has no special architecture dependencies, but ioremap_wc() is not as of yet a wholly generic interface. Some architectures that don't set ARCH_HAS_IOREMAP_WC get it by virtue of the asm-generic/iomap.h include, and most of the nommu architectures will stub it in via asm-generic/io.h, but this still leaves quite a long list of platforms that don't handle it at all.

Your options at this point are either to establish ioremap_wc() as a generic API, and layer this patch on top of that, or rework uvesafb_init_mtrr() to do the actual broken-out remapping and rework it in to something like a uvesafb_remap(), where you bury the MTRR details under CONFIG_MTRR.

Quoted 3 lines

While there's probably value in exposing ioremap_wc() as a generic interface, you're never going to hit any of the non-default ioremap() calls on platforms lacking MTRRs anyways, so special-casing it is ok.

Thank you for finding that problem and showing possibilities for fixing it. I prepared 3 patches, where the first essentially is my old patch with special- casing via ifdef CONFIG_X86. The second patch establishes ioremap_cache() and ioremap_wc() for all architectures, and the third patch removed the special- casing from uvesafb.

So the first patch can stand on its own and hopefully can be merged upstream. The third patch needs the second one, which may be merged for unifying purposes. But as these are mor cleanup-patches, they are not that important for me.

Best regards,
Thomas Schlichter

#3 lore raw

PATCH 1/3 uvesafb,vesafb: create WC or WB PAT entries

From 7172689eb500a7ab7090e8539f88d382fc686336 Mon Sep 17 00:00:00 2001
From: Thomas Schlichter <[email protected]>
Date: Sat, 27 Nov 2010 14:17:55 +0100
Subject: [PATCH 1/3] uvesafb,vesafb: create WC or WB PAT-entries

with an PAT-enabled kernel, when using uvesafb or vesafb, these drivers will create uncached-minus PAT entries for the framebuffer memory because they use ioremap() (not the *_cache or *_wc variants). When the framebuffer memory intersects with the video RAM used by Xorg, the complete video RAM will be mapped uncached-minus what results in a serve performance penalty.

Here are the correct MTRR entries created by uvesafb:

schlicht@netbook:~$ cat /proc/mtrr
reg00: base=0x000000000 ( 0MB), size= 2048MB, count=1: write-back
reg01: base=0x06ff00000 ( 1791MB), size= 1MB, count=1: uncachable
reg02: base=0x070000000 ( 1792MB), size= 256MB, count=1: uncachable
reg03: base=0x0d0000000 ( 3328MB), size= 16MB, count=1: write-combining

And here are the problematic PAT entries:

schlicht@netbook:~$ sudo cat /sys/kernel/debug/x86/pat_memtype_list
PAT memtype list:
write-back @ 0x0-0x1000
uncached-minus @ 0x6fedd000-0x6fee3000
uncached-minus @ 0x6fee2000-0x6fee3000
uncached-minus @ 0x6fee2000-0x6fee3000
uncached-minus @ 0x6fee2000-0x6fee3000
uncached-minus @ 0x6fee2000-0x6fee3000
uncached-minus @ 0x6fee2000-0x6fee3000
uncached-minus @ 0x6fee2000-0x6fee3000
uncached-minus @ 0x6fee2000-0x6fee3000
uncached-minus @ 0x6fee3000-0x6fee4000
uncached-minus @ 0x6fee3000-0x6fee4000
uncached-minus @ 0x6fee3000-0x6fee4000
uncached-minus @ 0xd0000000-0xe0000000 <-- created by xserver-xorg
uncached-minus @ 0xd0000000-0xd1194000 <-- created by uvesafb
uncached-minus @ 0xf4000000-0xf4009000
uncached-minus @ 0xf4200000-0xf4400000
uncached-minus @ 0xf5000000-0xf5010000
uncached-minus @ 0xf5100000-0xf5104000
uncached-minus @ 0xf5400000-0xf5404000
uncached-minus @ 0xf5404000-0xf5405000
uncached-minus @ 0xf5404000-0xf5405000
uncached-minus @ 0xfed00000-0xfed01000

Therefore I created the attached patch for uvesafb which uses ioremap_wc() to create the correct PAT entries, as shown below:

schlicht@netbook:~$ sudo cat /sys/kernel/debug/x86/pat_memtype_list
PAT memtype list:
write-back @ 0x0-0x1000
uncached-minus @ 0x6fedd000-0x6fee3000
uncached-minus @ 0x6fee2000-0x6fee3000
uncached-minus @ 0x6fee2000-0x6fee3000
uncached-minus @ 0x6fee2000-0x6fee3000
uncached-minus @ 0x6fee2000-0x6fee3000
uncached-minus @ 0x6fee2000-0x6fee3000
uncached-minus @ 0x6fee2000-0x6fee3000
uncached-minus @ 0x6fee2000-0x6fee3000
uncached-minus @ 0x6fee3000-0x6fee4000
uncached-minus @ 0x6fee3000-0x6fee4000
uncached-minus @ 0x6fee3000-0x6fee4000
write-combining @ 0xd0000000-0xe0000000
write-combining @ 0xd0000000-0xd1194000
uncached-minus @ 0xf4000000-0xf4009000
uncached-minus @ 0xf4200000-0xf4400000
uncached-minus @ 0xf5000000-0xf5010000
uncached-minus @ 0xf5100000-0xf5104000
uncached-minus @ 0xf5400000-0xf5404000
uncached-minus @ 0xf5404000-0xf5405000
uncached-minus @ 0xf5404000-0xf5405000
uncached-minus @ 0xfed00000-0xfed01000

This results in a performance gain, objectively measurable with e.g. x11perf -comppixwin10 -comppixwin100 -comppixwin500:
1: x11perf_xaa.log
2: x11perf_xaa_patched.log

1 2 Operation
-------- ---------------- -----------------
124000.0 202000.0 ( 1.63) Composite 10x10 from pixmap to window
3340.0 24400.0 ( 7.31) Composite 100x100 from pixmap to window
131.0 1150.0 ( 8.78) Composite 500x500 from pixmap to window

You can see the serve performance gain when composing larger pixmaps to window.

The patches replace the ioremap() function with the variant matching the mtrr- parameter. To create "write-back" PAT entries, the ioremap_cache() function must be called after creating the MTRR entries, and the ioremap_cache() region must completely fit into the MTRR region, this is why the MTRR region size is now rounded up to the next power-of-two.

---
 drivers/video/uvesafb.c |   49 +++++++++++++++++++++++++++++++++-------------
 drivers/video/vesafb.c  |   44 +++++++++++++++++++++++++++--------------
 2 files changed, 64 insertions(+), 29 deletions(-)
drivers/video/uvesafb.c +35 -14
index 52ec095..2d6f799 100644
@@ -1552,8 +1552,7 @@ static void __devinit uvesafb_init_mtrr(struct fb_info *info)
 			int rc;
 
 			/* Find the largest power-of-two */
-			while (temp_size & (temp_size - 1))
-				temp_size &= (temp_size - 1);
+			temp_size = roundup_pow_of_two(temp_size);
 
 			/* Try and find a power of two to add */
 			do {
@@ -1566,6 +1565,28 @@ static void __devinit uvesafb_init_mtrr(struct fb_info *info)
 #endif /* CONFIG_MTRR */
 }
 
+static void __devinit uvesafb_ioremap(struct fb_info *info)
+{
+#ifdef CONFIG_X86
+	switch (mtrr) {
+	case 1: /* uncachable */
+		info->screen_base = ioremap_nocache(info->fix.smem_start, info->fix.smem_len);
+		break;
+	case 2: /* write-back */
+		info->screen_base = ioremap_cache(info->fix.smem_start, info->fix.smem_len);
+		break;
+	case 3: /* write-combining */
+		info->screen_base = ioremap_wc(info->fix.smem_start, info->fix.smem_len);
+		break;
+	case 4: /* write-through */
+	default:
+		info->screen_base = ioremap(info->fix.smem_start, info->fix.smem_len);
+		break;
+	}
+#else
+	info->screen_base = ioremap(info->fix.smem_start, info->fix.smem_len);
+#endif /* CONFIG_X86 */
+}
 
 static ssize_t uvesafb_show_vbe_ver(struct device *dev,
 		struct device_attribute *attr, char *buf)
@@ -1736,15 +1757,22 @@ static int __devinit uvesafb_probe(struct platform_device *dev)
 
 	uvesafb_init_info(info, mode);
 
+	if (!request_region(0x3c0, 32, "uvesafb")) {
+		printk(KERN_ERR "uvesafb: request region 0x3c0-0x3e0 failed\n");
+		err = -EIO;
+		goto out_mode;
+	}
+
 	if (!request_mem_region(info->fix.smem_start, info->fix.smem_len,
 				"uvesafb")) {
 		printk(KERN_ERR "uvesafb: cannot reserve video memory at "
 				"0x%lx\n", info->fix.smem_start);
 		err = -EIO;
-		goto out_mode;
+		goto out_reg;
 	}
 
-	info->screen_base = ioremap(info->fix.smem_start, info->fix.smem_len);
+	uvesafb_init_mtrr(info);
+	uvesafb_ioremap(info);
 
 	if (!info->screen_base) {
 		printk(KERN_ERR
@@ -1755,20 +1783,13 @@ static int __devinit uvesafb_probe(struct platform_device *dev)
 		goto out_mem;
 	}
 
-	if (!request_region(0x3c0, 32, "uvesafb")) {
-		printk(KERN_ERR "uvesafb: request region 0x3c0-0x3e0 failed\n");
-		err = -EIO;
-		goto out_unmap;
-	}
-
-	uvesafb_init_mtrr(info);
 	platform_set_drvdata(dev, info);
 
 	if (register_framebuffer(info) < 0) {
 		printk(KERN_ERR
 			"uvesafb: failed to register framebuffer device\n");
 		err = -EINVAL;
-		goto out_reg;
+		goto out_unmap;
 	}
 
 	printk(KERN_INFO "uvesafb: framebuffer at 0x%lx, mapped to 0x%p, "
@@ -1785,12 +1806,12 @@ static int __devinit uvesafb_probe(struct platform_device *dev)
 
 	return 0;
 
-out_reg:
-	release_region(0x3c0, 32);
 out_unmap:
 	iounmap(info->screen_base);
 out_mem:
 	release_mem_region(info->fix.smem_start, info->fix.smem_len);
+out_reg:
+	release_region(0x3c0, 32);
 out_mode:
 	if (!list_empty(&info->modelist))
 		fb_destroy_modelist(&info->modelist);
drivers/video/vesafb.c +29 -15

62 lines not on this page · raw message

Signature · 1 line
1.7.1
#4 lore raw

PATCH 2/3 Add ioremap_cache and ioremap_wc to all architectures

In reply to Thomas Schlichter

From 194ea8d7dc39c1587d0e38d2571775e73949953b Mon Sep 17 00:00:00 2001
From: Thomas Schlichter <[email protected]>
Date: Sat, 5 Feb 2011 15:07:41 +0100
Subject: [PATCH 2/3] Add ioremap_cache and ioremap_wc to all architectures

Establish ioremap_cache() and ioremap_wc() to be available besides ioremap() and ioremap_nocache() on all architectures. This allows generic drivers to use them without any ifdef-cludge.

---
 arch/alpha/include/asm/io.h      |    3 +++
 arch/arm/include/asm/io.h        |    2 +-
 arch/arm/mm/mmu.c                |    2 +-
 arch/avr32/include/asm/io.h      |    6 ++++++
 arch/cris/include/asm/io.h       |    3 +++
 arch/frv/include/asm/io.h        |    1 +
 arch/h8300/include/asm/io.h      |    3 +++
 arch/ia64/include/asm/io.h       |    1 +
 arch/m32r/include/asm/io.h       |    2 ++
 arch/m68k/include/asm/io_mm.h    |    3 +++
 arch/m68k/include/asm/io_no.h    |    3 +++
 arch/microblaze/include/asm/io.h |    4 ++++
 arch/mips/include/asm/io.h       |    6 ++++--
 arch/mn10300/include/asm/io.h    |    1 +
 arch/parisc/include/asm/io.h     |    2 ++
 arch/powerpc/include/asm/io.h    |    2 ++
 arch/sh/include/asm/io.h         |    1 +
 arch/sparc/include/asm/io_32.h   |    1 +
 arch/sparc/include/asm/io_64.h   |    1 +
 arch/tile/include/asm/io.h       |    2 ++
 arch/x86/include/asm/io.h        |    2 --
 arch/xtensa/include/asm/io.h     |    3 +++
 drivers/mtd/maps/pxa2xx-flash.c  |    2 +-
 include/asm-generic/io.h         |    4 ++++
 include/asm-generic/iomap.h      |    4 ----
 25 files changed, 53 insertions(+), 11 deletions(-)
arch/alpha/include/asm/io.h +3 -0
index 56ff965..beb17bc 100644
@@ -300,6 +300,9 @@ static inline void __iomem * ioremap_nocache(unsigned long offset,
 	return ioremap(offset, size);
 } 
 
+#define ioremap_cache ioremap
+#define ioremap_wc ioremap_nocache
+
 static inline void iounmap(volatile void __iomem *addr)
 {
 	IO_CONCAT(__IO_PREFIX,iounmap)(addr);
arch/arm/include/asm/io.h +1 -1
index d66605d..adb0e46 100644
@@ -248,7 +248,7 @@ extern void _memset_io(volatile void __iomem *, int, size_t);
 
 #define ioremap(cookie,size)		__arch_ioremap((cookie), (size), MT_DEVICE)
 #define ioremap_nocache(cookie,size)	__arch_ioremap((cookie), (size), MT_DEVICE)
-#define ioremap_cached(cookie,size)	__arch_ioremap((cookie), (size), MT_DEVICE_CACHED)
+#define ioremap_cache(cookie,size)	__arch_ioremap((cookie), (size), MT_DEVICE_CACHED)
 #define ioremap_wc(cookie,size)		__arch_ioremap((cookie), (size), MT_DEVICE_WC)
 #define iounmap				__arch_iounmap
 
arch/arm/mm/mmu.c +1 -1
index 3c67e92..d4bf66b 100644
@@ -208,7 +208,7 @@ static struct mem_type mem_types[] = {
 		.prot_sect	= PROT_SECT_DEVICE,
 		.domain		= DOMAIN_IO,
 	},
-	[MT_DEVICE_CACHED] = {	  /* ioremap_cached */
+	[MT_DEVICE_CACHED] = {	  /* ioremap_cache */
 		.prot_pte	= PROT_PTE_DEVICE | L_PTE_MT_DEV_CACHED,
 		.prot_l1	= PMD_TYPE_TABLE,
 		.prot_sect	= PROT_SECT_DEVICE | PMD_SECT_WB,
arch/avr32/include/asm/io.h +6 -0
index 22c97ef..35095c4 100644
@@ -287,6 +287,12 @@ extern void __iounmap(void __iomem *addr);
 #define ioremap_nocache(offset, size)		\
 	__ioremap((offset), (size), 0)
 
+#define ioremap_cache(offset, size)		\
+	__ioremap((offset), (size), 0)
+
+#define ioremap_wc(offset, size)		\
+	__ioremap((offset), (size), 0)
+
 #define iounmap(addr)				\
 	__iounmap(addr)
 
arch/cris/include/asm/io.h +3 -0
index 32567bc..9dad86e 100644
@@ -45,6 +45,9 @@ extern void iounmap(volatile void * __iomem addr);
 
 extern void __iomem * ioremap_nocache(unsigned long offset, unsigned long size);
 
+#define ioremap_cache ioremap
+#define ioremap_wc ioremap_nocache
+
 /*
  * IO bus memory addresses are also 1:1 with the physical address
  */
arch/frv/include/asm/io.h +1 -0
index ca7475e..44d0adf 100644
@@ -271,6 +271,7 @@ static inline void __iomem *ioremap_fullcache(unsigned long physaddr, unsigned l
 	return __ioremap(physaddr, size, IOMAP_FULL_CACHING);
 }
 
+#define ioremap_cache ioremap_fullcache
 #define ioremap_wc ioremap_nocache
 
 extern void iounmap(void volatile __iomem *addr);
arch/h8300/include/asm/io.h +3 -0
index c1a8df2..f5e6aec 100644
@@ -262,6 +262,9 @@ static inline void *ioremap_fullcache(unsigned long physaddr, unsigned long size
 	return __ioremap(physaddr, size, IOMAP_FULL_CACHING);
 }
 
+#define ioremap_cache ioremap_fullcache
+#define ioremap_wc ioremap_nocache
+
 extern void iounmap(void *addr);
 
 /* H8/300 internal I/O functions */
arch/ia64/include/asm/io.h +1 -0
index e5a6c35..9f9e156 100644
@@ -431,6 +431,7 @@ static inline void __iomem * ioremap_cache (unsigned long phys_addr, unsigned lo
 	return ioremap(phys_addr, size);
 }
 
+#define ioremap_wc ioremap_nocache
 
 /*
  * String version of IO memory access ops:
arch/m32r/include/asm/io.h +2 -0
index 4010f1f..0a4a2a9 100644
@@ -67,6 +67,8 @@ static inline void __iomem *ioremap(unsigned long offset, unsigned long size)
 
 extern void iounmap(volatile void __iomem *addr);
 #define ioremap_nocache(off,size) ioremap(off,size)
+#define ioremap_cache(off,size)   ioremap(off,size)
+#define ioremap_wc(off,size)      ioremap(off,size)
 
 /*
  * IO bus memory addresses are also 1:1 with the physical address
arch/m68k/include/asm/io_mm.h +3 -0
index 0fb3468..603b973 100644
@@ -299,6 +299,9 @@ static inline void __iomem *ioremap_fullcache(unsigned long physaddr,
 	return __ioremap(physaddr, size, IOMAP_FULL_CACHING);
 }
 
+#define ioremap_cache ioremap_fullcache
+#define ioremap_wc ioremap_nocache
+
 static inline void memset_io(volatile void __iomem *addr, unsigned char val, int count)
 {
 	__builtin_memset((void __force *) addr, val, count);
arch/m68k/include/asm/io_no.h +3 -0
index cf20f30..ecfead4 100644
@@ -163,6 +163,9 @@ static inline void *ioremap_fullcache(unsigned long physaddr, unsigned long size
 	return __ioremap(physaddr, size, IOMAP_FULL_CACHING);
 }
 
+#define ioremap_cache ioremap_fullcache
+#define ioremap_wc ioremap_nocache
+
 extern void iounmap(void *addr);
 
 /*
arch/microblaze/include/asm/io.h +4 -0
index eae3222..9af2203 100644
@@ -153,6 +153,8 @@ extern void __iomem *ioremap(phys_addr_t address, unsigned long size);
 #define ioremap_writethrough(addr, size) ioremap((addr), (size))
 #define ioremap_nocache(addr, size)      ioremap((addr), (size))
 #define ioremap_fullcache(addr, size)    ioremap((addr), (size))
+#define ioremap_cache(addr, size)        ioremap((addr), (size))
+#define ioremap_wc(addr, size)           ioremap((addr), (size))
 
 #else /* CONFIG_MMU */
 
@@ -203,6 +205,8 @@ static inline void __iomem *__ioremap(phys_addr_t address, unsigned long size,
 #define ioremap(physaddr, size)	((void __iomem *)(unsigned long)(physaddr))
 #define iounmap(addr)		((void)0)
 #define ioremap_nocache(physaddr, size)	ioremap(physaddr, size)
+#define ioremap_cache(physaddr, size)	ioremap(physaddr, size)
+#define ioremap_wc(physaddr, size)	ioremap(physaddr, size)
 
 #endif /* CONFIG_MMU */
 
arch/mips/include/asm/io.h +4 -2
index 5b017f2..51dad4a 100644
@@ -251,7 +251,7 @@ static inline void __iomem * __ioremap_mode(phys_t offset, unsigned long size,
 	__ioremap_mode((offset), (size), _CACHE_UNCACHED)
 
 /*
- * ioremap_cachable -   map bus memory into CPU space
+ * ioremap_cache -  map bus memory into CPU space
  * @offset:         bus address of the memory
  * @size:           size of the resource to map
  *
@@ -265,9 +265,11 @@ static inline void __iomem * __ioremap_mode(phys_t offset, unsigned long size,
  * the CPU.  Also enables full write-combining.  Useful for some
  * memory-like regions on I/O busses.
  */
-#define ioremap_cachable(offset, size)					\
+#define ioremap_cache(offset, size)					\
 	__ioremap_mode((offset), (size), _page_cachable_default)
 
+#define ioremap_wc ioremap_nocache
+
 /*
  * These two are MIPS specific ioremap variant.  ioremap_cacheable_cow
  * requests a cachable mapping, ioremap_uncached_accelerated requests a
arch/mn10300/include/asm/io.h +1 -0
index 787255d..1ed75a0 100644
@@ -272,6 +272,7 @@ static inline void *ioremap_nocache(unsigned long offset, unsigned long size)
 	return (void *) (offset | 0x20000000);
 }
 
+#define ioremap_cache ioremap
 #define ioremap_wc ioremap_nocache
 
 static inline void iounmap(void *addr)
arch/parisc/include/asm/io.h +2 -0
index 1f6d2ae..01edb85 100644
@@ -137,6 +137,8 @@ static inline void __iomem * ioremap(unsigned long offset, unsigned long size)
 	return __ioremap(offset, size, _PAGE_NO_CACHE);
 }
 #define ioremap_nocache(off, sz)	ioremap((off), (sz))
+#define ioremap_cache(off, sz)		ioremap((off), (sz))
+#define ioremap_wc(off, sz)		ioremap((off), (sz))
 
 extern void iounmap(const volatile void __iomem *addr);
 
arch/powerpc/include/asm/io.h +2 -0
index 001f2f1..ee41d61 100644
@@ -643,6 +643,8 @@ extern void __iomem *ioremap(phys_addr_t address, unsigned long size);
 extern void __iomem *ioremap_flags(phys_addr_t address, unsigned long size,
 				   unsigned long flags);
 #define ioremap_nocache(addr, size)	ioremap((addr), (size))
+#define ioremap_cache(addr, size)	ioremap((addr), (size))
+#define ioremap_wc(addr, size)		ioremap((addr), (size))
 #define ioremap_prot(addr, size, prot)	ioremap_flags((addr), (size), (prot))
 
 extern void iounmap(volatile void __iomem *addr);
arch/sh/include/asm/io.h +1 -0
index 28c5aa5..7dfbb47 100644
@@ -369,6 +369,7 @@ static inline int iounmap_fixed(void __iomem *addr) { return -EINVAL; }
 #endif
 
 #define ioremap_nocache	ioremap
+#define ioremap_wc	ioremap
 #define iounmap		__iounmap
 
 /*
arch/sparc/include/asm/io_32.h +1 -0
index c2ced21..f0a8173 100644
@@ -275,6 +275,7 @@ _memcpy_toio(volatile void __iomem *dst, const void *src, __kernel_size_t n)
  */
 extern void __iomem *ioremap(unsigned long offset, unsigned long size);
 #define ioremap_nocache(X,Y)	ioremap((X),(Y))
+#define ioremap_cache(X,Y)	ioremap((X),(Y))
 #define ioremap_wc(X,Y)		ioremap((X),(Y))
 extern void iounmap(volatile void __iomem *addr);
 
arch/sparc/include/asm/io_64.h +1 -0
index 9c89654..08fcfdb 100644
@@ -491,6 +491,7 @@ static inline void __iomem *ioremap(unsigned long offset, unsigned long size)
 }
 
 #define ioremap_nocache(X,Y)		ioremap((X),(Y))
+#define ioremap_cache(X,Y)		ioremap((X),(Y))
 #define ioremap_wc(X,Y)			ioremap((X),(Y))
 
 static inline void iounmap(volatile void __iomem *addr)
arch/tile/include/asm/io.h +2 -0
index d3cbb9b..a9c5320 100644
@@ -54,6 +54,8 @@ extern void iounmap(volatile void __iomem *addr);
 #define ioremap_nocache(physaddr, size)		ioremap(physaddr, size)
 #define ioremap_writethrough(physaddr, size)	ioremap(physaddr, size)
 #define ioremap_fullcache(physaddr, size)	ioremap(physaddr, size)
+#define ioremap_cache(physaddr, size)		ioremap(physaddr, size)
+#define ioremap_wc(physaddr, size)		ioremap(physaddr, size)
 
 #define mmiowb()
 
arch/x86/include/asm/io.h +0 -2
index 0722730..4977ddc 100644
@@ -34,8 +34,6 @@
   *  - Arnaldo Carvalho de Melo <[email protected]>
   */
 
-#define ARCH_HAS_IOREMAP_WC
-
 #include <linux/string.h>
 #include <linux/compiler.h>
 #include <asm-generic/int-ll64.h>
arch/xtensa/include/asm/io.h +3 -0
index d04cd3a..c392cd8 100644
@@ -93,6 +93,9 @@ static inline void *ioremap_nocache(unsigned long offset, unsigned long size)
 #endif
 }
 
+#define ioremap_cache ioremap
+#define ioremap_wc ioremap_nocache
+
 static inline void iounmap(void *addr)
 {
 }
drivers/mtd/maps/pxa2xx-flash.c +1 -1
index d8ae634..2170634 100644
@@ -81,7 +81,7 @@ static int __devinit pxa2xx_flash_probe(struct platform_device *pdev)
 		return -ENOMEM;
 	}
 	info->map.cached =
-		ioremap_cached(info->map.phys, info->map.size);
+		ioremap_cache(info->map.phys, info->map.size);
 	if (!info->map.cached)
 		printk(KERN_WARNING "Failed to ioremap cached %s\n",
 		       info->map.name);
include/asm-generic/io.h +4 -0
index 4644c9a..598d26c 100644
@@ -318,6 +318,10 @@ static inline void __iomem *ioremap(phys_addr_t offset, unsigned long size)
 #define ioremap_wc ioremap_nocache
 #endif
 
+#ifndef ioremap_cache
+#define ioremap_cache ioremap
+#endif
+
 static inline void iounmap(void *addr)
 {
 }
include/asm-generic/iomap.h +0 -4
index 76b0cc5..67dc84c 100644
@@ -60,10 +60,6 @@ extern void iowrite32_rep(void __iomem *port, const void *buf, unsigned long cou
 extern void __iomem *ioport_map(unsigned long port, unsigned int nr);
 extern void ioport_unmap(void __iomem *);
 
-#ifndef ARCH_HAS_IOREMAP_WC
-#define ioremap_wc ioremap_nocache
-#endif
-
 /* Create a virtual mapping cookie for a PCI BAR (memory or IO) */
 struct pci_dev;
 extern void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max);
Signature · 1 line
1.7.1
#5 lore raw

Re: [PATCH 2/3] Add ioremap_cache and ioremap_wc to all architectures

This really should go to linux-arch...

Quoted 2 lines · Thomas Schlichter

Oops, no inline patch. Well, people know they can find the attachment on lkml ;-)

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds

#6 lore raw

PATCH 3/3 uvesafb: remove-ifdef-CONFIG_X86-around-ioremap

In reply to Thomas Schlichter

From d1e432f878746b699856160456f811affc3c42fe Mon Sep 17 00:00:00 2001
From: Thomas Schlichter <[email protected]>
Date: Sun, 6 Feb 2011 11:45:08 +0100
Subject: [PATCH 3/3] uvesafb: remove ifdef CONFIG_X86 around ioremap in

Now that ioremap_cache() and ioremap_wc() are available on each architecture we can remove the unneccessary ifdef in uvesafb.

---
 drivers/video/uvesafb.c |    4 ----
 1 files changed, 0 insertions(+), 4 deletions(-)
drivers/video/uvesafb.c +0 -4
index 2d6f799..ca15166 100644
@@ -1567,7 +1567,6 @@ static void __devinit uvesafb_init_mtrr(struct fb_info *info)
 
 static void __devinit uvesafb_ioremap(struct fb_info *info)
 {
-#ifdef CONFIG_X86
 	switch (mtrr) {
 	case 1: /* uncachable */
 		info->screen_base = ioremap_nocache(info->fix.smem_start, info->fix.smem_len);
@@ -1583,9 +1582,6 @@ static void __devinit uvesafb_ioremap(struct fb_info *info)
 		info->screen_base = ioremap(info->fix.smem_start, info->fix.smem_len);
 		break;
 	}
-#else
-	info->screen_base = ioremap(info->fix.smem_start, info->fix.smem_len);
-#endif /* CONFIG_X86 */
 }
 
 static ssize_t uvesafb_show_vbe_ver(struct device *dev,
Signature · 1 line
1.7.1