From 30ab2b034fa87472d700f584e277e3aeb7a84d2c Mon Sep 17 00:00:00 2001 From: Jonas Bonn Date: Sat, 2 Jul 2011 10:29:24 +0200 Subject: asm-generic: adapt delay.h to common implementation Several architectures are using a common delay.h implementation that appears to have originated with the x86 architecture. This common implementation is a bit fuller than the current asm-generic version and has some compile-time checks that should be interesting for all architectures. This patch takes the common delay.h version and replaces the rather trivial asm-generic version with it. As no architecture was actually using asm-generic/delay.h, this change is rather innocuous; it will, however, allow us to switch at least four architectures over to using the asm-generic version. Signed-off-by: Jonas Bonn Acked-by: Arnd Bergmann --- include/asm-generic/delay.h | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/asm-generic/delay.h b/include/asm-generic/delay.h index 4586fec75ddb..6511b99c5f17 100644 --- a/include/asm-generic/delay.h +++ b/include/asm-generic/delay.h @@ -1,9 +1,23 @@ #ifndef __ASM_GENERIC_DELAY_H #define __ASM_GENERIC_DELAY_H +/* Undefined functions to get compile-time errors */ +extern void __bad_udelay(void); +extern void __bad_ndelay(void); + extern void __udelay(unsigned long usecs); +extern void __ndelay(unsigned long nsecs); +extern void __const_udelay(unsigned long xloops); extern void __delay(unsigned long loops); -#define udelay(n) __udelay(n) +/* 0x10c7 is 2**32 / 1000000 (rounded up) */ +#define udelay(n) (__builtin_constant_p(n) ? \ + ((n) > 20000 ? __bad_udelay() : __const_udelay((n) * 0x10c7ul)) : \ + __udelay(n)) + +/* 0x5 is 2**32 / 1000000000 (rounded up) */ +#define ndelay(n) (__builtin_constant_p(n) ? \ + ((n) > 20000 ? __bad_ndelay() : __const_udelay((n) * 5ul)) : \ + __ndelay(n)) #endif /* __ASM_GENERIC_DELAY_H */ -- cgit v1.2.3 From a87e553fabe8ceadc6f90889066559234cf194c7 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Mon, 18 Jul 2011 15:28:20 +0200 Subject: asm-generic: delay.h fix udelay and ndelay for 8 bit args With a non-constant 8-bit argument, a call to udelay() generates a warning: drivers/gpu/drm/radeon/atom.c: In function 'atom_op_delay': drivers/gpu/drm/radeon/atom.c:654: warning: comparison is always false due to limited range of data type The code looks like it works OK with an 8-bit arg, and the calling code is doing nothing wrong, so udelay() needs fixing. Fixing it was rather tricky. Simply typecasting `n' in the comparison with 20000 didn't change anything. Hence the divide-by-20000 trick. Using a do{}while loop didn't work because udelay() is used in ?: statements, hence the ({...}) construct. While I was there I replaced the brain-bending ?:?:?: mess with nice if/else code. Probably other architectures are generating the same warning and can use a similar change. [Taken from the x86 tree and moved to asm-generic by Jonas Bonn] Cc: Ingo Molnar Cc: Thomas Gleixner Cc: "H. Peter Anvin" Cc: Signed-off-by: Andrew Morton Signed-off-by: Jonas Bonn --- include/asm-generic/delay.h | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) (limited to 'include') diff --git a/include/asm-generic/delay.h b/include/asm-generic/delay.h index 6511b99c5f17..0f79054ce7cd 100644 --- a/include/asm-generic/delay.h +++ b/include/asm-generic/delay.h @@ -10,14 +10,35 @@ extern void __ndelay(unsigned long nsecs); extern void __const_udelay(unsigned long xloops); extern void __delay(unsigned long loops); +/* + * The weird n/20000 thing suppresses a "comparison is always false due to + * limited range of data type" warning with non-const 8-bit arguments. + */ + /* 0x10c7 is 2**32 / 1000000 (rounded up) */ -#define udelay(n) (__builtin_constant_p(n) ? \ - ((n) > 20000 ? __bad_udelay() : __const_udelay((n) * 0x10c7ul)) : \ - __udelay(n)) +#define udelay(n) \ + ({ \ + if (__builtin_constant_p(n)) { \ + if ((n) / 20000 >= 1) \ + __bad_udelay(); \ + else \ + __const_udelay((n) * 0x10c7ul); \ + } else { \ + __udelay(n); \ + } \ + }) /* 0x5 is 2**32 / 1000000000 (rounded up) */ -#define ndelay(n) (__builtin_constant_p(n) ? \ - ((n) > 20000 ? __bad_ndelay() : __const_udelay((n) * 5ul)) : \ - __ndelay(n)) +#define ndelay(n) \ + ({ \ + if (__builtin_constant_p(n)) { \ + if ((n) / 20000 >= 1) \ + __bad_ndelay(); \ + else \ + __const_udelay((n) * 5ul); \ + } else { \ + __ndelay(n); \ + } \ + }) #endif /* __ASM_GENERIC_DELAY_H */ -- cgit v1.2.3 From f1ecc69838a2d7c8a3e1909f637d4083c071777d Mon Sep 17 00:00:00 2001 From: Jonas Bonn Date: Sat, 2 Jul 2011 17:17:35 +0200 Subject: asm-generic: add MMU variants of io.h functions Some of the implementations, in particular the ioremap variants, in asm-generic/io.h are for systems without an MMU. In order to be able to use the generic header file for systems with an MMU, this patch wraps these implementations in checks for CONFIG_MMU. Tested on OpenRISC. Signed-off-by: Jonas Bonn Cc: liqin.chen@sunplusct.com Cc: gxt@mprc.pku.edu.cn Acked-by: Mike Frysinger Acked-by: Arnd Bergmann --- include/asm-generic/io.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/asm-generic/io.h b/include/asm-generic/io.h index e0ffa3ddb02a..a1caf2d25d82 100644 --- a/include/asm-generic/io.h +++ b/include/asm-generic/io.h @@ -307,7 +307,11 @@ static inline void *phys_to_virt(unsigned long address) /* * Change "struct page" to physical address. + * + * This implementation is for the no-MMU case only... if you have an MMU + * you'll need to provide your own definitions. */ +#ifndef CONFIG_MMU static inline void __iomem *ioremap(phys_addr_t offset, unsigned long size) { return (void __iomem*) (unsigned long)offset; @@ -326,6 +330,7 @@ static inline void __iomem *ioremap(phys_addr_t offset, unsigned long size) static inline void iounmap(void *addr) { } +#endif /* CONFIG_MMU */ #ifndef CONFIG_GENERIC_IOMAP static inline void __iomem *ioport_map(unsigned long port, unsigned int nr) @@ -342,7 +347,7 @@ extern void ioport_unmap(void __iomem *p); #endif /* CONFIG_GENERIC_IOMAP */ #define xlate_dev_kmem_ptr(p) p -#define xlate_dev_mem_ptr(p) ((void *) (p)) +#define xlate_dev_mem_ptr(p) __va(p) #ifndef virt_to_bus static inline unsigned long virt_to_bus(volatile void *address) -- cgit v1.2.3 From 82ed223c264def2b15ee4bec2e8c3048092ceb5f Mon Sep 17 00:00:00 2001 From: Jonas Bonn Date: Sat, 2 Jul 2011 17:23:29 +0200 Subject: iomap: make IOPORT/PCI mapping functions conditional Use the CONFIG_HAS_IOPORT and CONFIG_PCI options to decide whether or not functions for mapping these areas are provided. Signed-off-by: Jonas Bonn Acked-by: Arnd Bergmann --- include/asm-generic/io.h | 2 ++ include/asm-generic/iomap.h | 4 ++++ 2 files changed, 6 insertions(+) (limited to 'include') diff --git a/include/asm-generic/io.h b/include/asm-generic/io.h index a1caf2d25d82..912088773a69 100644 --- a/include/asm-generic/io.h +++ b/include/asm-generic/io.h @@ -332,6 +332,7 @@ static inline void iounmap(void *addr) } #endif /* CONFIG_MMU */ +#ifdef CONFIG_HAS_IOPORT #ifndef CONFIG_GENERIC_IOMAP static inline void __iomem *ioport_map(unsigned long port, unsigned int nr) { @@ -345,6 +346,7 @@ static inline void ioport_unmap(void __iomem *p) extern void __iomem *ioport_map(unsigned long port, unsigned int nr); extern void ioport_unmap(void __iomem *p); #endif /* CONFIG_GENERIC_IOMAP */ +#endif /* CONFIG_HAS_IOPORT */ #define xlate_dev_kmem_ptr(p) p #define xlate_dev_mem_ptr(p) __va(p) diff --git a/include/asm-generic/iomap.h b/include/asm-generic/iomap.h index 76b0cc5637f8..c74ef2c6e633 100644 --- a/include/asm-generic/iomap.h +++ b/include/asm-generic/iomap.h @@ -56,17 +56,21 @@ extern void iowrite8_rep(void __iomem *port, const void *buf, unsigned long coun extern void iowrite16_rep(void __iomem *port, const void *buf, unsigned long count); extern void iowrite32_rep(void __iomem *port, const void *buf, unsigned long count); +#ifdef CONFIG_HAS_IOPORT /* Create a virtual mapping cookie for an IO port range */ extern void __iomem *ioport_map(unsigned long port, unsigned int nr); extern void ioport_unmap(void __iomem *); +#endif #ifndef ARCH_HAS_IOREMAP_WC #define ioremap_wc ioremap_nocache #endif +#ifdef CONFIG_PCI /* 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); extern void pci_iounmap(struct pci_dev *dev, void __iomem *); +#endif #endif -- cgit v1.2.3