[ARM] mm 10: allow memory type to be specified with ioremap

__ioremap() took a set of page table flags (specifically the cacheable
and bufferable bits) to control the mapping type.  However, with
the advent of ARMv6, this is far too limited.

Replace the page table flags with a memory type index, so that the
desired attributes can be selected from the mem_type table.

Finally, to prevent silent miscompilation due to the differing
arguments, rename the __ioremap() and __ioremap_pfn() functions.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
This commit is contained in:
Russell King 2007-05-05 20:59:27 +01:00 коммит произвёл Russell King
Родитель 0af92befeb
Коммит 3603ab2b62
9 изменённых файлов: 54 добавлений и 48 удалений

Просмотреть файл

@ -41,7 +41,7 @@ void * __iomem __iop13xx_io(unsigned long io_addr)
EXPORT_SYMBOL(__iop13xx_io); EXPORT_SYMBOL(__iop13xx_io);
void * __iomem __iop13xx_ioremap(unsigned long cookie, size_t size, void * __iomem __iop13xx_ioremap(unsigned long cookie, size_t size,
unsigned long flags) unsigned int mtype)
{ {
void __iomem * retval; void __iomem * retval;
@ -61,9 +61,9 @@ void * __iomem __iop13xx_ioremap(unsigned long cookie, size_t size,
(cookie - IOP13XX_PCIE_LOWER_MEM_RA)); (cookie - IOP13XX_PCIE_LOWER_MEM_RA));
break; break;
case IOP13XX_PBI_LOWER_MEM_RA ... IOP13XX_PBI_UPPER_MEM_RA: case IOP13XX_PBI_LOWER_MEM_RA ... IOP13XX_PBI_UPPER_MEM_RA:
retval = __ioremap(IOP13XX_PBI_LOWER_MEM_PA + retval = __arm_ioremap(IOP13XX_PBI_LOWER_MEM_PA +
(cookie - IOP13XX_PBI_LOWER_MEM_RA), (cookie - IOP13XX_PBI_LOWER_MEM_RA),
size, flags); size, mtype);
break; break;
case IOP13XX_PCIE_LOWER_IO_PA ... IOP13XX_PCIE_UPPER_IO_PA: case IOP13XX_PCIE_LOWER_IO_PA ... IOP13XX_PCIE_UPPER_IO_PA:
retval = (void *) IOP13XX_PCIE_IO_PHYS_TO_VIRT(cookie); retval = (void *) IOP13XX_PCIE_IO_PHYS_TO_VIRT(cookie);
@ -75,7 +75,7 @@ void * __iomem __iop13xx_ioremap(unsigned long cookie, size_t size,
retval = (void *) IOP13XX_PMMR_PHYS_TO_VIRT(cookie); retval = (void *) IOP13XX_PMMR_PHYS_TO_VIRT(cookie);
break; break;
default: default:
retval = __ioremap(cookie, size, flags); retval = __arm_ioremap(cookie, size, mtype);
} }
return retval; return retval;

Просмотреть файл

@ -88,9 +88,9 @@ void iop13xx_map_pci_memory(void)
if (end) { if (end) {
iop13xx_atux_mem_base = iop13xx_atux_mem_base =
(u32) __ioremap_pfn( (u32) __arm_ioremap_pfn(
__phys_to_pfn(IOP13XX_PCIX_LOWER_MEM_PA) __phys_to_pfn(IOP13XX_PCIX_LOWER_MEM_PA)
, 0, iop13xx_atux_mem_size, 0); , 0, iop13xx_atux_mem_size, MT_DEVICE);
if (!iop13xx_atux_mem_base) { if (!iop13xx_atux_mem_base) {
printk("%s: atux allocation " printk("%s: atux allocation "
"failed\n", __FUNCTION__); "failed\n", __FUNCTION__);
@ -114,9 +114,9 @@ void iop13xx_map_pci_memory(void)
if (end) { if (end) {
iop13xx_atue_mem_base = iop13xx_atue_mem_base =
(u32) __ioremap_pfn( (u32) __arm_ioremap_pfn(
__phys_to_pfn(IOP13XX_PCIE_LOWER_MEM_PA) __phys_to_pfn(IOP13XX_PCIE_LOWER_MEM_PA)
, 0, iop13xx_atue_mem_size, 0); , 0, iop13xx_atue_mem_size, MT_DEVICE);
if (!iop13xx_atue_mem_base) { if (!iop13xx_atue_mem_base) {
printk("%s: atue allocation " printk("%s: atue allocation "
"failed\n", __FUNCTION__); "failed\n", __FUNCTION__);

Просмотреть файл

@ -262,11 +262,10 @@ remap_area_supersections(unsigned long virt, unsigned long pfn,
* mapping. See include/asm-arm/proc-armv/pgtable.h for more information. * mapping. See include/asm-arm/proc-armv/pgtable.h for more information.
*/ */
void __iomem * void __iomem *
__ioremap_pfn(unsigned long pfn, unsigned long offset, size_t size, __arm_ioremap_pfn(unsigned long pfn, unsigned long offset, size_t size,
unsigned long flags) unsigned int mtype)
{ {
const struct mem_type *type; const struct mem_type *type;
struct mem_type t;
int err; int err;
unsigned long addr; unsigned long addr;
struct vm_struct * area; struct vm_struct * area;
@ -277,10 +276,9 @@ __ioremap_pfn(unsigned long pfn, unsigned long offset, size_t size,
if (pfn >= 0x100000 && (__pfn_to_phys(pfn) & ~SUPERSECTION_MASK)) if (pfn >= 0x100000 && (__pfn_to_phys(pfn) & ~SUPERSECTION_MASK))
return NULL; return NULL;
t = *get_mem_type(MT_DEVICE); type = get_mem_type(mtype);
t.prot_sect |= flags; if (!type)
t.prot_pte |= flags; return NULL;
type = &t;
size = PAGE_ALIGN(size); size = PAGE_ALIGN(size);
@ -311,10 +309,10 @@ __ioremap_pfn(unsigned long pfn, unsigned long offset, size_t size,
flush_cache_vmap(addr, addr + size); flush_cache_vmap(addr, addr + size);
return (void __iomem *) (offset + addr); return (void __iomem *) (offset + addr);
} }
EXPORT_SYMBOL(__ioremap_pfn); EXPORT_SYMBOL(__arm_ioremap_pfn);
void __iomem * void __iomem *
__ioremap(unsigned long phys_addr, size_t size, unsigned long flags) __arm_ioremap(unsigned long phys_addr, size_t size, unsigned int mtype)
{ {
unsigned long last_addr; unsigned long last_addr;
unsigned long offset = phys_addr & ~PAGE_MASK; unsigned long offset = phys_addr & ~PAGE_MASK;
@ -332,9 +330,9 @@ __ioremap(unsigned long phys_addr, size_t size, unsigned long flags)
*/ */
size = PAGE_ALIGN(last_addr + 1) - phys_addr; size = PAGE_ALIGN(last_addr + 1) - phys_addr;
return __ioremap_pfn(pfn, offset, size, flags); return __arm_ioremap_pfn(pfn, offset, size, mtype);
} }
EXPORT_SYMBOL(__ioremap); EXPORT_SYMBOL(__arm_ioremap);
void __iounmap(volatile void __iomem *addr) void __iounmap(volatile void __iomem *addr)
{ {

Просмотреть файл

@ -62,21 +62,21 @@ void flush_dcache_page(struct page *page)
} }
EXPORT_SYMBOL(flush_dcache_page); EXPORT_SYMBOL(flush_dcache_page);
void __iomem *__ioremap_pfn(unsigned long pfn, unsigned long offset, void __iomem *__arm_ioremap_pfn(unsigned long pfn, unsigned long offset,
size_t size, unsigned long flags) size_t size, unsigned int mtype)
{ {
if (pfn >= (0x100000000ULL >> PAGE_SHIFT)) if (pfn >= (0x100000000ULL >> PAGE_SHIFT))
return NULL; return NULL;
return (void __iomem *) (offset + (pfn << PAGE_SHIFT)); return (void __iomem *) (offset + (pfn << PAGE_SHIFT));
} }
EXPORT_SYMBOL(__ioremap_pfn); EXPORT_SYMBOL(__arm_ioremap_pfn);
void __iomem *__ioremap(unsigned long phys_addr, size_t size, void __iomem *__arm_ioremap(unsigned long phys_addr, size_t size,
unsigned long flags) unsigned int mtype)
{ {
return (void __iomem *)phys_addr; return (void __iomem *)phys_addr;
} }
EXPORT_SYMBOL(__ioremap); EXPORT_SYMBOL(__arm_ioremap);
void __iounmap(volatile void __iomem *addr) void __iounmap(volatile void __iomem *addr)
{ {

Просмотреть файл

@ -22,7 +22,7 @@
#include <asm/io.h> #include <asm/io.h>
void * __iomem __iop3xx_ioremap(unsigned long cookie, size_t size, void * __iomem __iop3xx_ioremap(unsigned long cookie, size_t size,
unsigned long flags) unsigned int mtype)
{ {
void __iomem * retval; void __iomem * retval;
@ -34,7 +34,7 @@ void * __iomem __iop3xx_ioremap(unsigned long cookie, size_t size,
retval = (void *) IOP3XX_PMMR_PHYS_TO_VIRT(cookie); retval = (void *) IOP3XX_PMMR_PHYS_TO_VIRT(cookie);
break; break;
default: default:
retval = __ioremap(cookie, size, flags); retval = __arm_ioremap(cookie, size, mtype);
} }
return retval; return retval;

Просмотреть файл

@ -23,7 +23,7 @@
#include <linux/kernel.h> /* For BUG */ #include <linux/kernel.h> /* For BUG */
static inline void __iomem * static inline void __iomem *
ixp23xx_ioremap(unsigned long addr, unsigned long size, unsigned long flags) ixp23xx_ioremap(unsigned long addr, unsigned long size, unsigned int mtype)
{ {
if (addr >= IXP23XX_PCI_MEM_START && if (addr >= IXP23XX_PCI_MEM_START &&
addr <= IXP23XX_PCI_MEM_START + IXP23XX_PCI_MEM_SIZE) { addr <= IXP23XX_PCI_MEM_START + IXP23XX_PCI_MEM_SIZE) {
@ -34,7 +34,7 @@ ixp23xx_ioremap(unsigned long addr, unsigned long size, unsigned long flags)
((addr - IXP23XX_PCI_MEM_START) + IXP23XX_PCI_MEM_VIRT); ((addr - IXP23XX_PCI_MEM_START) + IXP23XX_PCI_MEM_VIRT);
} }
return __ioremap(addr, size, flags); return __arm_ioremap(addr, size, mtype);
} }
static inline void static inline void

Просмотреть файл

@ -59,10 +59,10 @@ extern int ixp4xx_pci_write(u32 addr, u32 cmd, u32 data);
* fallback to the default. * fallback to the default.
*/ */
static inline void __iomem * static inline void __iomem *
__ixp4xx_ioremap(unsigned long addr, size_t size, unsigned long flags) __ixp4xx_ioremap(unsigned long addr, size_t size, unsigned int mtype)
{ {
if((addr < 0x48000000) || (addr > 0x4fffffff)) if((addr < 0x48000000) || (addr > 0x4fffffff))
return __ioremap(addr, size, flags); return __arm_ioremap(addr, size, mtype);
return (void *)addr; return (void *)addr;
} }

Просмотреть файл

@ -56,13 +56,22 @@ extern void __raw_readsl(const void __iomem *addr, void *data, int longlen);
/* /*
* Architecture ioremap implementation. * Architecture ioremap implementation.
*
* __ioremap takes CPU physical address.
*
* __ioremap_pfn takes a Page Frame Number and an offset into that page
*/ */
extern void __iomem * __ioremap_pfn(unsigned long, unsigned long, size_t, unsigned long); #define MT_DEVICE 0
extern void __iomem * __ioremap(unsigned long, size_t, unsigned long); #define MT_DEVICE_NONSHARED 1
#define MT_DEVICE_CACHED 2
#define MT_DEVICE_IXP2000 3
/*
* types 4 onwards can be found in asm/mach/map.h and are undefined
* for ioremap
*/
/*
* __arm_ioremap takes CPU physical address.
* __arm_ioremap_pfn takes a Page Frame Number and an offset into that page
*/
extern void __iomem * __arm_ioremap_pfn(unsigned long, unsigned long, size_t, unsigned int);
extern void __iomem * __arm_ioremap(unsigned long, size_t, unsigned int);
extern void __iounmap(volatile void __iomem *addr); extern void __iounmap(volatile void __iomem *addr);
/* /*
@ -203,14 +212,14 @@ extern void _memset_io(volatile void __iomem *, int, size_t);
* *
*/ */
#ifndef __arch_ioremap #ifndef __arch_ioremap
#define ioremap(cookie,size) __ioremap(cookie,size,0) #define ioremap(cookie,size) __arm_ioremap(cookie, size, MT_DEVICE)
#define ioremap_nocache(cookie,size) __ioremap(cookie,size,0) #define ioremap_nocache(cookie,size) __arm_ioremap(cookie, size, MT_DEVICE)
#define ioremap_cached(cookie,size) __ioremap(cookie,size,L_PTE_CACHEABLE) #define ioremap_cached(cookie,size) __arm_ioremap(cookie, size, MT_DEVICE_CACHED)
#define iounmap(cookie) __iounmap(cookie) #define iounmap(cookie) __iounmap(cookie)
#else #else
#define ioremap(cookie,size) __arch_ioremap((cookie),(size),0) #define ioremap(cookie,size) __arch_ioremap((cookie), (size), MT_DEVICE)
#define ioremap_nocache(cookie,size) __arch_ioremap((cookie),(size),0) #define ioremap_nocache(cookie,size) __arch_ioremap((cookie), (size), MT_DEVICE)
#define ioremap_cached(cookie,size) __arch_ioremap((cookie),(size),L_PTE_CACHEABLE) #define ioremap_cached(cookie,size) __arch_ioremap((cookie), (size), MT_DEVICE_CACHED)
#define iounmap(cookie) __arch_iounmap(cookie) #define iounmap(cookie) __arch_iounmap(cookie)
#endif #endif

Просмотреть файл

@ -9,6 +9,8 @@
* *
* Page table mapping constructs and function prototypes * Page table mapping constructs and function prototypes
*/ */
#include <asm/io.h>
struct map_desc { struct map_desc {
unsigned long virtual; unsigned long virtual;
unsigned long pfn; unsigned long pfn;
@ -16,10 +18,7 @@ struct map_desc {
unsigned int type; unsigned int type;
}; };
#define MT_DEVICE 0 /* types 0-3 are defined in asm/io.h */
#define MT_DEVICE_NONSHARED 1
#define MT_DEVICE_CACHED 2
#define MT_DEVICE_IXP2000 3
#define MT_CACHECLEAN 4 #define MT_CACHECLEAN 4
#define MT_MINICLEAN 5 #define MT_MINICLEAN 5
#define MT_LOW_VECTORS 6 #define MT_LOW_VECTORS 6