Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
[pandora-kernel.git] / arch / sh / mm / cache-sh4.c
index 8648632..226b190 100644 (file)
@@ -2,7 +2,7 @@
  * arch/sh/mm/cache-sh4.c
  *
  * Copyright (C) 1999, 2000, 2002  Niibe Yutaka
- * Copyright (C) 2001 - 2006  Paul Mundt
+ * Copyright (C) 2001 - 2007  Paul Mundt
  * Copyright (C) 2003  Richard Curnow
  *
  * This file is subject to the terms and conditions of the GNU General Public
@@ -44,7 +44,7 @@ static void (*__flush_dcache_segment_fn)(unsigned long, unsigned long) =
 static void compute_alias(struct cache_info *c)
 {
        c->alias_mask = ((c->sets - 1) << c->entry_shift) & ~(PAGE_SIZE - 1);
-       c->n_aliases = (c->alias_mask >> PAGE_SHIFT) + 1;
+       c->n_aliases = c->alias_mask ? (c->alias_mask >> PAGE_SHIFT) + 1 : 0;
 }
 
 static void __init emit_cache_params(void)
@@ -54,21 +54,35 @@ static void __init emit_cache_params(void)
                ctrl_inl(CCN_CVR),
                ctrl_inl(CCN_PRR));
        printk("I-cache : n_ways=%d n_sets=%d way_incr=%d\n",
-               current_cpu_data.icache.ways,
-               current_cpu_data.icache.sets,
-               current_cpu_data.icache.way_incr);
+               boot_cpu_data.icache.ways,
+               boot_cpu_data.icache.sets,
+               boot_cpu_data.icache.way_incr);
        printk("I-cache : entry_mask=0x%08x alias_mask=0x%08x n_aliases=%d\n",
-               current_cpu_data.icache.entry_mask,
-               current_cpu_data.icache.alias_mask,
-               current_cpu_data.icache.n_aliases);
+               boot_cpu_data.icache.entry_mask,
+               boot_cpu_data.icache.alias_mask,
+               boot_cpu_data.icache.n_aliases);
        printk("D-cache : n_ways=%d n_sets=%d way_incr=%d\n",
-               current_cpu_data.dcache.ways,
-               current_cpu_data.dcache.sets,
-               current_cpu_data.dcache.way_incr);
+               boot_cpu_data.dcache.ways,
+               boot_cpu_data.dcache.sets,
+               boot_cpu_data.dcache.way_incr);
        printk("D-cache : entry_mask=0x%08x alias_mask=0x%08x n_aliases=%d\n",
-               current_cpu_data.dcache.entry_mask,
-               current_cpu_data.dcache.alias_mask,
-               current_cpu_data.dcache.n_aliases);
+               boot_cpu_data.dcache.entry_mask,
+               boot_cpu_data.dcache.alias_mask,
+               boot_cpu_data.dcache.n_aliases);
+
+       /*
+        * Emit Secondary Cache parameters if the CPU has a probed L2.
+        */
+       if (boot_cpu_data.flags & CPU_HAS_L2_CACHE) {
+               printk("S-cache : n_ways=%d n_sets=%d way_incr=%d\n",
+                       boot_cpu_data.scache.ways,
+                       boot_cpu_data.scache.sets,
+                       boot_cpu_data.scache.way_incr);
+               printk("S-cache : entry_mask=0x%08x alias_mask=0x%08x n_aliases=%d\n",
+                       boot_cpu_data.scache.entry_mask,
+                       boot_cpu_data.scache.alias_mask,
+                       boot_cpu_data.scache.n_aliases);
+       }
 
        if (!__flush_dcache_segment_fn)
                panic("unknown number of cache ways\n");
@@ -79,10 +93,11 @@ static void __init emit_cache_params(void)
  */
 void __init p3_cache_init(void)
 {
-       compute_alias(&current_cpu_data.icache);
-       compute_alias(&current_cpu_data.dcache);
+       compute_alias(&boot_cpu_data.icache);
+       compute_alias(&boot_cpu_data.dcache);
+       compute_alias(&boot_cpu_data.scache);
 
-       switch (current_cpu_data.dcache.ways) {
+       switch (boot_cpu_data.dcache.ways) {
        case 1:
                __flush_dcache_segment_fn = __flush_dcache_segment_1way;
                break;
@@ -187,13 +202,13 @@ void flush_cache_sigtramp(unsigned long addr)
                     : "m" (__m(v)));
 
        index = CACHE_IC_ADDRESS_ARRAY |
-                       (v & current_cpu_data.icache.entry_mask);
+                       (v & boot_cpu_data.icache.entry_mask);
 
        local_irq_save(flags);
        jump_to_P2();
 
-       for (i = 0; i < current_cpu_data.icache.ways;
-            i++, index += current_cpu_data.icache.way_incr)
+       for (i = 0; i < boot_cpu_data.icache.ways;
+            i++, index += boot_cpu_data.icache.way_incr)
                ctrl_outl(0, index);    /* Clear out Valid-bit */
 
        back_to_P1();
@@ -210,7 +225,7 @@ static inline void flush_cache_4096(unsigned long start,
         * All types of SH-4 require PC to be in P2 to operate on the I-cache.
         * Some types of SH-4 require PC to be in P2 to operate on the D-cache.
         */
-       if ((current_cpu_data.flags & CPU_HAS_P2_FLUSH_BUG) ||
+       if ((boot_cpu_data.flags & CPU_HAS_P2_FLUSH_BUG) ||
            (start < CACHE_OC_ADDRESS_ARRAY))
                exec_offset = 0x20000000;
 
@@ -232,7 +247,7 @@ void flush_dcache_page(struct page *page)
                int i, n;
 
                /* Loop all the D-cache */
-               n = current_cpu_data.dcache.n_aliases;
+               n = boot_cpu_data.dcache.n_aliases;
                for (i = 0; i < n; i++, addr += 4096)
                        flush_cache_4096(addr, phys);
        }
@@ -264,7 +279,7 @@ static inline void flush_icache_all(void)
 
 void flush_dcache_all(void)
 {
-       (*__flush_dcache_segment_fn)(0UL, current_cpu_data.dcache.way_size);
+       (*__flush_dcache_segment_fn)(0UL, boot_cpu_data.dcache.way_size);
        wmb();
 }
 
@@ -278,8 +293,8 @@ static void __flush_cache_mm(struct mm_struct *mm, unsigned long start,
                             unsigned long end)
 {
        unsigned long d = 0, p = start & PAGE_MASK;
-       unsigned long alias_mask = current_cpu_data.dcache.alias_mask;
-       unsigned long n_aliases = current_cpu_data.dcache.n_aliases;
+       unsigned long alias_mask = boot_cpu_data.dcache.alias_mask;
+       unsigned long n_aliases = boot_cpu_data.dcache.n_aliases;
        unsigned long select_bit;
        unsigned long all_aliases_mask;
        unsigned long addr_offset;
@@ -366,7 +381,7 @@ void flush_cache_mm(struct mm_struct *mm)
         * If cache is only 4k-per-way, there are never any 'aliases'.  Since
         * the cache is physically tagged, the data can just be left in there.
         */
-       if (current_cpu_data.dcache.n_aliases == 0)
+       if (boot_cpu_data.dcache.n_aliases == 0)
                return;
 
        /*
@@ -403,7 +418,7 @@ void flush_cache_page(struct vm_area_struct *vma, unsigned long address,
        unsigned long phys = pfn << PAGE_SHIFT;
        unsigned int alias_mask;
 
-       alias_mask = current_cpu_data.dcache.alias_mask;
+       alias_mask = boot_cpu_data.dcache.alias_mask;
 
        /* We only need to flush D-cache when we have alias */
        if ((address^phys) & alias_mask) {
@@ -417,7 +432,7 @@ void flush_cache_page(struct vm_area_struct *vma, unsigned long address,
                        phys);
        }
 
-       alias_mask = current_cpu_data.icache.alias_mask;
+       alias_mask = boot_cpu_data.icache.alias_mask;
        if (vma->vm_flags & VM_EXEC) {
                /*
                 * Evict entries from the portion of the cache from which code
@@ -449,7 +464,7 @@ void flush_cache_range(struct vm_area_struct *vma, unsigned long start,
         * If cache is only 4k-per-way, there are never any 'aliases'.  Since
         * the cache is physically tagged, the data can just be left in there.
         */
-       if (current_cpu_data.dcache.n_aliases == 0)
+       if (boot_cpu_data.dcache.n_aliases == 0)
                return;
 
        /*
@@ -510,7 +525,7 @@ static void __flush_cache_4096(unsigned long addr, unsigned long phys,
        unsigned long a, ea, p;
        unsigned long temp_pc;
 
-       dcache = &current_cpu_data.dcache;
+       dcache = &boot_cpu_data.dcache;
        /* Write this way for better assembly. */
        way_count = dcache->ways;
        way_incr = dcache->way_incr;
@@ -585,7 +600,7 @@ static void __flush_dcache_segment_1way(unsigned long start,
        base_addr = ((base_addr >> 16) << 16);
        base_addr |= start;
 
-       dcache = &current_cpu_data.dcache;
+       dcache = &boot_cpu_data.dcache;
        linesz = dcache->linesz;
        way_incr = dcache->way_incr;
        way_size = dcache->way_size;
@@ -627,7 +642,7 @@ static void __flush_dcache_segment_2way(unsigned long start,
        base_addr = ((base_addr >> 16) << 16);
        base_addr |= start;
 
-       dcache = &current_cpu_data.dcache;
+       dcache = &boot_cpu_data.dcache;
        linesz = dcache->linesz;
        way_incr = dcache->way_incr;
        way_size = dcache->way_size;
@@ -686,7 +701,7 @@ static void __flush_dcache_segment_4way(unsigned long start,
        base_addr = ((base_addr >> 16) << 16);
        base_addr |= start;
 
-       dcache = &current_cpu_data.dcache;
+       dcache = &boot_cpu_data.dcache;
        linesz = dcache->linesz;
        way_incr = dcache->way_incr;
        way_size = dcache->way_size;