Add ioremap_exec enhancements
Subsystems (4)
cover Add ioremap_exec enhancements
Hi,
Some platforms need the ability to ioremap memory for use with small chunks of code, like in certain PM applications that run from sram.
This series provides a common way to call an arch's ioremap_exec, which currently only exists for ARM, so that we can use it in the generic sram driver in a forthcoming patch.
This patch is part of a patch series split into several smaller sets for introducing suspend on AM335x. I plan to use it to copy several pieces of ASM code from an EMIF driver and the SoC PM code to run from SRAM on the SoC. I have pushed a branch here [1] based on v3.18-rc6 with all required patches so that the higher level plan for these patches can be seen.
Regards,
Dave
[1] https://github.com/dgerlach/linux-pm/tree/rfc-pm-am335x-v3.18-rc6
Russ Dill (2):
asm-generic: io: Add exec versions of ioremap
lib: devres: Add exec versions of devm_ioremap_resource and friends
arch/arm/include/asm/io.h | 2 + include/asm-generic/iomap.h | 5 ++ include/linux/device.h | 19 ++++++- include/linux/io.h | 9 +++- lib/devres.c | 125 ++++++++++++++++++++++++++++++++++++++++++-- 5 files changed, 154 insertions(+), 6 deletions(-)
Signature · 1 line
2.1.0
RFC PATCH 1/2 asm-generic: io: Add exec versions of ioremap
From: Russ Dill <[email protected]>
If code is to be copied into and area (such as SRAM) and run, it needs to be marked as exec. Currently only an ARM version of this exists.
--- arch/arm/include/asm/io.h | 2 ++ include/asm-generic/iomap.h | 5 +++++ 2 files changed, 7 insertions(+)
arch/arm/include/asm/io.h +2 -0
@@ -344,6 +344,8 @@ extern void _memset_io(volatile void __iomem *, int, size_t);#define ioremap_nocache (cookie,size) __arm_ioremap((cookie), (size), MT_DEVICE)#define ioremap_cache (cookie,size) __arm_ioremap((cookie), (size), MT_DEVICE_CACHED)#define ioremap_wc (cookie,size) __arm_ioremap((cookie), (size), MT_DEVICE_WC) +#define ioremap_exec (cookie,size) __arm_ioremap_exec((cookie), (size), true) +#define ioremap_exec_nocache (cookie,size) __arm_ioremap_exec((cookie), (size), false)#define iounmap __arm_iounmap/*
include/asm-generic/iomap.h +5 -0
@@ -66,6 +66,11 @@ extern void ioport_unmap(void __iomem *);#define ioremap_wc ioremap_nocache#endif +#ifndef ARCH_HAS_IOREMAP_EXEC +#define ioremap_exec ioremap +#define ioremap_exec_nocache ioremap_nocache +#endif +#ifdef CONFIG_PCI /* Destroy a virtual mapping cookie for a PCI BAR (memory or IO) */ struct pci_dev ;
Signature · 1 line
2.1.0
Arnd Bergmann
maintainerRe: [RFC PATCH 1/2] asm-generic: io: Add exec versions of ioremap
include/asm-generic/iomap.h extern void ioport_unmap(void __iomem *); · line 76
Quoted 13 lines · On Wednesday 26 November 2014 15:14:00 Dave Gerlach wrote:
include/asm-generic/iomap.h +5
-0@@ -66,6 +66,11 @@ extern void ioport_unmap(void __iomem *);#define ioremap_wc ioremap_nocache#endif +#ifndef ARCH_HAS_IOREMAP_EXEC +#define ioremap_exec ioremap +#define ioremap_exec_nocache ioremap_nocache +#endif +#ifdef CONFIG_PCI /* Destroy a virtual mapping cookie for a PCI BAR (memory or IO) */ struct pci_dev ;
ioremap and ioremap_nocache are the same, and there is no architecture-independent interface to map an MMIO range as cached because a lot of architectures can't do that.
Also, I think there are architectures that cannot execute from uncached memory, so I think adding this as a generic API is not a good idea.
Arnd
RFC PATCH 2/2 lib: devres: Add exec versions of devm_ioremap_resource and friends
In reply to Dave GerlachFrom: Russ Dill <[email protected]>
Now that there is an _exec version of ioremap, add devm support for it.
--- include/linux/device.h | 19 +++++++- include/linux/io.h | 9 +++- lib/devres.c | 125 +++++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 147 insertions(+), 6 deletions(-)
include/linux/device.h +18 -1
@@ -635,7 +635,24 @@ extern unsigned long devm_get_free_pages(struct device *dev, gfp_t gfp_mask, unsigned int order);extern void devm_free_pages (struct device *dev,unsigned long addr); -void __iomem *devm_ioremap_resource (struct device *dev,struct resource *res); +void __iomem *__devm_ioremap_resource (struct device *dev,struct resource *res, +bool exec); +static inline void __iomem *devm_ioremap_resource (struct device *dev, +struct resource *res) +{ +return __devm_ioremap_resource (dev, res, false); +} +void __iomem *devm_request_and_ioremap (struct device *dev, +struct resource *res); + +static inline void __iomem *devm_ioremap_exec_resource (struct device *dev, +struct resource *res) +{ +return __devm_ioremap_resource (dev, res, true); +} + +void __iomem *devm_request_and_ioremap_exec (struct device *dev, +struct resource *res);/* allows to add/remove a custom action to devres stack */ int devm_add_action (struct device *dev,void (*action)(void *),void *data);
include/linux/io.h +7 -2
@@ -61,9 +61,14 @@ static inline void devm_ioport_unmap(struct device *dev, void __iomem *addr)#define IOMEM_ERR_PTR (err) (__force void __iomem *)ERR_PTR(err)void __iomem *devm_ioremap (struct device *dev,resource_size_t offset, -unsigned long size); +unsigned long size);void __iomem *devm_ioremap_nocache (struct device *dev,resource_size_t offset, -unsigned long size); +unsigned long size); +void __iomem *devm_ioremap_exec (struct device *dev,resource_size_t offset, +unsigned long size); +void __iomem *devm_ioremap_exec_nocache (struct device *dev, +resource_size_t offset, +unsigned long 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);
lib/devres.c +122 -3
149 lines not on this page · raw message
Signature · 6 lines
2.1.0 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC PATCH 2/2] lib: devres: Add exec versions of devm_ioremap_resource and friends
Quoted 16 lines · Dave Gerlach
lib/devres.c +10
-0@@ -72,6 +72,64 @@ void __iomem *devm_ioremap_nocache(struct device *dev, resource_size_t offset,EXPORT_SYMBOL (devm_ioremap_nocache);/** +* devm_ioremap_exec - Managed ioremap_exec() +* @dev: Generic device to remap IO address for +* @offset: BUS offset to map +* @size: Size of map +* +* Managed ioremap_exec(). Map is automatically unmapped on driver detach. +*/ +void __iomem *devm_ioremap_exec (struct device *dev,resource_size_t offset, +unsigned long size) +{
[...]
Quoted 1 line
+ addr =
ioremap_exec(offset, size);
[...]
Quoted 16 lines
lib/devres.c +16
-0+} +EXPORT_SYMBOL (devm_ioremap_exec); + +/** +* devm_ioremap_exec_nocache - Managed ioremap_exec_nocache() +* @dev: Generic device to remap IO address for +* @offset: BUS offset to map +* @size: Size of map +* +* Managed ioremap_exec_nocache(). Map is automatically unmapped on driver +* detach. +*/ +void __iomem *devm_ioremap_exec_nocache (struct device *dev, +resource_size_t offset, +unsigned long size) +{
[...]
Quoted 1 line
+ addr =
ioremap_exec_nocache(offset, size);
[...]
lib/devres.c void __iomem *devm_ioremap_nocache(struct device *dev, resource_size_t offset, · line 131
Quoted 3 lines
lib/devres.c +3
-0+} +EXPORT_SYMBOL (devm_ioremap_exec_nocache); +
Both of these are identical to the already-existing devm_ioremap() and devm_ioremap_nocache(), except for the call to the underlying ioremap*() variant.
Can't the variant selection be done by passing a flag around, set by the top-level inline functions, to avoid code duplication? Some architecture-specific ioremap() implementations already work that way, cfr. arch/m68k/include/asm/io_mm.h:
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 lonn
g size)
{
return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
}
static inline void __iomem *ioremap_writethrough(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);
}Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds