From fedc33e36406c4e50592a286169583d0d3d25a2e Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Wed, 21 Mar 2018 23:36:11 +1000 Subject: [PATCH 01/14] m68k: move *_relaxed macros into io_no.h and io_mm.h Move a copy of the definitions of the *_relaxed() macros into io_no.h and io_mm.h. This precedes a change to the io_no.h file to use asm-generic/io.h. They will be removed from io_no.h at that point. Signed-off-by: Greg Ungerer Reviewed-by: Geert Uytterhoeven Reviewed-by: Angelo Dureghello Tested-by: Angelo Dureghello --- arch/m68k/include/asm/io.h | 8 -------- arch/m68k/include/asm/io_mm.h | 8 ++++++++ arch/m68k/include/asm/io_no.h | 8 ++++++++ 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/arch/m68k/include/asm/io.h b/arch/m68k/include/asm/io.h index 756089cc019c..00b45155969c 100644 --- a/arch/m68k/include/asm/io.h +++ b/arch/m68k/include/asm/io.h @@ -4,11 +4,3 @@ #else #include #endif - -#define readb_relaxed(addr) readb(addr) -#define readw_relaxed(addr) readw(addr) -#define readl_relaxed(addr) readl(addr) - -#define writeb_relaxed(b, addr) writeb(b, addr) -#define writew_relaxed(b, addr) writew(b, addr) -#define writel_relaxed(b, addr) writel(b, addr) diff --git a/arch/m68k/include/asm/io_mm.h b/arch/m68k/include/asm/io_mm.h index ed5333e87879..22e778e293c6 100644 --- a/arch/m68k/include/asm/io_mm.h +++ b/arch/m68k/include/asm/io_mm.h @@ -524,4 +524,12 @@ static inline void ioport_unmap(void __iomem *p) { } +#define readb_relaxed(addr) readb(addr) +#define readw_relaxed(addr) readw(addr) +#define readl_relaxed(addr) readl(addr) + +#define writeb_relaxed(b, addr) writeb(b, addr) +#define writew_relaxed(b, addr) writew(b, addr) +#define writel_relaxed(b, addr) writel(b, addr) + #endif /* _IO_H */ diff --git a/arch/m68k/include/asm/io_no.h b/arch/m68k/include/asm/io_no.h index 86f45b403bcc..ffe567e79082 100644 --- a/arch/m68k/include/asm/io_no.h +++ b/arch/m68k/include/asm/io_no.h @@ -189,4 +189,12 @@ static inline void ioport_unmap(void __iomem *p) #endif /* __KERNEL__ */ +#define readb_relaxed(addr) readb(addr) +#define readw_relaxed(addr) readw(addr) +#define readl_relaxed(addr) readl(addr) + +#define writeb_relaxed(b, addr) writeb(b, addr) +#define writew_relaxed(b, addr) writew(b, addr) +#define writel_relaxed(b, addr) writel(b, addr) + #endif /* _M68KNOMMU_IO_H */ From f8f3304856cdf67414ba2c1a3d2adf78974a3d6a Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Thu, 22 Mar 2018 10:36:41 +1000 Subject: [PATCH 02/14] m68k: put definition guards around virt_to_phys and phys_to_virt The non-MMU and ColdFire IO access functions will be moving to using the asm-generic/io.h in the near future. To make that possible we need define guards around the m68k specific virt_to_phys() and phys_to_virt() functions. Signed-off-by: Greg Ungerer Reviewed-by: Geert Uytterhoeven Reviewed-by: Angelo Dureghello Tested-by: Angelo Dureghello --- arch/m68k/include/asm/virtconvert.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/m68k/include/asm/virtconvert.h b/arch/m68k/include/asm/virtconvert.h index 4aea6be7b220..dfe43083b579 100644 --- a/arch/m68k/include/asm/virtconvert.h +++ b/arch/m68k/include/asm/virtconvert.h @@ -16,11 +16,13 @@ /* * Change virtual addresses to physical addresses and vv. */ +#define virt_to_phys virt_to_phys static inline unsigned long virt_to_phys(void *address) { return __pa(address); } +#define phys_to_virt phys_to_virt static inline void *phys_to_virt(unsigned long address) { return __va(address); From d97cf70af09721ef416c61faa44543e3b84c9a55 Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Fri, 23 Mar 2018 23:39:10 +1000 Subject: [PATCH 03/14] m68k: use asm-generic/io.h for non-MMU io access functions There is nothing really special about the non-MMU m68k IO access functions. So we can easily switch to using the asm-generic/io.h functions. The only thing we do need to handle is that historically the m68k IO access functions for readw/readl/writew/writel use native CPU endian ordering. So for us on m68k/ColdFire that means they are big-endian. Leave the existing set of _raw_read/__raw_write and read/write macros in place to deal with them. (They are ripe for later cleanup, but that is for another patch). Signed-off-by: Greg Ungerer Reviewed-by: Angelo Dureghello Tested-by: Angelo Dureghello --- arch/m68k/include/asm/io_no.h | 179 +--------------------------------- 1 file changed, 5 insertions(+), 174 deletions(-) diff --git a/arch/m68k/include/asm/io_no.h b/arch/m68k/include/asm/io_no.h index ffe567e79082..acd049824dec 100644 --- a/arch/m68k/include/asm/io_no.h +++ b/arch/m68k/include/asm/io_no.h @@ -2,40 +2,11 @@ #ifndef _M68KNOMMU_IO_H #define _M68KNOMMU_IO_H -#ifdef __KERNEL__ - -#define ARCH_HAS_IOREMAP_WT - -#include -#include - /* - * These are for ISA/PCI shared memory _only_ and should never be used - * on any other type of memory, including Zorro memory. They are meant to - * access the bus in the bus byte order which is little-endian!. - * - * readX/writeX() are used to access memory mapped devices. On some - * architectures the memory mapped IO stuff needs to be accessed - * differently. On the m68k architecture, we just read/write the - * memory location directly. + * The non-MMU m68k and ColdFire IO and memory mapped hardware access + * functions have always worked in CPU native endian. We need to define + * that behavior here first before we include asm-generic/io.h. */ -/* ++roman: The assignments to temp. vars avoid that gcc sometimes generates - * two accesses to memory, which may be undesirable for some devices. - */ - -/* - * swap functions are sometimes needed to interface little-endian hardware - */ -static inline unsigned short _swapw(volatile unsigned short v) -{ - return ((v << 8) | (v >> 8)); -} - -static inline unsigned int _swapl(volatile unsigned long v) -{ - return ((v << 24) | ((v & 0xff00) << 8) | ((v & 0xff0000) >> 8) | (v >> 24)); -} - #define readb(addr) \ ({ unsigned char __v = (*(volatile unsigned char *) (addr)); __v; }) #define readw(addr) \ @@ -54,147 +25,7 @@ static inline unsigned int _swapl(volatile unsigned long v) #define __raw_writew writew #define __raw_writel writel -static inline void io_outsb(unsigned int addr, const void *buf, int len) -{ - volatile unsigned char *ap = (volatile unsigned char *) addr; - unsigned char *bp = (unsigned char *) buf; - while (len--) - *ap = *bp++; -} - -static inline void io_outsw(unsigned int addr, const void *buf, int len) -{ - volatile unsigned short *ap = (volatile unsigned short *) addr; - unsigned short *bp = (unsigned short *) buf; - while (len--) - *ap = _swapw(*bp++); -} - -static inline void io_outsl(unsigned int addr, const void *buf, int len) -{ - volatile unsigned int *ap = (volatile unsigned int *) addr; - unsigned int *bp = (unsigned int *) buf; - while (len--) - *ap = _swapl(*bp++); -} - -static inline void io_insb(unsigned int addr, void *buf, int len) -{ - volatile unsigned char *ap = (volatile unsigned char *) addr; - unsigned char *bp = (unsigned char *) buf; - while (len--) - *bp++ = *ap; -} - -static inline void io_insw(unsigned int addr, void *buf, int len) -{ - volatile unsigned short *ap = (volatile unsigned short *) addr; - unsigned short *bp = (unsigned short *) buf; - while (len--) - *bp++ = _swapw(*ap); -} - -static inline void io_insl(unsigned int addr, void *buf, int len) -{ - volatile unsigned int *ap = (volatile unsigned int *) addr; - unsigned int *bp = (unsigned int *) buf; - while (len--) - *bp++ = _swapl(*ap); -} - -#define mmiowb() - -/* - * make the short names macros so specific devices - * can override them as required - */ - -#define memset_io(a,b,c) memset((void *)(a),(b),(c)) -#define memcpy_fromio(a,b,c) memcpy((a),(void *)(b),(c)) -#define memcpy_toio(a,b,c) memcpy((void *)(a),(b),(c)) - -#define inb(addr) readb(addr) -#define inw(addr) readw(addr) -#define inl(addr) readl(addr) -#define outb(x,addr) ((void) writeb(x,addr)) -#define outw(x,addr) ((void) writew(x,addr)) -#define outl(x,addr) ((void) writel(x,addr)) - -#define inb_p(addr) inb(addr) -#define inw_p(addr) inw(addr) -#define inl_p(addr) inl(addr) -#define outb_p(x,addr) outb(x,addr) -#define outw_p(x,addr) outw(x,addr) -#define outl_p(x,addr) outl(x,addr) - -#define outsb(a,b,l) io_outsb(a,b,l) -#define outsw(a,b,l) io_outsw(a,b,l) -#define outsl(a,b,l) io_outsl(a,b,l) - -#define insb(a,b,l) io_insb(a,b,l) -#define insw(a,b,l) io_insw(a,b,l) -#define insl(a,b,l) io_insl(a,b,l) - -#define IO_SPACE_LIMIT 0xffffffff - - -/* Values for nocacheflag and cmode */ -#define IOMAP_FULL_CACHING 0 -#define IOMAP_NOCACHE_SER 1 -#define IOMAP_NOCACHE_NONSER 2 -#define IOMAP_WRITETHROUGH 3 - -static inline void *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag) -{ - return (void *) physaddr; -} -static inline void *ioremap(unsigned long physaddr, unsigned long size) -{ - return __ioremap(physaddr, size, IOMAP_NOCACHE_SER); -} -static inline void *ioremap_nocache(unsigned long physaddr, unsigned long size) -{ - return __ioremap(physaddr, size, IOMAP_NOCACHE_SER); -} -static inline void *ioremap_wt(unsigned long physaddr, unsigned long size) -{ - return __ioremap(physaddr, size, IOMAP_WRITETHROUGH); -} -static inline void *ioremap_fullcache(unsigned long physaddr, unsigned long size) -{ - return __ioremap(physaddr, size, IOMAP_FULL_CACHING); -} - -#define iounmap(addr) do { } while(0) - -/* - * Convert a physical pointer to a virtual kernel pointer for /dev/mem - * access - */ -#define xlate_dev_mem_ptr(p) __va(p) - -/* - * Convert a virtual cached pointer to an uncached pointer - */ -#define xlate_dev_kmem_ptr(p) p - -static inline void __iomem *ioport_map(unsigned long port, unsigned int nr) -{ - return (void __iomem *) port; -} - -static inline void ioport_unmap(void __iomem *p) -{ -} - -#endif /* __KERNEL__ */ - -#define readb_relaxed(addr) readb(addr) -#define readw_relaxed(addr) readw(addr) -#define readl_relaxed(addr) readl(addr) - -#define writeb_relaxed(b, addr) writeb(b, addr) -#define writew_relaxed(b, addr) writew(b, addr) -#define writel_relaxed(b, addr) writel(b, addr) +#include +#include #endif /* _M68KNOMMU_IO_H */ From 4478048b4485285353cc095a47683d2a86509c7d Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Mon, 26 Mar 2018 11:35:13 +1000 Subject: [PATCH 04/14] m68k: rework raw access macros for the non-MMU case The primary and fundamental access macros are really the __raw versions. So make them the actual implementation for access, and not the read/write access macros. The read/write macros and functions are built on top of the raw access (with byte swapping or other actions as required). This in itself causes no functional change right now. But it will make it easier to fix and resolve problems with PCI bus access in the future. Signed-off-by: Greg Ungerer Reviewed-by: Angelo Dureghello Tested-by: Angelo Dureghello --- arch/m68k/include/asm/io_no.h | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/arch/m68k/include/asm/io_no.h b/arch/m68k/include/asm/io_no.h index acd049824dec..5095693e46ce 100644 --- a/arch/m68k/include/asm/io_no.h +++ b/arch/m68k/include/asm/io_no.h @@ -7,23 +7,23 @@ * functions have always worked in CPU native endian. We need to define * that behavior here first before we include asm-generic/io.h. */ -#define readb(addr) \ +#define __raw_readb(addr) \ ({ unsigned char __v = (*(volatile unsigned char *) (addr)); __v; }) -#define readw(addr) \ +#define __raw_readw(addr) \ ({ unsigned short __v = (*(volatile unsigned short *) (addr)); __v; }) -#define readl(addr) \ +#define __raw_readl(addr) \ ({ unsigned int __v = (*(volatile unsigned int *) (addr)); __v; }) -#define writeb(b,addr) (void)((*(volatile unsigned char *) (addr)) = (b)) -#define writew(b,addr) (void)((*(volatile unsigned short *) (addr)) = (b)) -#define writel(b,addr) (void)((*(volatile unsigned int *) (addr)) = (b)) +#define __raw_writeb(b, addr) (void)((*(volatile unsigned char *) (addr)) = (b)) +#define __raw_writew(b, addr) (void)((*(volatile unsigned short *) (addr)) = (b)) +#define __raw_writel(b, addr) (void)((*(volatile unsigned int *) (addr)) = (b)) -#define __raw_readb readb -#define __raw_readw readw -#define __raw_readl readl -#define __raw_writeb writeb -#define __raw_writew writew -#define __raw_writel writel +#define readb __raw_readb +#define readw __raw_readw +#define readl __raw_readl +#define writeb __raw_writeb +#define writew __raw_writew +#define writel __raw_writel #include #include From 9746882f547d2f00d2e761b418ae690cd406c8e2 Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Sun, 25 Mar 2018 22:17:38 +1000 Subject: [PATCH 05/14] m68k: group io mapping definitions and functions Create a new header file, kmap.h, that groups all the definitions and functions associated with the io mapping and remapping. Currently the functions are spread across raw_io.h and io_mm.h. And in the future we will want to use these in io_no.h as well. So it makes sense to move them all together into a single header file. It is named after the arch/m68k/mm/kmap.c file that actually implements many of the exported functions. Signed-off-by: Greg Ungerer Tested-by: Angelo Dureghello --- arch/m68k/include/asm/atarihw.h | 1 + arch/m68k/include/asm/io_mm.h | 43 +--------------- arch/m68k/include/asm/io_no.h | 12 +++++ arch/m68k/include/asm/kmap.h | 80 ++++++++++++++++++++++++++++++ arch/m68k/include/asm/nubus.h | 1 + arch/m68k/include/asm/q40_master.h | 2 +- arch/m68k/include/asm/raw_io.h | 14 ------ arch/m68k/include/asm/vga.h | 1 + arch/m68k/include/asm/zorro.h | 1 + 9 files changed, 98 insertions(+), 57 deletions(-) create mode 100644 arch/m68k/include/asm/kmap.h diff --git a/arch/m68k/include/asm/atarihw.h b/arch/m68k/include/asm/atarihw.h index 972c8f33f055..9000b249d225 100644 --- a/arch/m68k/include/asm/atarihw.h +++ b/arch/m68k/include/asm/atarihw.h @@ -23,6 +23,7 @@ #include #include #include +#include extern u_long atari_mch_cookie; extern u_long atari_mch_type; diff --git a/arch/m68k/include/asm/io_mm.h b/arch/m68k/include/asm/io_mm.h index 22e778e293c6..21fba26f57f4 100644 --- a/arch/m68k/include/asm/io_mm.h +++ b/arch/m68k/include/asm/io_mm.h @@ -26,6 +26,7 @@ #include #include #include +#include #include @@ -461,39 +462,6 @@ static inline void isa_delay(void) #define mmiowb() -static inline void __iomem *ioremap(unsigned long physaddr, unsigned long size) -{ - return __ioremap(physaddr, size, IOMAP_NOCACHE_SER); -} -static inline void __iomem *ioremap_nocache(unsigned long physaddr, unsigned long size) -{ - return __ioremap(physaddr, size, IOMAP_NOCACHE_SER); -} -#define ioremap_uc ioremap_nocache -static inline void __iomem *ioremap_wt(unsigned long physaddr, - unsigned long size) -{ - return __ioremap(physaddr, size, IOMAP_WRITETHROUGH); -} -static inline void __iomem *ioremap_fullcache(unsigned long physaddr, - unsigned long size) -{ - return __ioremap(physaddr, size, IOMAP_FULL_CACHING); -} - -static inline void memset_io(volatile void __iomem *addr, unsigned char val, int count) -{ - __builtin_memset((void __force *) addr, val, count); -} -static inline void memcpy_fromio(void *dst, const volatile void __iomem *src, int count) -{ - __builtin_memcpy(dst, (void __force *) src, count); -} -static inline void memcpy_toio(volatile void __iomem *dst, const void *src, int count) -{ - __builtin_memcpy((void __force *) dst, src, count); -} - #ifndef CONFIG_SUN3 #define IO_SPACE_LIMIT 0xffff #else @@ -515,15 +483,6 @@ static inline void memcpy_toio(volatile void __iomem *dst, const void *src, int */ #define xlate_dev_kmem_ptr(p) p -static inline void __iomem *ioport_map(unsigned long port, unsigned int nr) -{ - return (void __iomem *) port; -} - -static inline void ioport_unmap(void __iomem *p) -{ -} - #define readb_relaxed(addr) readb(addr) #define readw_relaxed(addr) readw(addr) #define readl_relaxed(addr) readl(addr) diff --git a/arch/m68k/include/asm/io_no.h b/arch/m68k/include/asm/io_no.h index 5095693e46ce..e9c70f754e02 100644 --- a/arch/m68k/include/asm/io_no.h +++ b/arch/m68k/include/asm/io_no.h @@ -25,6 +25,18 @@ #define writew __raw_writew #define writel __raw_writel +/* + * These are defined in kmap.h as static inline functions. To maintain + * previous behavior we put these define guards here so io_mm.h doesn't + * see them. + */ +#ifdef CONFIG_MMU +#define memset_io memset_io +#define memcpy_fromio memcpy_fromio +#define memcpy_toio memcpy_toio +#endif + +#include #include #include diff --git a/arch/m68k/include/asm/kmap.h b/arch/m68k/include/asm/kmap.h new file mode 100644 index 000000000000..84b8333db8ad --- /dev/null +++ b/arch/m68k/include/asm/kmap.h @@ -0,0 +1,80 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _KMAP_H +#define _KMAP_H + +#ifdef CONFIG_MMU + +/* Values for nocacheflag and cmode */ +#define IOMAP_FULL_CACHING 0 +#define IOMAP_NOCACHE_SER 1 +#define IOMAP_NOCACHE_NONSER 2 +#define IOMAP_WRITETHROUGH 3 + +/* + * These functions exported by arch/m68k/mm/kmap.c. + * Only needed on MMU enabled systems. + */ +extern void __iomem *__ioremap(unsigned long physaddr, unsigned long size, + int cacheflag); +extern void iounmap(void __iomem *addr); +extern void __iounmap(void *addr, unsigned long size); + +#define ioremap ioremap +static inline void __iomem *ioremap(unsigned long physaddr, unsigned long size) +{ + return __ioremap(physaddr, size, IOMAP_NOCACHE_SER); +} + +#define ioremap_nocache ioremap_nocache +static inline void __iomem *ioremap_nocache(unsigned long physaddr, + unsigned long size) +{ + return __ioremap(physaddr, size, IOMAP_NOCACHE_SER); +} + +#define ioremap_uc ioremap_nocache +static inline void __iomem *ioremap_wt(unsigned long physaddr, + unsigned long size) +{ + return __ioremap(physaddr, size, IOMAP_WRITETHROUGH); +} + +#define ioremap_fillcache ioremap_fullcache +static inline void __iomem *ioremap_fullcache(unsigned long physaddr, + unsigned long size) +{ + return __ioremap(physaddr, size, IOMAP_FULL_CACHING); +} + +static inline void memset_io(volatile void __iomem *addr, unsigned char val, + int count) +{ + __builtin_memset((void __force *) addr, val, count); +} + +static inline void memcpy_fromio(void *dst, const volatile void __iomem *src, + int count) +{ + __builtin_memcpy(dst, (void __force *) src, count); +} + +static inline void memcpy_toio(volatile void __iomem *dst, const void *src, + int count) +{ + __builtin_memcpy((void __force *) dst, src, count); +} + +#endif /* CONFIG_MMU */ + +#define ioport_map ioport_map +static inline void __iomem *ioport_map(unsigned long port, unsigned int nr) +{ + return (void __iomem *) port; +} + +#define ioport_unmap ioport_unmap +static inline void ioport_unmap(void __iomem *p) +{ +} + +#endif /* _KMAP_H */ diff --git a/arch/m68k/include/asm/nubus.h b/arch/m68k/include/asm/nubus.h index d0d2039e434e..c2281da6c51a 100644 --- a/arch/m68k/include/asm/nubus.h +++ b/arch/m68k/include/asm/nubus.h @@ -3,6 +3,7 @@ #define _ASM_M68K_NUBUS_H #include +#include #define nubus_readb raw_inb #define nubus_readw raw_inw diff --git a/arch/m68k/include/asm/q40_master.h b/arch/m68k/include/asm/q40_master.h index 3a89c088800c..9b00fb8079e6 100644 --- a/arch/m68k/include/asm/q40_master.h +++ b/arch/m68k/include/asm/q40_master.h @@ -8,7 +8,7 @@ #define _Q40_MASTER_H #include - +#include #define q40_master_addr 0xff000000 diff --git a/arch/m68k/include/asm/raw_io.h b/arch/m68k/include/asm/raw_io.h index 05e940c29b54..85761255dde5 100644 --- a/arch/m68k/include/asm/raw_io.h +++ b/arch/m68k/include/asm/raw_io.h @@ -13,20 +13,6 @@ #include - -/* Values for nocacheflag and cmode */ -#define IOMAP_FULL_CACHING 0 -#define IOMAP_NOCACHE_SER 1 -#define IOMAP_NOCACHE_NONSER 2 -#define IOMAP_WRITETHROUGH 3 - -extern void iounmap(void __iomem *addr); - -extern void __iomem *__ioremap(unsigned long physaddr, unsigned long size, - int cacheflag); -extern void __iounmap(void *addr, unsigned long size); - - /* ++roman: The assignments to temp. vars avoid that gcc sometimes generates * two accesses to memory, which may be undesirable for some devices. */ diff --git a/arch/m68k/include/asm/vga.h b/arch/m68k/include/asm/vga.h index 010a624d1b39..819d46d91886 100644 --- a/arch/m68k/include/asm/vga.h +++ b/arch/m68k/include/asm/vga.h @@ -3,6 +3,7 @@ #define _ASM_M68K_VGA_H #include +#include /* * FIXME diff --git a/arch/m68k/include/asm/zorro.h b/arch/m68k/include/asm/zorro.h index 96f64bf7bcaa..60fc4b6f294d 100644 --- a/arch/m68k/include/asm/zorro.h +++ b/arch/m68k/include/asm/zorro.h @@ -3,6 +3,7 @@ #define _ASM_M68K_ZORRO_H #include +#include #define z_readb raw_inb #define z_readw raw_inw From 927c28c252dc4c0c9c4ca9fcfcfad9e70a555298 Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Sun, 25 Mar 2018 22:29:51 +1000 Subject: [PATCH 06/14] m68k: setup PCI support code in io_no.h Ultimately we want the ColdFire IO access support to be consisent no matter whether it is configured with MMU enabled or disabled. To acheive that we need to get all the ColdFire IO access support code together in one place, in this case io_no.h. The last big piece not in io_no.h is the PCI bus support functions. Define the IO mapping addresses required to use the asm-generic IO access functions. They can provide everything we need - no need for us to duplicate or have local in/out or read/write access functions. Note that this support is not active yet, since we haven't done the full switch over to using the asm-generic functions yet. And also note that we do not yet remove the old PCI functions from io_mm.h yet. Consolodating all this IO access support in a single place will make it easier in the future to enable PCI bus support for non-MMU enabled ColdFire (which we currently cannot do). Signed-off-by: Greg Ungerer Reviewed-by: Angelo Dureghello Tested-by: Angelo Dureghello --- arch/m68k/include/asm/io_no.h | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/arch/m68k/include/asm/io_no.h b/arch/m68k/include/asm/io_no.h index e9c70f754e02..42d61d4f4b86 100644 --- a/arch/m68k/include/asm/io_no.h +++ b/arch/m68k/include/asm/io_no.h @@ -18,6 +18,35 @@ #define __raw_writew(b, addr) (void)((*(volatile unsigned short *) (addr)) = (b)) #define __raw_writel(b, addr) (void)((*(volatile unsigned int *) (addr)) = (b)) +#if defined(CONFIG_PCI) && defined(CONFIG_COLDFIRE) +/* + * Support for PCI bus access uses the asm-generic access functions. + * We need to supply the base address and masks for the normal memory + * and IO address space mappings. + */ +#include +#include +#include + +#define PCI_MEM_PA 0xf0000000 /* Host physical address */ +#define PCI_MEM_BA 0xf0000000 /* Bus physical address */ +#define PCI_MEM_SIZE 0x08000000 /* 128 MB */ +#define PCI_MEM_MASK (PCI_MEM_SIZE - 1) + +#define PCI_IO_PA 0xf8000000 /* Host physical address */ +#define PCI_IO_BA 0x00000000 /* Bus physical address */ +#define PCI_IO_SIZE 0x00010000 /* 64k */ +#define PCI_IO_MASK (PCI_IO_SIZE - 1) + +#define HAVE_ARCH_PIO_SIZE +#define PIO_OFFSET 0 +#define PIO_MASK 0xffff +#define PIO_RESERVED 0x10000 +#define PCI_IOBASE ((void __iomem *) PCI_IO_PA) +#define PCI_SPACE_LIMIT PCI_IO_MASK + +#else + #define readb __raw_readb #define readw __raw_readw #define readl __raw_readl @@ -25,6 +54,8 @@ #define writew __raw_writew #define writel __raw_writel +#endif /* CONFIG_PCI && CONFIG_COLDFIRE */ + /* * These are defined in kmap.h as static inline functions. To maintain * previous behavior we put these define guards here so io_mm.h doesn't From dfbc5cb39928c872c299f4718674e3f1215b07ae Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Sun, 25 Mar 2018 22:37:11 +1000 Subject: [PATCH 07/14] m68k: use io_no.h for MMU and non-MMU enabled ColdFire Use the io_no.h IO access support for all ColdFire systems, no matter whether configured with MMU enabled or disabled. Previously there was subtle differences in IO access functions used in both cases, and these resulted in broken behavior for some drivers. As observed and reported by Angelo when using MMU enabled systems the read/write family of functions was using little endian access, while the non-MMU enabled systems were using native endian. This results in drivers that are shared across Freescale processors (for some of the common internal SoC peripherals) not working - since they are wired up for native endian access. This problem brings to light issues with PCI bus access and local peripheral access - but these are not addressed with this fix. Reported-by: Angelo Dureghello Signed-off-by: Greg Ungerer Reviewed-by: Angelo Dureghello Tested-by: Angelo Dureghello --- arch/m68k/include/asm/io.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/m68k/include/asm/io.h b/arch/m68k/include/asm/io.h index 00b45155969c..ca2849afb087 100644 --- a/arch/m68k/include/asm/io.h +++ b/arch/m68k/include/asm/io.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0 */ -#ifdef __uClinux__ +#if defined(__uClinux__) || defined(CONFIG_COLDFIRE) #include #else #include From de25cfcb6404a0370067bbadaf13122f15464459 Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Sun, 25 Mar 2018 22:50:00 +1000 Subject: [PATCH 08/14] m68k: remove old ColdFire IO access support code All the ColdFire IO access support code has been moved to io_no.h. This means that all ColdFire support is at least now consistent no matter whether the MMU is enabled or not for them. Now that io_mm.h has reverted to only support the traditional m68k MMU enabled processors we can remove the ColdFire specific definitions. We can also remove the old ColdFire PCI bus IO access functions. The new io_no.h uses asm-generic/io.h to provide all the basic support. Signed-off-by: Greg Ungerer Reviewed-by: Angelo Dureghello Tested-by: Angelo Dureghello --- arch/m68k/coldfire/pci.c | 99 ++--------------------------------- arch/m68k/include/asm/io_mm.h | 51 +----------------- 2 files changed, 5 insertions(+), 145 deletions(-) diff --git a/arch/m68k/coldfire/pci.c b/arch/m68k/coldfire/pci.c index 3097fa2ca746..db709ad30f88 100644 --- a/arch/m68k/coldfire/pci.c +++ b/arch/m68k/coldfire/pci.c @@ -23,20 +23,10 @@ /* * Memory and IO mappings. We use a 1:1 mapping for local host memory to - * PCI bus memory (no reason not to really). IO space doesn't matter, we - * always use access functions for that. The device configuration space is - * mapped over the IO map space when we enable it in the PCICAR register. + * PCI bus memory (no reason not to really). IO space is mapped in its own + * separate address region. The device configuration space is mapped over + * the IO map space when we enable it in the PCICAR register. */ -#define PCI_MEM_PA 0xf0000000 /* Host physical address */ -#define PCI_MEM_BA 0xf0000000 /* Bus physical address */ -#define PCI_MEM_SIZE 0x08000000 /* 128 MB */ -#define PCI_MEM_MASK (PCI_MEM_SIZE - 1) - -#define PCI_IO_PA 0xf8000000 /* Host physical address */ -#define PCI_IO_BA 0x00000000 /* Bus physical address */ -#define PCI_IO_SIZE 0x00010000 /* 64k */ -#define PCI_IO_MASK (PCI_IO_SIZE - 1) - static struct pci_bus *rootbus; static unsigned long iospace; @@ -143,89 +133,6 @@ static struct pci_ops mcf_pci_ops = { .write = mcf_pci_writeconfig, }; -/* - * IO address space access functions. Pretty strait forward, these are - * directly mapped in to the IO mapping window. And that is mapped into - * virtual address space. - */ -u8 mcf_pci_inb(u32 addr) -{ - return __raw_readb(iospace + (addr & PCI_IO_MASK)); -} -EXPORT_SYMBOL(mcf_pci_inb); - -u16 mcf_pci_inw(u32 addr) -{ - return le16_to_cpu(__raw_readw(iospace + (addr & PCI_IO_MASK))); -} -EXPORT_SYMBOL(mcf_pci_inw); - -u32 mcf_pci_inl(u32 addr) -{ - return le32_to_cpu(__raw_readl(iospace + (addr & PCI_IO_MASK))); -} -EXPORT_SYMBOL(mcf_pci_inl); - -void mcf_pci_insb(u32 addr, u8 *buf, u32 len) -{ - for (; len; len--) - *buf++ = mcf_pci_inb(addr); -} -EXPORT_SYMBOL(mcf_pci_insb); - -void mcf_pci_insw(u32 addr, u16 *buf, u32 len) -{ - for (; len; len--) - *buf++ = mcf_pci_inw(addr); -} -EXPORT_SYMBOL(mcf_pci_insw); - -void mcf_pci_insl(u32 addr, u32 *buf, u32 len) -{ - for (; len; len--) - *buf++ = mcf_pci_inl(addr); -} -EXPORT_SYMBOL(mcf_pci_insl); - -void mcf_pci_outb(u8 v, u32 addr) -{ - __raw_writeb(v, iospace + (addr & PCI_IO_MASK)); -} -EXPORT_SYMBOL(mcf_pci_outb); - -void mcf_pci_outw(u16 v, u32 addr) -{ - __raw_writew(cpu_to_le16(v), iospace + (addr & PCI_IO_MASK)); -} -EXPORT_SYMBOL(mcf_pci_outw); - -void mcf_pci_outl(u32 v, u32 addr) -{ - __raw_writel(cpu_to_le32(v), iospace + (addr & PCI_IO_MASK)); -} -EXPORT_SYMBOL(mcf_pci_outl); - -void mcf_pci_outsb(u32 addr, const u8 *buf, u32 len) -{ - for (; len; len--) - mcf_pci_outb(*buf++, addr); -} -EXPORT_SYMBOL(mcf_pci_outsb); - -void mcf_pci_outsw(u32 addr, const u16 *buf, u32 len) -{ - for (; len; len--) - mcf_pci_outw(*buf++, addr); -} -EXPORT_SYMBOL(mcf_pci_outsw); - -void mcf_pci_outsl(u32 addr, const u32 *buf, u32 len) -{ - for (; len; len--) - mcf_pci_outl(*buf++, addr); -} -EXPORT_SYMBOL(mcf_pci_outsl); - /* * Initialize the PCI bus registers, and scan the bus. */ diff --git a/arch/m68k/include/asm/io_mm.h b/arch/m68k/include/asm/io_mm.h index 21fba26f57f4..fe485f4f5fac 100644 --- a/arch/m68k/include/asm/io_mm.h +++ b/arch/m68k/include/asm/io_mm.h @@ -86,53 +86,7 @@ #endif /* ATARI_ROM_ISA */ -#if defined(CONFIG_PCI) && defined(CONFIG_COLDFIRE) - -#define HAVE_ARCH_PIO_SIZE -#define PIO_OFFSET 0 -#define PIO_MASK 0xffff -#define PIO_RESERVED 0x10000 - -u8 mcf_pci_inb(u32 addr); -u16 mcf_pci_inw(u32 addr); -u32 mcf_pci_inl(u32 addr); -void mcf_pci_insb(u32 addr, u8 *buf, u32 len); -void mcf_pci_insw(u32 addr, u16 *buf, u32 len); -void mcf_pci_insl(u32 addr, u32 *buf, u32 len); - -void mcf_pci_outb(u8 v, u32 addr); -void mcf_pci_outw(u16 v, u32 addr); -void mcf_pci_outl(u32 v, u32 addr); -void mcf_pci_outsb(u32 addr, const u8 *buf, u32 len); -void mcf_pci_outsw(u32 addr, const u16 *buf, u32 len); -void mcf_pci_outsl(u32 addr, const u32 *buf, u32 len); - -#define inb mcf_pci_inb -#define inb_p mcf_pci_inb -#define inw mcf_pci_inw -#define inw_p mcf_pci_inw -#define inl mcf_pci_inl -#define inl_p mcf_pci_inl -#define insb mcf_pci_insb -#define insw mcf_pci_insw -#define insl mcf_pci_insl - -#define outb mcf_pci_outb -#define outb_p mcf_pci_outb -#define outw mcf_pci_outw -#define outw_p mcf_pci_outw -#define outl mcf_pci_outl -#define outl_p mcf_pci_outl -#define outsb mcf_pci_outsb -#define outsw mcf_pci_outsw -#define outsl mcf_pci_outsl - -#define readb(addr) in_8(addr) -#define writeb(v, addr) out_8((addr), (v)) -#define readw(addr) in_le16(addr) -#define writew(v, addr) out_le16((addr), (v)) - -#elif defined(CONFIG_ISA) || defined(CONFIG_ATARI_ROM_ISA) +#if defined(CONFIG_ISA) || defined(CONFIG_ATARI_ROM_ISA) #if MULTI_ISA == 0 #undef MULTI_ISA @@ -415,8 +369,7 @@ static inline void isa_delay(void) #define writew(val, addr) out_le16((addr), (val)) #endif /* CONFIG_ATARI_ROM_ISA */ -#if !defined(CONFIG_ISA) && !defined(CONFIG_ATARI_ROM_ISA) && \ - !(defined(CONFIG_PCI) && defined(CONFIG_COLDFIRE)) +#if !defined(CONFIG_ISA) && !defined(CONFIG_ATARI_ROM_ISA) /* * We need to define dummy functions for GENERIC_IOMAP support. */ From df8f77dec74319794eff9a93d68ada7998b0d510 Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Mon, 26 Mar 2018 12:35:18 +1000 Subject: [PATCH 09/14] m68k: don't redefine access functions if we have PCI Some ColdFire platforms do have real PCI buses, so we should not be re-defining or otherwise mangling the IO access functions for them. So when CONFIG_PCI is true use the real io.h support. Signed-off-by: Greg Ungerer Reviewed-by: Angelo Dureghello Tested-by: Angelo Dureghello --- arch/m68k/include/asm/vga.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/arch/m68k/include/asm/vga.h b/arch/m68k/include/asm/vga.h index 819d46d91886..4742e6bc3ab8 100644 --- a/arch/m68k/include/asm/vga.h +++ b/arch/m68k/include/asm/vga.h @@ -2,6 +2,13 @@ #ifndef _ASM_M68K_VGA_H #define _ASM_M68K_VGA_H +/* + * Some ColdFire platforms do in fact have a PCI bus. So for those we want + * to use the real IO access functions, don't fake them out or redirect them + * for that case. + */ +#ifndef CONFIG_PCI + #include #include @@ -26,4 +33,5 @@ #define writeb raw_outb #define writew raw_outw +#endif /* CONFIG_PCI */ #endif /* _ASM_M68K_VGA_H */ From 4d53037876277fbba10f47de7b90d3a873c5d12b Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Fri, 30 Mar 2018 23:40:31 +1000 Subject: [PATCH 10/14] m68k: fix read/write multi-byte IO for PCI on ColdFire We need to treat built-in peripherals and bus based address ranges differently. Local built-in peripherals (and the ColdFire SoC parts have quite a lot of them) are always native endian - which is big endian on m68k/ColdFire. Bus based address ranges, like the PCI bus, are accessed little endian - so we need to byte swap those. So implement readw/writew and readl/writel functions to deal with memory mapped accesses correctly based on the address range being accessed. This fixes readw/writew and readl/writel so that they can be used in drivers for native SoC hardware modules (many of which are shared with other architectures (ARM in Freescale SoC parts for example). And also drivers for PCI devices. Signed-off-by: Greg Ungerer Tested-by: Angelo Dureghello --- arch/m68k/include/asm/io_no.h | 101 ++++++++++++++++++++++++++++------ 1 file changed, 85 insertions(+), 16 deletions(-) diff --git a/arch/m68k/include/asm/io_no.h b/arch/m68k/include/asm/io_no.h index 42d61d4f4b86..ccb8c31faf49 100644 --- a/arch/m68k/include/asm/io_no.h +++ b/arch/m68k/include/asm/io_no.h @@ -18,16 +18,95 @@ #define __raw_writew(b, addr) (void)((*(volatile unsigned short *) (addr)) = (b)) #define __raw_writel(b, addr) (void)((*(volatile unsigned int *) (addr)) = (b)) -#if defined(CONFIG_PCI) && defined(CONFIG_COLDFIRE) +#if defined(CONFIG_COLDFIRE) +/* + * For ColdFire platforms we may need to do some extra checks for what + * type of address range we are accessing. Include the ColdFire platform + * definitions so we can figure out if need to do something special. + */ +#include +#include +#include +#endif /* CONFIG_COLDFIRE */ + +#if defined(IOMEMBASE) +/* + * 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. We can quickly + * determine if we are accessing an internal peripheral device given the + * physical or vitrual address using the same range check. This check logic + * applies just the same of there is no MMU but something like a PCI bus + * is present. + */ +static int __cf_internalio(unsigned long addr) +{ + return (addr >= IOMEMBASE) && (addr <= IOMEMBASE + IOMEMSIZE - 1); +} + +static int cf_internalio(const volatile void __iomem *addr) +{ + return __cf_internalio((unsigned long) addr); +} + +/* + * We need to treat built-in peripherals and bus based address ranges + * differently. Local built-in peripherals (and the ColdFire SoC parts + * have quite a lot of them) are always native endian - which is big + * endian on m68k/ColdFire. Bus based address ranges, like the PCI bus, + * are accessed little endian - so we need to byte swap those. + */ +#define readw readw +static inline u16 readw(const volatile void __iomem *addr) +{ + if (cf_internalio(addr)) + return __raw_readw(addr); + return __le16_to_cpu(__raw_readw(addr)); +} + +#define readl readl +static inline u32 readl(const volatile void __iomem *addr) +{ + if (cf_internalio(addr)) + return __raw_readl(addr); + return __le32_to_cpu(__raw_readl(addr)); +} + +#define writew writew +static inline void writew(u16 value, volatile void __iomem *addr) +{ + if (cf_internalio(addr)) + __raw_writew(value, addr); + else + __raw_writew(__cpu_to_le16(value), addr); +} + +#define writel writel +static inline void writel(u32 value, volatile void __iomem *addr) +{ + if (cf_internalio(addr)) + __raw_writel(value, addr); + else + __raw_writel(__cpu_to_le32(value), addr); +} + +#else + +#define readb __raw_readb +#define readw __raw_readw +#define readl __raw_readl +#define writeb __raw_writeb +#define writew __raw_writew +#define writel __raw_writel + +#endif /* IOMEMBASE */ + +#if defined(CONFIG_PCI) /* * Support for PCI bus access uses the asm-generic access functions. * We need to supply the base address and masks for the normal memory * and IO address space mappings. */ -#include -#include -#include - #define PCI_MEM_PA 0xf0000000 /* Host physical address */ #define PCI_MEM_BA 0xf0000000 /* Bus physical address */ #define PCI_MEM_SIZE 0x08000000 /* 128 MB */ @@ -44,17 +123,7 @@ #define PIO_RESERVED 0x10000 #define PCI_IOBASE ((void __iomem *) PCI_IO_PA) #define PCI_SPACE_LIMIT PCI_IO_MASK - -#else - -#define readb __raw_readb -#define readw __raw_readw -#define readl __raw_readl -#define writeb __raw_writeb -#define writew __raw_writew -#define writel __raw_writel - -#endif /* CONFIG_PCI && CONFIG_COLDFIRE */ +#endif /* CONFIG_PCI */ /* * These are defined in kmap.h as static inline functions. To maintain From be39cbcbd6cc94ed0e6daf3637cc092641254cf3 Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Thu, 5 Apr 2018 23:55:11 +1000 Subject: [PATCH 11/14] 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 Signed-off-by: Greg Ungerer Reviewed-by: Angelo Dureghello Tested-by: Angelo Dureghello --- arch/m68k/mm/kmap.c | 8 ++++++++ 1 file changed, 8 insertions(+) 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 } From 4a2e130cce1f6ad1b70f0fa8ca1852377fc285ae Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Mon, 2 Apr 2018 23:28:52 +1000 Subject: [PATCH 12/14] m68k: allow ColdFire PCI bus on MMU and non-MMU configuration Up to now we have only had support for the PCI bus when running the ColdFire CPU family with the MMU enabled. The only reason for this was the incomplete state of the IO remapping and access functions when running with the MMU disabled. Recent fixes and improvements to the ColdFire IO access code means we can now support the PCI bus when running non-MMU enabled as well. So modify the configuration support to allow it to be selected no matter what choice of MMU mode is used. Signed-off-by: Greg Ungerer Reviewed-by: Angelo Dureghello Tested-by: Angelo Dureghello --- arch/m68k/Kconfig.bus | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/arch/m68k/Kconfig.bus b/arch/m68k/Kconfig.bus index d5e66ec136db..aef698fa50e5 100644 --- a/arch/m68k/Kconfig.bus +++ b/arch/m68k/Kconfig.bus @@ -59,6 +59,10 @@ config ATARI_ROM_ISA config GENERIC_ISA_DMA def_bool ISA +source "drivers/zorro/Kconfig" + +endif + config PCI bool "PCI support" depends on M54xx @@ -66,10 +70,8 @@ config PCI Enable the PCI bus. Support for the PCI bus hardware built into the ColdFire 547x and 548x processors. +if PCI source "drivers/pci/Kconfig" - -source "drivers/zorro/Kconfig" - endif if !MMU From 48074d2615add385e6357fc1333959fc778557f9 Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Sun, 8 Apr 2018 23:12:55 +1000 Subject: [PATCH 13/14] m68k: introduce iomem() macro for __iomem conversions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A lot of the ColdFire internal peripherals (clocks, timers, interrupt controllers, etc) are addressed using constants. The only problem with that is they are not type clean when used with __raw_read/__raw_write and read/write - they should be of type "void __iomem". This isn't a problem currently because the IO access functions are local macros. To switch to using the asm-generic implementations of these we need to clean up the types. Otherwise you get warnings like this: In file included from ./arch/m68k/include/asm/mcfsim.h:24:0, from arch/m68k/coldfire/intc-simr.c:20: arch/m68k/coldfire/intc-simr.c: In function ‘init_IRQ’: ./arch/m68k/include/asm/m520xsim.h:40:29: warning: passing argument 2 of ‘__raw_writeb’ makes pointer from integer without a cast [-Wint-conversion] #define MCFINTC0_SIMR (MCFICM_INTC0 + MCFINTC_SIMR) ^ arch/m68k/coldfire/intc-simr.c:182:21: note: in expansion of macro ‘MCFINTC0_SIMR’ __raw_writeb(0xff, MCFINTC0_SIMR); ^ In file included from ./arch/m68k/include/asm/io_no.h:120:0, from ./arch/m68k/include/asm/io.h:3, from ./include/linux/io.h:25, from ./include/linux/irq.h:25, from ./include/asm-generic/hardirq.h:13, from ./arch/m68k/include/asm/hardirq.h:25, from ./include/linux/hardirq.h:9, from ./include/linux/interrupt.h:13, from arch/m68k/coldfire/intc-simr.c:16: ./include/asm-generic/io.h:71:22: note: expected ‘volatile void *’ but argument is of type ‘unsigned int’ #define __raw_writeb __raw_writeb ^ ./include/asm-generic/io.h:72:20: note: in expansion of macro ‘__raw_writeb’ static inline void __raw_writeb(u8 value, volatile void __iomem *addr) ^ To start this clean up process introduce a macro, iomem(), that converts a constant address to the correct "void __iomem *" type. Signed-off-by: Greg Ungerer Tested-by: Angelo Dureghello --- arch/m68k/include/asm/io_no.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/m68k/include/asm/io_no.h b/arch/m68k/include/asm/io_no.h index ccb8c31faf49..83a0a6d449f4 100644 --- a/arch/m68k/include/asm/io_no.h +++ b/arch/m68k/include/asm/io_no.h @@ -2,6 +2,12 @@ #ifndef _M68KNOMMU_IO_H #define _M68KNOMMU_IO_H +/* + * Convert a physical memory address into a IO memory address. + * For us this is trivially a type cast. + */ +#define iomem(a) ((void __iomem *) (a)) + /* * The non-MMU m68k and ColdFire IO and memory mapped hardware access * functions have always worked in CPU native endian. We need to define From 082f55c459845088c3fee99c3a88ee117c148218 Mon Sep 17 00:00:00 2001 From: Greg Ungerer Date: Wed, 11 Apr 2018 13:39:44 +1000 Subject: [PATCH 14/14] m68k: fix ColdFire PCI config reads and writes The ColdFire PCI configuration space access functions swap addressing regions to do their work. Just letting the read/write cycles exit the CPU core (via the ColdFire "nop" instruction) is not enough to guarantee that the address region remapping has actually completed. Insert a read back of the mapping register to be absolutely sure that the remapping has completed. This fixes an occasional boot hang during the ColdFire PCI initialization phase. Signed-off-by: Greg Ungerer Reviewed-by: Angelo Dureghello Tested-by: Angelo Dureghello --- arch/m68k/coldfire/pci.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/arch/m68k/coldfire/pci.c b/arch/m68k/coldfire/pci.c index db709ad30f88..62b0eb6cf69a 100644 --- a/arch/m68k/coldfire/pci.c +++ b/arch/m68k/coldfire/pci.c @@ -46,13 +46,6 @@ static unsigned char mcf_host_irq[] = { 0, 69, 69, 71, 71, }; - -static inline void syncio(void) -{ - /* The ColdFire "nop" instruction waits for all bus IO to complete */ - __asm__ __volatile__ ("nop"); -} - /* * Configuration space access functions. Configuration space access is * through the IO mapping window, enabling it via the PCICAR register. @@ -74,9 +67,9 @@ static int mcf_pci_readconfig(struct pci_bus *bus, unsigned int devfn, return PCIBIOS_SUCCESSFUL; } - syncio(); addr = mcf_mk_pcicar(bus->number, devfn, where); __raw_writel(PCICAR_E | addr, PCICAR); + __raw_readl(PCICAR); addr = iospace + (where & 0x3); switch (size) { @@ -91,8 +84,8 @@ static int mcf_pci_readconfig(struct pci_bus *bus, unsigned int devfn, break; } - syncio(); __raw_writel(0, PCICAR); + __raw_readl(PCICAR); return PCIBIOS_SUCCESSFUL; } @@ -106,9 +99,9 @@ static int mcf_pci_writeconfig(struct pci_bus *bus, unsigned int devfn, return PCIBIOS_SUCCESSFUL; } - syncio(); addr = mcf_mk_pcicar(bus->number, devfn, where); __raw_writel(PCICAR_E | addr, PCICAR); + __raw_readl(PCICAR); addr = iospace + (where & 0x3); switch (size) { @@ -123,8 +116,8 @@ static int mcf_pci_writeconfig(struct pci_bus *bus, unsigned int devfn, break; } - syncio(); __raw_writel(0, PCICAR); + __raw_readl(PCICAR); return PCIBIOS_SUCCESSFUL; }