[RFC/NOT FOR MERGING 2/3] serial: omap: remove hwmod dependency
Tony Lindgren
tony at atomide.com
Thu Feb 14 17:47:10 EST 2013
* Paul Walmsley <paul at pwsan.com> [130214 13:44]:
> Hi,
>
> On Thu, 14 Feb 2013, Paul Walmsley wrote:
>
> > So instead of something bus-specific like that, a better way would be to
> > use something like:
> >
> > va = dev->bus->ioremap( ... );
> > va = dev->bus->iounmap( ... );
>
> Something like this is what I was thinking. Obviously there would be more
> patches needed, for the various arches, etc.; and I'm not convinced that
> the function pointer init is done at the right time yet. Comments welcome.
>
>
> - Paul
>
>
> From: Paul Walmsley <paul at pwsan.com>
> Date: Thu, 14 Feb 2013 13:49:58 -0700
> Subject: [PATCH] EXPERIMENTAL: device/ARM: allow buses to override ioremap*()
> and iounmap()
>
> On some hardware, such as OMAP, the bus abstraction code needs to call
> ioremap(), since some SoC-integration registers are located in the
> device address space. But generic device drivers should be able to
> call ioremap() from driver code, for the majority of situations where
> this isn't necessary. This experimental patch allows Linux bus abstraction
> code to override all of the ioremap*() and iounmap() functions. In the OMAP
> case, this would be used to return the previously-mapped address range from
> the bus code, when called for the device's register area. This would avoid
> a duplicate TLB mapping for that space.
>
> This might also be useful as a generic replacement for pci_ioremap_bar().
>
> Compile-tested only.
The other option could be to allow custom ioremap function pointers
based on address range in __arm_ioremap_pfn_caller() the same way as
the SoC specific static mappings are allowed. That would require adding
a function pointer to struct map_desc.
Maybe that would do the trick?
Regards,
Tony
> ---
> arch/arm/include/asm/io.h | 10 +++++-----
> arch/arm/mm/ioremap.c | 30 ++++++++++++++++++++++++++++++
> arch/arm/mm/mmu.c | 8 ++++++++
> include/linux/device.h | 26 ++++++++++++++++++++++++++
> 4 files changed, 69 insertions(+), 5 deletions(-)
>
> diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h
> index 652b560..22cc085 100644
> --- a/arch/arm/include/asm/io.h
> +++ b/arch/arm/include/asm/io.h
> @@ -325,11 +325,11 @@ extern void _memset_io(volatile void __iomem *, int, size_t);
> * Documentation/io-mapping.txt.
> *
> */
> -#define ioremap(cookie,size) __arm_ioremap((cookie), (size), MT_DEVICE)
j> -#define ioremap_nocache(cookie,size) __arm_ioremap((cookie), (size), MT_DEVICE)
> -#define ioremap_cached(cookie,size) __arm_ioremap((cookie), (size), MT_DEVICE_CACHED)
> -#define ioremap_wc(cookie,size) __arm_ioremap((cookie), (size), MT_DEVICE_WC)
> -#define iounmap __arm_iounmap
> +extern void __iomem *ioremap(unsigned long cookie, size_t size);
> +extern void __iomem *ioremap_nocache(unsigned long cookie, size_t size);
> +extern void __iomem *ioremap_cached(unsigned long cookie, size_t size);
> +extern void __iomem *ioremap_wc(unsigned long cookie, size_t size);
> +extern void iounmap(volatile void __iomem *va);
>
> /*
> * io{read,write}{8,16,32} macros
> diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c
> index 88fd86c..6507e69 100644
> --- a/arch/arm/mm/ioremap.c
> +++ b/arch/arm/mm/ioremap.c
> @@ -398,3 +398,33 @@ int pci_ioremap_io(unsigned int offset, phys_addr_t phys_addr)
> }
> EXPORT_SYMBOL_GPL(pci_ioremap_io);
> #endif
> +
> +void __iomem *ioremap(unsigned long cookie, size_t size)
> +{
> + return __arm_ioremap(cookie, size, MT_DEVICE);
> +}
> +EXPORT_SYMBOL(ioremap);
> +
> +void __iomem *ioremap_nocache(unsigned long cookie, size_t size)
> +{
> + return __arm_ioremap(cookie, size, MT_DEVICE);
> +}
> +EXPORT_SYMBOL(ioremap_nocache);
> +
> +void __iomem *ioremap_cached(unsigned long cookie, size_t size)
> +{
> + return __arm_ioremap(cookie, size, MT_DEVICE_CACHED);
> +}
> +EXPORT_SYMBOL(ioremap_cached);
> +
> +void __iomem *ioremap_wc(unsigned long cookie, size_t size)
> +{
> + return __arm_ioremap(cookie, size, MT_DEVICE_WC);
> +}
> +EXPORT_SYMBOL(ioremap_wc);
> +
> +void iounmap(volatile void __iomem *va)
> +{
> + return __arm_iounmap(va);
> +}
> +EXPORT_SYMBOL(iounmap);
> diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
> index ce328c7..303dba0 100644
> --- a/arch/arm/mm/mmu.c
> +++ b/arch/arm/mm/mmu.c
> @@ -17,6 +17,7 @@
> #include <linux/fs.h>
> #include <linux/vmalloc.h>
> #include <linux/sizes.h>
> +#include <linux/platform_device.h>
>
> #include <asm/cp15.h>
> #include <asm/cputype.h>
> @@ -28,6 +29,7 @@
> #include <asm/highmem.h>
> #include <asm/system_info.h>
> #include <asm/traps.h>
> +#include <asm/io.h>
>
> #include <asm/mach/arch.h>
> #include <asm/mach/map.h>
> @@ -1246,4 +1248,10 @@ void __init paging_init(struct machine_desc *mdesc)
>
> empty_zero_page = virt_to_page(zero_page);
> __flush_dcache_page(NULL, empty_zero_page);
> +
> + platform_bus_type.ioremap = ioremap;
> + platform_bus_type.ioremap_nocache = ioremap_nocache;
> + platform_bus_type.ioremap_cached = ioremap_cached;
> + platform_bus_type.ioremap_wc = ioremap_wc;
> + platform_bus_type.iounmap = iounmap;
> }
> diff --git a/include/linux/device.h b/include/linux/device.h
> index 43dcda9..48c35e2 100644
> --- a/include/linux/device.h
> +++ b/include/linux/device.h
> @@ -71,6 +71,26 @@ extern void bus_remove_file(struct bus_type *, struct bus_attribute *);
> * @shutdown: Called at shut-down time to quiesce the device.
> * @suspend: Called when a device on this bus wants to go to sleep mode.
> * @resume: Called to bring a device on this bus out of sleep mode.
> + * @ioremap: Function pointer returning a virtual address used to
> + * interact with a device on this bus. Generally
> + * implemented via @ioremap_nocache.
> + * @ioremap_nocache: Function pointer returning a virtual address used to
> + * interact with a device on this bus. Reads and writes
> + * to the returned address space are not cached by the
> + * CPU, so are suitable for memory-mapped I/O regions.
> + * @ioremap_cached: Function pointer returning a virtual address used to
> + * interact with private memory located on this bus. Reads and
> + * writes to the returned address space may be cached by the
> + * CPU, so this is suitable for I/O-mapped memory where all
> + * accesses are via the same cache.
> + * @ioremap_wc: Function pointer returning a virtual address used to
> + * interact with memory located on this bus. Writes to
> + * the returned address space may be combined by the CPU,
> + * so this is suitable for I/O-mapped memory such as
> + * framebuffers.
> + * @iounmap: Function pointer called to indicate that a caller is done
> + * with the virtual address mapping returned by @ioremap,
> + * @ioremap_nocache, @ioremap_cached, or @ioremap_wc.
> * @pm: Power management operations of this bus, callback the specific
> * device driver's pm-ops.
> * @iommu_ops: IOMMU specific operations for this bus, used to attach IOMMU
> @@ -105,6 +125,12 @@ struct bus_type {
> int (*suspend)(struct device *dev, pm_message_t state);
> int (*resume)(struct device *dev);
>
> + void __iomem *(*ioremap)(unsigned long phys_addr, size_t size);
> + void __iomem *(*ioremap_nocache)(unsigned long phys_addr, size_t size);
> + void __iomem *(*ioremap_cached)(unsigned long phys_addr, size_t size);
> + void __iomem *(*ioremap_wc)(unsigned long phys_addr, size_t size);
> + void (*iounmap)(volatile void __iomem *va);
> +
> const struct dev_pm_ops *pm;
>
> struct iommu_ops *iommu_ops;
> --
> 1.7.10.4
>
More information about the linux-arm-kernel
mailing list