summaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorGreg Ungerer <gerg@linux-m68k.org>2018-04-05 15:55:11 +0200
committerGreg Ungerer <gerg@linux-m68k.org>2018-05-28 01:45:27 +0200
commitbe39cbcbd6cc94ed0e6daf3637cc092641254cf3 (patch)
tree95b17fb51ea556553e6a5ae2f37952851f839191 /arch
parentm68k: fix read/write multi-byte IO for PCI on ColdFire (diff)
downloadlinux-be39cbcbd6cc94ed0e6daf3637cc092641254cf3.tar.xz
linux-be39cbcbd6cc94ed0e6daf3637cc092641254cf3.zip
m68k: fix ioremapping for internal ColdFire peripherals
The ColdFire SoC internal peripherals are mapped into virtual address space using the ACR registers of the cache control unit. This means we are using a 1:1 physical:virtual mapping for them that does not rely on page table mappings. We can quickly determine if we are accessing an internal peripheral device given the physical or vitrual address using the same range check. The implications of this mapping is that an ioremap should return the physical address as the virtual mapping __iomem cookie as well. So fix ioremap() to deal with this on ColdFire. Of course you need to take care of this in the iounmap() path as well. Reported-by: Angelo Dureghello <angelo@sysam.it> Signed-off-by: Greg Ungerer <gerg@linux-m68k.org> Reviewed-by: Angelo Dureghello <angelo@sysam.it> Tested-by: Angelo Dureghello <angelo@sysam.it>
Diffstat (limited to 'arch')
-rw-r--r--arch/m68k/mm/kmap.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/arch/m68k/mm/kmap.c b/arch/m68k/mm/kmap.c
index c2a38321c96d..411a308a8ac1 100644
--- a/arch/m68k/mm/kmap.c
+++ b/arch/m68k/mm/kmap.c
@@ -125,6 +125,10 @@ void __iomem *__ioremap(unsigned long physaddr, unsigned long size, int cachefla
return (void __iomem *)physaddr;
}
#endif
+#ifdef CONFIG_COLDFIRE
+ if (__cf_internalio(physaddr))
+ return (void __iomem *) physaddr;
+#endif
#ifdef DEBUG
printk("ioremap: 0x%lx,0x%lx(%d) - ", physaddr, size, cacheflag);
@@ -235,6 +239,10 @@ void iounmap(void __iomem *addr)
((unsigned long)addr > 0x60000000)))
free_io_area((__force void *)addr);
#else
+#ifdef CONFIG_COLDFIRE
+ if (cf_internalio(addr))
+ return;
+#endif
free_io_area((__force void *)addr);
#endif
}