fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / arch / mips / mm / ioremap.c
index adf3522..fc2c96f 100644 (file)
  * (C) Copyright 1995 1996 Linus Torvalds
  * (C) Copyright 2001, 2002 Ralf Baechle
  */
+#include <linux/mm.h>
 #include <linux/module.h>
 #include <asm/addrspace.h>
 #include <asm/byteorder.h>
 
 #include <linux/vmalloc.h>
-#include <asm/cacheflush.h>
-#include <asm/io.h>
-#include <asm/tlbflush.h>
-
-static inline void remap_area_pte(pte_t * pte, unsigned long address,
-       phys_t size, phys_t phys_addr, unsigned long flags)
-{
-       phys_t end;
-       unsigned long pfn;
-       pgprot_t pgprot = __pgprot(_PAGE_GLOBAL | _PAGE_PRESENT | __READABLE
-                                  | __WRITEABLE | flags);
-
-       address &= ~PMD_MASK;
-       end = address + size;
-       if (end > PMD_SIZE)
-               end = PMD_SIZE;
-       if (address >= end)
-               BUG();
-       pfn = phys_addr >> PAGE_SHIFT;
-       do {
-               if (!pte_none(*pte)) {
-                       printk("remap_area_pte: page already exists\n");
-                       BUG();
-               }
-               set_pte(pte, pfn_pte(pfn, pgprot));
-               address += PAGE_SIZE;
-               pfn++;
-               pte++;
-       } while (address && (address < end));
-}
-
-static inline int remap_area_pmd(pmd_t * pmd, unsigned long address,
-       phys_t size, phys_t phys_addr, unsigned long flags)
-{
-       phys_t end;
-
-       address &= ~PGDIR_MASK;
-       end = address + size;
-       if (end > PGDIR_SIZE)
-               end = PGDIR_SIZE;
-       phys_addr -= address;
-       if (address >= end)
-               BUG();
-       do {
-               pte_t * pte = pte_alloc_kernel(&init_mm, pmd, address);
-               if (!pte)
-                       return -ENOMEM;
-               remap_area_pte(pte, address, end - address, address + phys_addr, flags);
-               address = (address + PMD_SIZE) & PMD_MASK;
-               pmd++;
-       } while (address && (address < end));
-       return 0;
-}
-
-static int remap_area_pages(unsigned long address, phys_t phys_addr,
-       phys_t size, unsigned long flags)
-{
-       int error;
-       pgd_t * dir;
-       unsigned long end = address + size;
-
-       phys_addr -= address;
-       dir = pgd_offset(&init_mm, address);
-       flush_cache_all();
-       if (address >= end)
-               BUG();
-       spin_lock(&init_mm.page_table_lock);
-       do {
-               pmd_t *pmd;
-               pmd = pmd_alloc(&init_mm, dir, address);
-               error = -ENOMEM;
-               if (!pmd)
-                       break;
-               if (remap_area_pmd(pmd, address, end - address,
-                                        phys_addr + address, flags))
-                       break;
-               error = 0;
-               address = (address + PGDIR_SIZE) & PGDIR_MASK;
-               dir++;
-       } while (address && (address < end));
-       spin_unlock(&init_mm.page_table_lock);
-       flush_tlb_all();
-       return error;
-}
-
-/*
- * Allow physical addresses to be fixed up to help 36 bit peripherals.
- */
-phys_t __attribute__ ((weak))
-fixup_bigphys_addr(phys_t phys_addr, phys_t size)
-{
-       return phys_addr;
-}
+#include <linux/io.h>
 
 /*
  * Generic mapping function (not visible outside):
@@ -121,12 +30,13 @@ fixup_bigphys_addr(phys_t phys_addr, phys_t size)
 
 #define IS_LOW512(addr) (!((phys_t)(addr) & (phys_t) ~0x1fffffffULL))
 
-void * __ioremap(phys_t phys_addr, phys_t size, unsigned long flags)
+void __iomem * __ioremap(phys_t phys_addr, phys_t size, unsigned long flags)
 {
        struct vm_struct * area;
        unsigned long offset;
        phys_t last_addr;
        void * addr;
+       pgprot_t pgprot;
 
        phys_addr = fixup_bigphys_addr(phys_addr, size);
 
@@ -141,7 +51,7 @@ void * __ioremap(phys_t phys_addr, phys_t size, unsigned long flags)
         */
        if (IS_LOW512(phys_addr) && IS_LOW512(last_addr) &&
            flags == _CACHE_UNCACHED)
-               return (void *) KSEG1ADDR(phys_addr);
+               return (void __iomem *) CKSEG1ADDR(phys_addr);
 
        /*
         * Don't allow anybody to remap normal RAM that we're using..
@@ -158,6 +68,9 @@ void * __ioremap(phys_t phys_addr, phys_t size, unsigned long flags)
                                return NULL;
        }
 
+       pgprot = __pgprot(_PAGE_GLOBAL | _PAGE_PRESENT | __READABLE
+                         | __WRITEABLE | flags);
+
        /*
         * Mappings have to be page-aligned
         */
@@ -172,17 +85,18 @@ void * __ioremap(phys_t phys_addr, phys_t size, unsigned long flags)
        if (!area)
                return NULL;
        addr = area->addr;
-       if (remap_area_pages((unsigned long) addr, phys_addr, size, flags)) {
+       if (ioremap_page_range((unsigned long)addr, (unsigned long)addr + size,
+                              phys_addr, pgprot)) {
                vunmap(addr);
                return NULL;
        }
 
-       return (void *) (offset + (char *)addr);
+       return (void __iomem *) (offset + (char *)addr);
 }
 
-#define IS_KSEG1(addr) (((unsigned long)(addr) & ~0x1fffffffUL) == KSEG1)
+#define IS_KSEG1(addr) (((unsigned long)(addr) & ~0x1fffffffUL) == CKSEG1)
 
-void __iounmap(volatile void __iomem *addr)
+void __iounmap(const volatile void __iomem *addr)
 {
        struct vm_struct *p;
 
@@ -190,10 +104,8 @@ void __iounmap(volatile void __iomem *addr)
                return;
 
        p = remove_vm_area((void *) (PAGE_MASK & (unsigned long __force) addr));
-       if (!p) {
+       if (!p)
                printk(KERN_ERR "iounmap: bad address %p\n", addr);
-               return;
-       }
 
         kfree(p);
 }