2006-03-26 17:37:06 +08:00
|
|
|
/*
|
|
|
|
* (c) Copyright 2006 Hewlett-Packard Development Company, L.P.
|
|
|
|
* Bjorn Helgaas <bjorn.helgaas@hp.com>
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License version 2 as
|
|
|
|
* published by the Free Software Foundation.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <linux/compiler.h>
|
|
|
|
#include <linux/module.h>
|
|
|
|
#include <linux/efi.h>
|
|
|
|
#include <asm/io.h>
|
2006-05-06 07:19:50 +08:00
|
|
|
#include <asm/meminit.h>
|
2006-03-26 17:37:06 +08:00
|
|
|
|
|
|
|
static inline void __iomem *
|
2007-03-31 00:33:11 +08:00
|
|
|
__ioremap (unsigned long phys_addr, unsigned long size)
|
2006-03-26 17:37:06 +08:00
|
|
|
{
|
2007-03-31 00:33:11 +08:00
|
|
|
return (void __iomem *) (__IA64_UNCACHED_OFFSET | phys_addr);
|
2006-03-26 17:37:06 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void __iomem *
|
2007-03-31 00:33:11 +08:00
|
|
|
ioremap (unsigned long phys_addr, unsigned long size)
|
2006-03-26 17:37:06 +08:00
|
|
|
{
|
2006-05-06 07:19:50 +08:00
|
|
|
u64 attr;
|
|
|
|
unsigned long gran_base, gran_size;
|
2006-03-26 17:37:06 +08:00
|
|
|
|
2006-05-06 07:19:50 +08:00
|
|
|
/*
|
|
|
|
* For things in kern_memmap, we must use the same attribute
|
|
|
|
* as the rest of the kernel. For more details, see
|
|
|
|
* Documentation/ia64/aliasing.txt.
|
|
|
|
*/
|
2007-03-31 00:33:11 +08:00
|
|
|
attr = kern_mem_attribute(phys_addr, size);
|
2006-05-06 07:19:50 +08:00
|
|
|
if (attr & EFI_MEMORY_WB)
|
2007-03-31 00:33:11 +08:00
|
|
|
return (void __iomem *) phys_to_virt(phys_addr);
|
2006-05-06 07:19:50 +08:00
|
|
|
else if (attr & EFI_MEMORY_UC)
|
2007-03-31 00:33:11 +08:00
|
|
|
return __ioremap(phys_addr, size);
|
2006-03-31 00:53:39 +08:00
|
|
|
|
2006-03-26 17:37:06 +08:00
|
|
|
/*
|
2006-05-06 07:19:50 +08:00
|
|
|
* Some chipsets don't support UC access to memory. If
|
|
|
|
* WB is supported for the whole granule, we prefer that.
|
2006-03-26 17:37:06 +08:00
|
|
|
*/
|
2007-03-31 00:33:11 +08:00
|
|
|
gran_base = GRANULEROUNDDOWN(phys_addr);
|
|
|
|
gran_size = GRANULEROUNDUP(phys_addr + size) - gran_base;
|
2006-05-06 07:19:50 +08:00
|
|
|
if (efi_mem_attribute(gran_base, gran_size) & EFI_MEMORY_WB)
|
2007-03-31 00:33:11 +08:00
|
|
|
return (void __iomem *) phys_to_virt(phys_addr);
|
2006-05-06 07:19:50 +08:00
|
|
|
|
2007-03-31 00:33:11 +08:00
|
|
|
return __ioremap(phys_addr, size);
|
2006-03-26 17:37:06 +08:00
|
|
|
}
|
|
|
|
EXPORT_SYMBOL(ioremap);
|
|
|
|
|
|
|
|
void __iomem *
|
2007-03-31 00:33:11 +08:00
|
|
|
ioremap_nocache (unsigned long phys_addr, unsigned long size)
|
2006-03-26 17:37:06 +08:00
|
|
|
{
|
2007-03-31 00:33:11 +08:00
|
|
|
if (kern_mem_attribute(phys_addr, size) & EFI_MEMORY_WB)
|
2006-07-17 13:41:59 +08:00
|
|
|
return NULL;
|
2006-05-06 07:19:50 +08:00
|
|
|
|
2007-03-31 00:33:11 +08:00
|
|
|
return __ioremap(phys_addr, size);
|
2006-03-26 17:37:06 +08:00
|
|
|
}
|
|
|
|
EXPORT_SYMBOL(ioremap_nocache);
|