]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - arch/sh/mm/pmb.c
include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit...
[net-next-2.6.git] / arch / sh / mm / pmb.c
index 75b8861ec62410391a0d113443e100a462072819..e43ec600afcfbc9b853522ea4df330d1991de589 100644 (file)
@@ -15,7 +15,6 @@
 #include <linux/sysdev.h>
 #include <linux/cpu.h>
 #include <linux/module.h>
-#include <linux/slab.h>
 #include <linux/bitops.h>
 #include <linux/debugfs.h>
 #include <linux/fs.h>
@@ -24,6 +23,7 @@
 #include <linux/io.h>
 #include <linux/spinlock.h>
 #include <linux/vmalloc.h>
+#include <asm/cacheflush.h>
 #include <asm/sizes.h>
 #include <asm/system.h>
 #include <asm/uaccess.h>
@@ -292,9 +292,18 @@ static void pmb_free(struct pmb_entry *pmbe)
  */
 static void __set_pmb_entry(struct pmb_entry *pmbe)
 {
+       unsigned long addr, data;
+
+       addr = mk_pmb_addr(pmbe->entry);
+       data = mk_pmb_data(pmbe->entry);
+
+       jump_to_uncached();
+
        /* Set V-bit */
-       __raw_writel(pmbe->ppn | pmbe->flags | PMB_V, mk_pmb_data(pmbe->entry));
-       __raw_writel(pmbe->vpn | PMB_V, mk_pmb_addr(pmbe->entry));
+       __raw_writel(pmbe->vpn | PMB_V, addr);
+       __raw_writel(pmbe->ppn | pmbe->flags | PMB_V, data);
+
+       back_to_cached();
 }
 
 static void __clear_pmb_entry(struct pmb_entry *pmbe)
@@ -313,6 +322,7 @@ static void __clear_pmb_entry(struct pmb_entry *pmbe)
        writel_uncached(data_val & ~PMB_V, data);
 }
 
+#ifdef CONFIG_PM
 static void set_pmb_entry(struct pmb_entry *pmbe)
 {
        unsigned long flags;
@@ -321,11 +331,13 @@ static void set_pmb_entry(struct pmb_entry *pmbe)
        __set_pmb_entry(pmbe);
        spin_unlock_irqrestore(&pmbe->lock, flags);
 }
+#endif /* CONFIG_PM */
 
 int pmb_bolt_mapping(unsigned long vaddr, phys_addr_t phys,
                     unsigned long size, pgprot_t prot)
 {
        struct pmb_entry *pmbp, *pmbe;
+       unsigned long orig_addr, orig_size;
        unsigned long flags, pmb_flags;
        int i, mapped;
 
@@ -334,6 +346,11 @@ int pmb_bolt_mapping(unsigned long vaddr, phys_addr_t phys,
        if (pmb_mapping_exists(vaddr, phys, size))
                return 0;
 
+       orig_addr = vaddr;
+       orig_size = size;
+
+       flush_tlb_kernel_range(vaddr, vaddr + size);
+
        pmb_flags = pgprot_to_pmb_flags(prot);
        pmbp = NULL;
 
@@ -383,13 +400,15 @@ int pmb_bolt_mapping(unsigned long vaddr, phys_addr_t phys,
                }
        } while (size >= SZ_16M);
 
+       flush_cache_vmap(orig_addr, orig_addr + orig_size);
+
        return 0;
 }
 
 void __iomem *pmb_remap_caller(phys_addr_t phys, unsigned long size,
                               pgprot_t prot, void *caller)
 {
-       unsigned long orig_addr, vaddr;
+       unsigned long vaddr;
        phys_addr_t offset, last_addr;
        phys_addr_t align_mask;
        unsigned long aligned;
@@ -417,19 +436,24 @@ void __iomem *pmb_remap_caller(phys_addr_t phys, unsigned long size,
        phys &= align_mask;
        aligned = ALIGN(last_addr, pmb_sizes[i].size) - phys;
 
-       area = __get_vm_area_caller(aligned, VM_IOREMAP, uncached_end,
+       /*
+        * XXX: This should really start from uncached_end, but this
+        * causes the MMU to reset, so for now we restrict it to the
+        * 0xb000...0xc000 range.
+        */
+       area = __get_vm_area_caller(aligned, VM_IOREMAP, 0xb0000000,
                                    P3SEG, caller);
        if (!area)
                return NULL;
 
        area->phys_addr = phys;
-       orig_addr = vaddr = (unsigned long)area->addr;
+       vaddr = (unsigned long)area->addr;
 
        ret = pmb_bolt_mapping(vaddr, phys, size, prot);
        if (unlikely(ret != 0))
                return ERR_PTR(ret);
 
-       return (void __iomem *)(offset + (char *)orig_addr);
+       return (void __iomem *)(offset + (char *)vaddr);
 }
 
 int pmb_unmap(void __iomem *addr)
@@ -477,6 +501,8 @@ static void __pmb_unmap_entry(struct pmb_entry *pmbe, int depth)
                 */
                __clear_pmb_entry(pmbe);
 
+               flush_cache_vunmap(pmbe->vpn, pmbe->vpn + pmbe->size);
+
                pmbe = pmblink->link;
 
                pmb_free(pmblink);
@@ -777,7 +803,7 @@ void __init pmb_init(void)
        writel_uncached(0, PMB_IRMCR);
 
        /* Flush out the TLB */
-       __raw_writel(__raw_readl(MMUCR) | MMUCR_TI, MMUCR);
+       local_flush_tlb_all();
        ctrl_barrier();
 }
 
@@ -846,7 +872,7 @@ static int __init pmb_debugfs_init(void)
 
        return 0;
 }
-postcore_initcall(pmb_debugfs_init);
+subsys_initcall(pmb_debugfs_init);
 
 #ifdef CONFIG_PM
 static int pmb_sysdev_suspend(struct sys_device *dev, pm_message_t state)