[POWERPC] Add spinlock to request_phb_iospace()
[safe/jmp/linux-2.6] / arch / powerpc / mm / pgtable_64.c
index 9008424..ad6e135 100644 (file)
@@ -22,7 +22,6 @@
  *
  */
 
-#include <linux/config.h>
 #include <linux/signal.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
 #include <asm/iommu.h>
 #include <asm/abs_addr.h>
 #include <asm/vdso.h>
-#include <asm/imalloc.h>
+#include <asm/firmware.h>
+
+#include "mmu_decl.h"
 
 unsigned long ioremap_bot = IMALLOC_BASE;
 static unsigned long phbs_io_bot = PHBS_IO_BASE;
 
-#ifdef CONFIG_PPC_ISERIES
-
-void __iomem *ioremap(unsigned long addr, unsigned long size)
-{
-       return (void __iomem *)addr;
-}
-
-extern void __iomem *__ioremap(unsigned long addr, unsigned long size,
-                      unsigned long flags)
-{
-       return (void __iomem *)addr;
-}
-
-void iounmap(volatile void __iomem *addr)
-{
-       return;
-}
-
-#else
-
 /*
  * map_io_page currently only called by __ioremap
  * map_io_page adds an entry to the ioremap page table
@@ -122,14 +103,17 @@ static int map_io_page(unsigned long ea, unsigned long pa, int flags)
                 *
                 */
                if (htab_bolt_mapping(ea, ea + PAGE_SIZE, pa, flags,
-                                     mmu_virtual_psize))
-                       panic("Can't map bolted IO mapping");
+                                     mmu_io_psize)) {
+                       printk(KERN_ERR "Failed to do bolted mapping IO "
+                              "memory at %016lx !\n", pa);
+                       return -ENOMEM;
+               }
        }
        return 0;
 }
 
 
-static void __iomem * __ioremap_com(unsigned long addr, unsigned long pa,
+static void __iomem * __ioremap_com(phys_addr_t addr, unsigned long pa,
                            unsigned long ea, unsigned long size,
                            unsigned long flags)
 {
@@ -145,14 +129,7 @@ static void __iomem * __ioremap_com(unsigned long addr, unsigned long pa,
        return (void __iomem *) (ea + (addr & ~PAGE_MASK));
 }
 
-
-void __iomem *
-ioremap(unsigned long addr, unsigned long size)
-{
-       return __ioremap(addr, size, _PAGE_NO_CACHE | _PAGE_GUARDED);
-}
-
-void __iomem * __ioremap(unsigned long addr, unsigned long size,
+void __iomem * __ioremap(phys_addr_t addr, unsigned long size,
                         unsigned long flags)
 {
        unsigned long pa, ea;
@@ -170,7 +147,7 @@ void __iomem * __ioremap(unsigned long addr, unsigned long size,
        pa = addr & PAGE_MASK;
        size = PAGE_ALIGN(addr + size) - pa;
 
-       if (size == 0)
+       if ((size == 0) || (pa == 0))
                return NULL;
 
        if (mem_init_done) {
@@ -191,9 +168,28 @@ void __iomem * __ioremap(unsigned long addr, unsigned long size,
        return ret;
 }
 
+
+void __iomem * ioremap(phys_addr_t addr, unsigned long size)
+{
+       unsigned long flags = _PAGE_NO_CACHE | _PAGE_GUARDED;
+
+       if (ppc_md.ioremap)
+               return ppc_md.ioremap(addr, size, flags);
+       return __ioremap(addr, size, flags);
+}
+
+void __iomem * ioremap_flags(phys_addr_t addr, unsigned long size,
+                            unsigned long flags)
+{
+       if (ppc_md.ioremap)
+               return ppc_md.ioremap(addr, size, flags);
+       return __ioremap(addr, size, flags);
+}
+
+
 #define IS_PAGE_ALIGNED(_val) ((_val) == ((_val) & PAGE_MASK))
 
-int __ioremap_explicit(unsigned long pa, unsigned long ea,
+int __ioremap_explicit(phys_addr_t pa, unsigned long ea,
                       unsigned long size, unsigned long flags)
 {
        struct vm_struct *area;
@@ -248,7 +244,7 @@ int __ioremap_explicit(unsigned long pa, unsigned long ea,
  *
  * XXX what about calls before mem_init_done (ie python_countermeasures())
  */
-void iounmap(volatile void __iomem *token)
+void __iounmap(volatile void __iomem *token)
 {
        void *addr;
 
@@ -260,6 +256,14 @@ void iounmap(volatile void __iomem *token)
        im_free(addr);
 }
 
+void iounmap(volatile void __iomem *token)
+{
+       if (ppc_md.iounmap)
+               ppc_md.iounmap(token);
+       else
+               __iounmap(token);
+}
+
 static int iounmap_subset_regions(unsigned long addr, unsigned long size)
 {
        struct vm_struct *area;
@@ -278,7 +282,7 @@ static int iounmap_subset_regions(unsigned long addr, unsigned long size)
        return 0;
 }
 
-int iounmap_explicit(volatile void __iomem *start, unsigned long size)
+int __iounmap_explicit(volatile void __iomem *start, unsigned long size)
 {
        struct vm_struct *area;
        unsigned long addr;
@@ -312,11 +316,13 @@ int iounmap_explicit(volatile void __iomem *start, unsigned long size)
        return 0;
 }
 
-#endif
-
 EXPORT_SYMBOL(ioremap);
+EXPORT_SYMBOL(ioremap_flags);
 EXPORT_SYMBOL(__ioremap);
 EXPORT_SYMBOL(iounmap);
+EXPORT_SYMBOL(__iounmap);
+
+static DEFINE_SPINLOCK(phb_io_lock);
 
 void __iomem * reserve_phb_iospace(unsigned long size)
 {
@@ -325,8 +331,10 @@ void __iomem * reserve_phb_iospace(unsigned long size)
        if (phbs_io_bot >= IMALLOC_BASE) 
                panic("reserve_phb_iospace(): phb io space overflow\n");
                        
+       spin_lock(&phb_io_lock);
        virt_addr = (void __iomem *) phbs_io_bot;
        phbs_io_bot += size;
+       spin_unlock(&phb_io_lock);
 
        return virt_addr;
 }