On Wed, Jun 29, 2005 at 11:55:55AM +0100, Maciej W. Rozycki wrote: > I'd like to get rid of CKSEG1ADDR() wherever possible from code I am > looking after as the macro is unportable and has already proven to cause > maintenance hassle. I don't want to get rid of its advantages though, so > here's an update for ioremap() that makes it be expanded inline when > constant arguments are used and the resulting mapping fits in KSEG1. > Likewise for iounmap(). I don't think I'd complain about taking the whole thing out off line. Last I checked we had no driver that did substancially benefit from being initialized a few nanoseconds faster. > Apparently the generic version is used for all platforms but the Au1000. > I have only implemented the bare minimum required for the platform to keep > working. The platform seems to be maintained though, so I'm leaving the > decision as to whether to inline the platform-specific variation or not up > to the maintainer. So I guess your patch leaves getting rid of that indirection of fixup_bigphys_addr calling into __fixup_bigphys_addr to Pete :-) > OK to apply? Fee free. Ralf > patch-mips-2.6.12-rc4-20050526-ioremap-constant-1 > diff -up --recursive --new-file linux-mips-2.6.12-rc4-20050526.macro/arch/mips/au1000/common/setup.c linux-mips-2.6.12-rc4-20050526/arch/mips/au1000/common/setup.c > --- linux-mips-2.6.12-rc4-20050526.macro/arch/mips/au1000/common/setup.c 2005-04-04 04:56:03.000000000 +0000 > +++ linux-mips-2.6.12-rc4-20050526/arch/mips/au1000/common/setup.c 2005-06-25 23:45:43.000000000 +0000 > @@ -159,7 +159,7 @@ early_initcall(au1x00_setup); > > #if defined(CONFIG_64BIT_PHYS_ADDR) > /* This routine should be valid for all Au1x based boards */ > -phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size) > +phys_t __fixup_bigphys_addr(phys_t phys_addr, phys_t size) > { > u32 start, end; > > diff -up --recursive --new-file linux-mips-2.6.12-rc4-20050526.macro/arch/mips/mm/ioremap.c linux-mips-2.6.12-rc4-20050526/arch/mips/mm/ioremap.c > --- linux-mips-2.6.12-rc4-20050526.macro/arch/mips/mm/ioremap.c 2005-02-11 05:56:05.000000000 +0000 > +++ linux-mips-2.6.12-rc4-20050526/arch/mips/mm/ioremap.c 2005-06-26 00:00:51.000000000 +0000 > @@ -102,15 +102,6 @@ static int remap_area_pages(unsigned lon > } > > /* > - * Allow physical addresses to be fixed up to help 36 bit peripherals. > - */ > -phys_t __attribute__ ((weak)) > -fixup_bigphys_addr(phys_t phys_addr, phys_t size) > -{ > - return phys_addr; > -} > - > -/* > * Generic mapping function (not visible outside): > */ > > diff -up --recursive --new-file linux-mips-2.6.12-rc4-20050526.macro/include/asm-mips/io.h linux-mips-2.6.12-rc4-20050526/include/asm-mips/io.h > --- linux-mips-2.6.12-rc4-20050526.macro/include/asm-mips/io.h 2005-04-19 04:57:17.000000000 +0000 > +++ linux-mips-2.6.12-rc4-20050526/include/asm-mips/io.h 2005-06-26 00:27:00.000000000 +0000 > @@ -26,6 +26,7 @@ > #include <asm/pgtable-bits.h> > #include <asm/processor.h> > > +#include <ioremap.h> > #include <mangle-port.h> > > /* > @@ -208,6 +209,8 @@ extern void __iounmap(volatile void __io > static inline void * __ioremap_mode(phys_t offset, unsigned long size, > unsigned long flags) > { > +#define __IS_LOW512(addr) (!((phys_t)(addr) & (phys_t) ~0x1fffffffULL)) > + > if (cpu_has_64bit_addresses) { > u64 base = UNCAC_BASE; > > @@ -218,9 +221,30 @@ static inline void * __ioremap_mode(phys > if (flags == _CACHE_UNCACHED) > base = (u64) IO_BASE; > return (void *) (unsigned long) (base + offset); > + } else if (__builtin_constant_p(offset) && > + __builtin_constant_p(size) && __builtin_constant_p(flags)) { > + phys_t phys_addr, last_addr; > + > + phys_addr = fixup_bigphys_addr(offset, size); > + > + /* Don't allow wraparound or zero size. */ > + last_addr = phys_addr + size - 1; > + if (!size || last_addr < phys_addr) > + return NULL; > + > + /* > + * Map uncached objects in the low 512MB of address > + * space using KSEG1. > + */ > + if (__IS_LOW512(phys_addr) && __IS_LOW512(last_addr) && > + flags == _CACHE_UNCACHED) > + return (void *)CKSEG1ADDR(phys_addr); > + > } > > return __ioremap(offset, size, flags); > + > +#undef __IS_LOW512 > } > > /* > @@ -272,12 +296,16 @@ static inline void * __ioremap_mode(phys > > static inline void iounmap(volatile void __iomem *addr) > { > - if (cpu_has_64bit_addresses) > +#define __IS_KSEG1(addr) (((unsigned long)(addr) & ~0x1fffffffUL) == CKSEG1) > + > + if (cpu_has_64bit_addresses || > + (__builtin_constant_p(addr) && __IS_KSEG1(addr))) > return; > > __iounmap(addr); > -} > > +#undef __IS_KSEG1 > +} > > #define __BUILD_MEMORY_SINGLE(pfx, bwlq, type, irq) \ > \ > diff -up --recursive --new-file linux-mips-2.6.12-rc4-20050526.macro/include/asm-mips/mach-au1x00/ioremap.h linux-mips-2.6.12-rc4-20050526/include/asm-mips/mach-au1x00/ioremap.h > --- linux-mips-2.6.12-rc4-20050526.macro/include/asm-mips/mach-au1x00/ioremap.h 1970-01-01 00:00:00.000000000 +0000 > +++ linux-mips-2.6.12-rc4-20050526/include/asm-mips/mach-au1x00/ioremap.h 2005-06-26 00:16:26.000000000 +0000 > @@ -0,0 +1,29 @@ > +/* > + * include/asm-mips/mach-au1x00/ioremap.h > + * > + * This program is free software; you can redistribute it and/or > + * modify it under the terms of the GNU General Public License > + * as published by the Free Software Foundation; either version > + * 2 of the License, or (at your option) any later version. > + */ > +#ifndef __ASM_MACH_AU1X00_IOREMAP_H > +#define __ASM_MACH_AU1X00_IOREMAP_H > + > +#include <linux/types.h> > + > +#ifndef CONFIG_64BIT_PHYS_ADDR > +static inline phys_t __fixup_bigphys_addr(phys_t phys_addr, phys_t size) > +{ > + return phys_addr; > +} > +#endif > + > +/* > + * Allow physical addresses to be fixed up to help 36-bit peripherals. > + */ > +static inline phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size) > +{ > + return __fixup_bigphys_addr(phys_addr, size); > +} > + > +#endif /* __ASM_MACH_AU1X00_IOREMAP_H */ > diff -up --recursive --new-file linux-mips-2.6.12-rc4-20050526.macro/include/asm-mips/mach-generic/ioremap.h linux-mips-2.6.12-rc4-20050526/include/asm-mips/mach-generic/ioremap.h > --- linux-mips-2.6.12-rc4-20050526.macro/include/asm-mips/mach-generic/ioremap.h 1970-01-01 00:00:00.000000000 +0000 > +++ linux-mips-2.6.12-rc4-20050526/include/asm-mips/mach-generic/ioremap.h 2005-06-26 00:05:42.000000000 +0000 > @@ -0,0 +1,23 @@ > +/* > + * include/asm-mips/mach-generic/ioremap.h > + * > + * This program is free software; you can redistribute it and/or > + * modify it under the terms of the GNU General Public License > + * as published by the Free Software Foundation; either version > + * 2 of the License, or (at your option) any later version. > + */ > +#ifndef __ASM_MACH_GENERIC_IOREMAP_H > +#define __ASM_MACH_GENERIC_IOREMAP_H > + > +#include <linux/types.h> > + > +/* > + * Allow physical addresses to be fixed up to help peripherals located > + * outside the low 32-bit range -- generic pass-through version. > + */ > +static inline phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size) > +{ > + return phys_addr; > +} > + > +#endif /* __ASM_MACH_GENERIC_IOREMAP_H */