From mboxrd@z Thu Jan 1 00:00:00 1970 From: Tony Lindgren Subject: Re: [RFC/NOT FOR MERGING 2/3] serial: omap: remove hwmod dependency Date: Thu, 14 Feb 2013 14:47:10 -0800 Message-ID: <20130214224710.GF11362@atomide.com> References: <1360840554-26901-1-git-send-email-balbi@ti.com> <1360840554-26901-2-git-send-email-balbi@ti.com> <20130214171253.GC7144@atomide.com> <20130214175650.GA25891@arwen.pp.htv.fi> <20130214181217.GA11806@atomide.com> <20130214192719.GB26679@arwen.pp.htv.fi> <20130214193911.GD11806@atomide.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Return-path: Received: from mho-03-ewr.mailhop.org ([204.13.248.66]:46786 "EHLO mho-01-ewr.mailhop.org" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1030238Ab3BNWrO (ORCPT ); Thu, 14 Feb 2013 17:47:14 -0500 Content-Disposition: inline In-Reply-To: Sender: linux-omap-owner@vger.kernel.org List-Id: linux-omap@vger.kernel.org To: Paul Walmsley Cc: Felipe Balbi , Linux OMAP Mailing List , Linux ARM Kernel Mailing List * Paul Walmsley [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 > 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 > #include > #include > +#include > > #include > #include > @@ -28,6 +29,7 @@ > #include > #include > #include > +#include > > #include > #include > @@ -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 > From mboxrd@z Thu Jan 1 00:00:00 1970 From: tony@atomide.com (Tony Lindgren) Date: Thu, 14 Feb 2013 14:47:10 -0800 Subject: [RFC/NOT FOR MERGING 2/3] serial: omap: remove hwmod dependency In-Reply-To: References: <1360840554-26901-1-git-send-email-balbi@ti.com> <1360840554-26901-2-git-send-email-balbi@ti.com> <20130214171253.GC7144@atomide.com> <20130214175650.GA25891@arwen.pp.htv.fi> <20130214181217.GA11806@atomide.com> <20130214192719.GB26679@arwen.pp.htv.fi> <20130214193911.GD11806@atomide.com> Message-ID: <20130214224710.GF11362@atomide.com> To: linux-arm-kernel@lists.infradead.org List-Id: linux-arm-kernel.lists.infradead.org * Paul Walmsley [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 > 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 > #include > #include > +#include > > #include > #include > @@ -28,6 +29,7 @@ > #include > #include > #include > +#include > > #include > #include > @@ -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 >