aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRob Herring <rob.herring@calxeda.com>2012-02-10 18:05:13 -0500
committerRob Herring <rob.herring@calxeda.com>2012-03-06 22:22:01 -0500
commit4fe7ef3a0811c33137ace0ed424dd0c01dd2d75e (patch)
tree046a63d0c5db517529e86c914bb2fb493a4adee6
parent47168824fa71b52ca3f4c18ddf0c42ff35192235 (diff)
ARM: provide runtime hook for ioremap/iounmap
We have compile time over-ride of ioremap and iounmap, but an run-time override is needed for multi-platform builds. This adds an extra function pointer check, but ioremap is not peformance critical. The option for compile time selection remains. The caller variant is used here to provide correct caller information as ARM can only support level 0 for __builtin_return_address. Signed-off-by: Rob Herring <rob.herring@calxeda.com> Cc: Russell King <linux@arm.linux.org.uk> Reviewed-by: Arnd Bergmann <arnd@arndb.de> Reviewed-by: Nicolas Pitre <nico@linaro.org>
-rw-r--r--arch/arm/include/asm/io.h7
-rw-r--r--arch/arm/mm/ioremap.c17
2 files changed, 20 insertions, 4 deletions
diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h
index 9275828feb3d..6c363c16851c 100644
--- a/arch/arm/include/asm/io.h
+++ b/arch/arm/include/asm/io.h
@@ -83,6 +83,11 @@ extern void __iomem *__arm_ioremap_pfn(unsigned long, unsigned long, size_t, uns
83extern void __iomem *__arm_ioremap(unsigned long, size_t, unsigned int); 83extern void __iomem *__arm_ioremap(unsigned long, size_t, unsigned int);
84extern void __iomem *__arm_ioremap_exec(unsigned long, size_t, bool cached); 84extern void __iomem *__arm_ioremap_exec(unsigned long, size_t, bool cached);
85extern void __iounmap(volatile void __iomem *addr); 85extern void __iounmap(volatile void __iomem *addr);
86extern void __arm_iounmap(volatile void __iomem *addr);
87
88extern void __iomem * (*arch_ioremap_caller)(unsigned long, size_t,
89 unsigned int, void *);
90extern void (*arch_iounmap)(volatile void __iomem *);
86 91
87/* 92/*
88 * Bad read/write accesses... 93 * Bad read/write accesses...
@@ -266,7 +271,7 @@ extern void _memset_io(volatile void __iomem *, int, size_t);
266 */ 271 */
267#ifndef __arch_ioremap 272#ifndef __arch_ioremap
268#define __arch_ioremap __arm_ioremap 273#define __arch_ioremap __arm_ioremap
269#define __arch_iounmap __iounmap 274#define __arch_iounmap __arm_iounmap
270#endif 275#endif
271 276
272#define ioremap(cookie,size) __arch_ioremap((cookie), (size), MT_DEVICE) 277#define ioremap(cookie,size) __arch_ioremap((cookie), (size), MT_DEVICE)
diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c
index 80632e8d7538..024629046f1f 100644
--- a/arch/arm/mm/ioremap.c
+++ b/arch/arm/mm/ioremap.c
@@ -306,11 +306,15 @@ __arm_ioremap_pfn(unsigned long pfn, unsigned long offset, size_t size,
306} 306}
307EXPORT_SYMBOL(__arm_ioremap_pfn); 307EXPORT_SYMBOL(__arm_ioremap_pfn);
308 308
309void __iomem * (*arch_ioremap_caller)(unsigned long, size_t,
310 unsigned int, void *) =
311 __arm_ioremap_caller;
312
309void __iomem * 313void __iomem *
310__arm_ioremap(unsigned long phys_addr, size_t size, unsigned int mtype) 314__arm_ioremap(unsigned long phys_addr, size_t size, unsigned int mtype)
311{ 315{
312 return __arm_ioremap_caller(phys_addr, size, mtype, 316 return arch_ioremap_caller(phys_addr, size, mtype,
313 __builtin_return_address(0)); 317 __builtin_return_address(0));
314} 318}
315EXPORT_SYMBOL(__arm_ioremap); 319EXPORT_SYMBOL(__arm_ioremap);
316 320
@@ -369,4 +373,11 @@ void __iounmap(volatile void __iomem *io_addr)
369 373
370 vunmap(addr); 374 vunmap(addr);
371} 375}
372EXPORT_SYMBOL(__iounmap); 376
377void (*arch_iounmap)(volatile void __iomem *) = __iounmap;
378
379void __arm_iounmap(volatile void __iomem *io_addr)
380{
381 arch_iounmap(io_addr);
382}
383EXPORT_SYMBOL(__arm_iounmap);