Message ID | 20210215121713.57687-11-marcan@marcan.st (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Apple M1 SoC platform bring-up | expand |
Hi Hector, I love your patch! Yet something to improve: [auto build test ERROR on arm64/for-next/core] [also build test ERROR on robh/for-next tty/tty-testing linus/master v5.11 next-20210212] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch] url: https://github.com/0day-ci/linux/commits/Hector-Martin/Apple-M1-SoC-platform-bring-up/20210215-202520 base: https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git for-next/core config: mips-randconfig-r002-20210215 (attached as .config) compiler: mips64-linux-gcc (GCC) 9.3.0 reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # https://github.com/0day-ci/linux/commit/9785be3c8ec6cb8530d72cff794f5c22414f5a3e git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review Hector-Martin/Apple-M1-SoC-platform-bring-up/20210215-202520 git checkout 9785be3c8ec6cb8530d72cff794f5c22414f5a3e # save the attached .config to linux build tree COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=mips If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot <lkp@intel.com> All errors (new ones prefixed by >>): lib/devres.c: In function '__devm_ioremap': >> lib/devres.c:47:10: error: implicit declaration of function 'ioremap_np'; did you mean 'ioremap_uc'? [-Werror=implicit-function-declaration] 47 | addr = ioremap_np(offset, size); | ^~~~~~~~~~ | ioremap_uc lib/devres.c:47:8: warning: assignment to 'void *' from 'int' makes pointer from integer without a cast [-Wint-conversion] 47 | addr = ioremap_np(offset, size); | ^ cc1: some warnings being treated as errors vim +47 lib/devres.c 25 26 static void __iomem *__devm_ioremap(struct device *dev, resource_size_t offset, 27 resource_size_t size, 28 enum devm_ioremap_type type) 29 { 30 void __iomem **ptr, *addr = NULL; 31 32 ptr = devres_alloc(devm_ioremap_release, sizeof(*ptr), GFP_KERNEL); 33 if (!ptr) 34 return NULL; 35 36 switch (type) { 37 case DEVM_IOREMAP: 38 addr = ioremap(offset, size); 39 break; 40 case DEVM_IOREMAP_UC: 41 addr = ioremap_uc(offset, size); 42 break; 43 case DEVM_IOREMAP_WC: 44 addr = ioremap_wc(offset, size); 45 break; 46 case DEVM_IOREMAP_NP: > 47 addr = ioremap_np(offset, size); 48 break; 49 } 50 51 if (addr) { 52 *ptr = addr; 53 devres_add(dev, ptr); 54 } else 55 devres_free(ptr); 56 57 return addr; 58 } 59 --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
On 16/02/2021 00.27, kernel test robot wrote: > config: mips-randconfig-r002-20210215 (attached as .config) > compiler: mips64-linux-gcc (GCC) 9.3.0 >>> lib/devres.c:47:10: error: implicit declaration of function 'ioremap_np'; did you mean 'ioremap_uc'? [-Werror=implicit-function-declaration] Well, today I learned that some architectures, like mips, only include asm-generic/iomap.h, not asm-generic/io.h... and one, sparc64, includes neither. That's unfortunate. I added the missing bit to iomap.h, and a one-off patch to arch/sparc/include/asm/io_64.h: diff --git a/arch/sparc/include/asm/io_64.h b/arch/sparc/include/asm/io_64.h index 9bb27e5c22f1..35470d275ddc 100644 --- a/arch/sparc/include/asm/io_64.h +++ b/arch/sparc/include/asm/io_64.h @@ -409,6 +409,7 @@ static inline void __iomem *ioremap(unsigned long offset, unsigned long size) #define ioremap_uc(X,Y) ioremap((X),(Y)) #define ioremap_wc(X,Y) ioremap((X),(Y)) #define ioremap_wt(X,Y) ioremap((X),(Y)) +#define ioremap_np(X,Y) ioremap((X),(Y)) static inline void iounmap(volatile void __iomem *addr) { David, is this okay? This series is headed for the soc tree, but I wasn't expecting to have to touch arch-specific code for anything but arm... you can see the rest of it here: https://lore.kernel.org/linux-arm-kernel/YCqdi%2F5TSlbt0w%2F2@kroah.com/T/ I'll CC you on v3 if this works for you.
Your new iomremap variant needs proper documentation explaining the semantics in detail.
On 16/02/2021 19.53, Christoph Hellwig wrote: > Your new iomremap variant needs proper documentation explaining the > semantics in detail. What's the right place for this? I haven't found any generic ioremap documentation page in the tree yet. I suppose I could write an ARM64-specific blurb on IO mapping modes, much like x86 has one...
diff --git a/include/asm-generic/io.h b/include/asm-generic/io.h index c6af40ce03be..43e4bb8d633c 100644 --- a/include/asm-generic/io.h +++ b/include/asm-generic/io.h @@ -942,7 +942,9 @@ static inline void *phys_to_virt(unsigned long address) * * ioremap_wc() and ioremap_wt() can provide more relaxed caching attributes * for specific drivers if the architecture choses to implement them. If they - * are not implemented we fall back to plain ioremap. + * are not implemented we fall back to plain ioremap. Conversely, ioremap_np() + * can provide stricter non-posted write semantics if the architecture + * implements them. */ #ifndef CONFIG_MMU #ifndef ioremap @@ -980,6 +982,10 @@ static inline void __iomem *ioremap(phys_addr_t addr, size_t size) #define ioremap_wt ioremap #endif +#ifndef ioremap_np +#define ioremap_np ioremap +#endif + /* * ioremap_uc is special in that we do require an explicit architecture * implementation. In general you do not want to use this function in a diff --git a/include/linux/io.h b/include/linux/io.h index 8394c56babc2..d718354ed3e1 100644 --- a/include/linux/io.h +++ b/include/linux/io.h @@ -68,6 +68,8 @@ void __iomem *devm_ioremap_uc(struct device *dev, resource_size_t offset, resource_size_t size); void __iomem *devm_ioremap_wc(struct device *dev, resource_size_t offset, resource_size_t size); +void __iomem *devm_ioremap_np(struct device *dev, resource_size_t offset, + resource_size_t size); void devm_iounmap(struct device *dev, void __iomem *addr); int check_signature(const volatile void __iomem *io_addr, const unsigned char *signature, int length); diff --git a/include/linux/ioport.h b/include/linux/ioport.h index fe48b7840665..5929a67570ae 100644 --- a/include/linux/ioport.h +++ b/include/linux/ioport.h @@ -108,6 +108,7 @@ struct resource { #define IORESOURCE_MEM_32BIT (3<<3) #define IORESOURCE_MEM_SHADOWABLE (1<<5) /* dup: IORESOURCE_SHADOWABLE */ #define IORESOURCE_MEM_EXPANSIONROM (1<<6) +#define IORESOURCE_MEM_NONPOSTED (1<<7) /* PnP I/O specific bits (IORESOURCE_BITS) */ #define IORESOURCE_IO_16BIT_ADDR (1<<0) diff --git a/lib/devres.c b/lib/devres.c index 2a4ff5d64288..4679dbb1bf5f 100644 --- a/lib/devres.c +++ b/lib/devres.c @@ -10,6 +10,7 @@ enum devm_ioremap_type { DEVM_IOREMAP = 0, DEVM_IOREMAP_UC, DEVM_IOREMAP_WC, + DEVM_IOREMAP_NP, }; void devm_ioremap_release(struct device *dev, void *res) @@ -42,6 +43,9 @@ static void __iomem *__devm_ioremap(struct device *dev, resource_size_t offset, case DEVM_IOREMAP_WC: addr = ioremap_wc(offset, size); break; + case DEVM_IOREMAP_NP: + addr = ioremap_np(offset, size); + break; } if (addr) { @@ -98,6 +102,21 @@ void __iomem *devm_ioremap_wc(struct device *dev, resource_size_t offset, } EXPORT_SYMBOL(devm_ioremap_wc); +/** + * devm_ioremap_np - Managed ioremap_np() + * @dev: Generic device to remap IO address for + * @offset: Resource address to map + * @size: Size of map + * + * Managed ioremap_np(). Map is automatically unmapped on driver detach. + */ +void __iomem *devm_ioremap_np(struct device *dev, resource_size_t offset, + resource_size_t size) +{ + return __devm_ioremap(dev, offset, size, DEVM_IOREMAP_NP); +} +EXPORT_SYMBOL(devm_ioremap_np); + /** * devm_iounmap - Managed iounmap() * @dev: Generic device to unmap for @@ -128,6 +147,9 @@ __devm_ioremap_resource(struct device *dev, const struct resource *res, return IOMEM_ERR_PTR(-EINVAL); } + if (type == DEVM_IOREMAP && res->flags & IORESOURCE_MEM_NONPOSTED) + type = DEVM_IOREMAP_NP; + size = resource_size(res); if (res->name)
ARM64 currently defaults to posted MMIO (nGnRnE), but some devices require the use of non-posted MMIO (nGnRE). Introduce a new ioremap() variant to handle this case. ioremap_np() is aliased to ioremap() by default on arches that do not implement this variant. This adds the IORESOURCE_MEM_NONPOSTED flag, which maps to this variant and marks a given resource as requiring non-posted mappings. This is implemented in the resource system because it is a SoC-level requirement, so existing drivers do not need special-case code to pick this ioremap variant. Then this is implemented in devres by introducing devm_ioremap_np(), and making devm_ioremap_resource() automatically select this variant when the resource has the IORESOURCE_MEM_NONPOSTED flag set. Signed-off-by: Hector Martin <marcan@marcan.st> --- include/asm-generic/io.h | 8 +++++++- include/linux/io.h | 2 ++ include/linux/ioport.h | 1 + lib/devres.c | 22 ++++++++++++++++++++++ 4 files changed, 32 insertions(+), 1 deletion(-)