Merge branch 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-linus
authorLinus Torvalds <torvalds@linux-foundation.org>
Sun, 7 Sep 2008 02:32:21 +0000 (19:32 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sun, 7 Sep 2008 02:32:21 +0000 (19:32 -0700)
* 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-linus:
  [MIPS] Probe initrd header only if explicitly specified
  [MIPS] TX39xx: Add missing local_flush_icache_range initialization
  [MIPS] TXx9: Fix txx9_pcode initialization
  [MIPS] Fix WARNING: at kernel/smp.c:290
  [MIPS] Fix data bus error recovery

arch/mips/Kconfig
arch/mips/kernel/setup.c
arch/mips/kernel/traps.c
arch/mips/mm/c-r3k.c
arch/mips/mm/c-r4k.c
arch/mips/mm/c-tx39.c
arch/mips/mm/cache.c
arch/mips/mm/tlbex.c
arch/mips/txx9/generic/setup.c
include/asm-mips/cacheflush.h

index 4da736e25333abc8ce46440dcb8b97c4c9f2be9d..49896a2a1d722e0760a866487f8b80b7d8af8fb0 100644 (file)
@@ -1886,6 +1886,15 @@ config STACKTRACE_SUPPORT
 
 source "init/Kconfig"
 
+config PROBE_INITRD_HEADER
+       bool "Probe initrd header created by addinitrd"
+       depends on BLK_DEV_INITRD
+       help
+         Probe initrd header at the last page of kernel image.
+         Say Y here if you are using arch/mips/boot/addinitrd.c to
+         add initrd or initramfs image to the kernel image.
+         Otherwise, say N.
+
 menu "Bus options (PCI, PCMCIA, EISA, ISA, TC)"
 
 config HW_HAS_EISA
index 2aae76bce29355183f9697cb314dec3306d89af5..16f8edfe5cdce81a63d850980cb0dda08e94049f 100644 (file)
@@ -160,30 +160,33 @@ early_param("rd_size", rd_size_early);
 static unsigned long __init init_initrd(void)
 {
        unsigned long end;
-       u32 *initrd_header;
 
        /*
         * Board specific code or command line parser should have
         * already set up initrd_start and initrd_end. In these cases
         * perfom sanity checks and use them if all looks good.
         */
-       if (initrd_start && initrd_end > initrd_start)
-               goto sanitize;
+       if (!initrd_start || initrd_end <= initrd_start) {
+#ifdef CONFIG_PROBE_INITRD_HEADER
+               u32 *initrd_header;
 
-       /*
-        * See if initrd has been added to the kernel image by
-        * arch/mips/boot/addinitrd.c. In that case a header is
-        * prepended to initrd and is made up by 8 bytes. The fisrt
-        * word is a magic number and the second one is the size of
-        * initrd.  Initrd start must be page aligned in any cases.
-        */
-       initrd_header = __va(PAGE_ALIGN(__pa_symbol(&_end) + 8)) - 8;
-       if (initrd_header[0] != 0x494E5244)
+               /*
+                * See if initrd has been added to the kernel image by
+                * arch/mips/boot/addinitrd.c. In that case a header is
+                * prepended to initrd and is made up by 8 bytes. The first
+                * word is a magic number and the second one is the size of
+                * initrd.  Initrd start must be page aligned in any cases.
+                */
+               initrd_header = __va(PAGE_ALIGN(__pa_symbol(&_end) + 8)) - 8;
+               if (initrd_header[0] != 0x494E5244)
+                       goto disable;
+               initrd_start = (unsigned long)(initrd_header + 2);
+               initrd_end = initrd_start + initrd_header[1];
+#else
                goto disable;
-       initrd_start = (unsigned long)(initrd_header + 2);
-       initrd_end = initrd_start + initrd_header[1];
+#endif
+       }
 
-sanitize:
        if (initrd_start & ~PAGE_MASK) {
                pr_err("initrd start must be page aligned\n");
                goto disable;
index 426cced1e9dce3e4d6e560fad38d26136a8c02e9..6bee29097a565e71459f80ee75c3affd3d0ed25b 100644 (file)
@@ -373,8 +373,8 @@ void __noreturn die(const char * str, const struct pt_regs * regs)
        do_exit(SIGSEGV);
 }
 
-extern const struct exception_table_entry __start___dbe_table[];
-extern const struct exception_table_entry __stop___dbe_table[];
+extern struct exception_table_entry __start___dbe_table[];
+extern struct exception_table_entry __stop___dbe_table[];
 
 __asm__(
 "      .section        __dbe_table, \"a\"\n"
@@ -1200,7 +1200,7 @@ void *set_except_vector(int n, void *addr)
        if (n == 0 && cpu_has_divec) {
                *(u32 *)(ebase + 0x200) = 0x08000000 |
                                          (0x03ffffff & (handler >> 2));
-               flush_icache_range(ebase + 0x200, ebase + 0x204);
+               local_flush_icache_range(ebase + 0x200, ebase + 0x204);
        }
        return (void *)old_handler;
 }
@@ -1283,7 +1283,8 @@ static void *set_vi_srs_handler(int n, vi_handler_t addr, int srs)
                *w = (*w & 0xffff0000) | (((u32)handler >> 16) & 0xffff);
                w = (u32 *)(b + ori_offset);
                *w = (*w & 0xffff0000) | ((u32)handler & 0xffff);
-               flush_icache_range((unsigned long)b, (unsigned long)(b+handler_len));
+               local_flush_icache_range((unsigned long)b,
+                                        (unsigned long)(b+handler_len));
        }
        else {
                /*
@@ -1295,7 +1296,8 @@ static void *set_vi_srs_handler(int n, vi_handler_t addr, int srs)
                w = (u32 *)b;
                *w++ = 0x08000000 | (((u32)handler >> 2) & 0x03fffff); /* j handler */
                *w = 0;
-               flush_icache_range((unsigned long)b, (unsigned long)(b+8));
+               local_flush_icache_range((unsigned long)b,
+                                        (unsigned long)(b+8));
        }
 
        return (void *)old_handler;
@@ -1515,7 +1517,7 @@ void __cpuinit per_cpu_trap_init(void)
 void __init set_handler(unsigned long offset, void *addr, unsigned long size)
 {
        memcpy((void *)(ebase + offset), addr, size);
-       flush_icache_range(ebase + offset, ebase + offset + size);
+       local_flush_icache_range(ebase + offset, ebase + offset + size);
 }
 
 static char panic_null_cerr[] __cpuinitdata =
@@ -1680,6 +1682,8 @@ void __init trap_init(void)
        signal32_init();
 #endif
 
-       flush_icache_range(ebase, ebase + 0x400);
+       local_flush_icache_range(ebase, ebase + 0x400);
        flush_tlb_handlers();
+
+       sort_extable(__start___dbe_table, __stop___dbe_table);
 }
index 27a5b466c85ce0ef4f859ea47402dfd2d77f112c..5500c20c79aeafc491c3b9b43cbe8f5e816e084c 100644 (file)
@@ -320,6 +320,7 @@ void __cpuinit r3k_cache_init(void)
        flush_cache_range = r3k_flush_cache_range;
        flush_cache_page = r3k_flush_cache_page;
        flush_icache_range = r3k_flush_icache_range;
+       local_flush_icache_range = r3k_flush_icache_range;
 
        flush_cache_sigtramp = r3k_flush_cache_sigtramp;
        local_flush_data_cache_page = local_r3k_flush_data_cache_page;
index 71df3390c07bf76608ee9c25f3896f9d93eda94c..6e99665ae860e540cafee642d5d3daf0c1537738 100644 (file)
@@ -543,12 +543,8 @@ struct flush_icache_range_args {
        unsigned long end;
 };
 
-static inline void local_r4k_flush_icache_range(void *args)
+static inline void local_r4k_flush_icache_range(unsigned long start, unsigned long end)
 {
-       struct flush_icache_range_args *fir_args = args;
-       unsigned long start = fir_args->start;
-       unsigned long end = fir_args->end;
-
        if (!cpu_has_ic_fills_f_dc) {
                if (end - start >= dcache_size) {
                        r4k_blast_dcache();
@@ -564,6 +560,15 @@ static inline void local_r4k_flush_icache_range(void *args)
                protected_blast_icache_range(start, end);
 }
 
+static inline void local_r4k_flush_icache_range_ipi(void *args)
+{
+       struct flush_icache_range_args *fir_args = args;
+       unsigned long start = fir_args->start;
+       unsigned long end = fir_args->end;
+
+       local_r4k_flush_icache_range(start, end);
+}
+
 static void r4k_flush_icache_range(unsigned long start, unsigned long end)
 {
        struct flush_icache_range_args args;
@@ -571,7 +576,7 @@ static void r4k_flush_icache_range(unsigned long start, unsigned long end)
        args.start = start;
        args.end = end;
 
-       r4k_on_each_cpu(local_r4k_flush_icache_range, &args, 1);
+       r4k_on_each_cpu(local_r4k_flush_icache_range_ipi, &args, 1);
        instruction_hazard();
 }
 
@@ -1375,6 +1380,7 @@ void __cpuinit r4k_cache_init(void)
        local_flush_data_cache_page     = local_r4k_flush_data_cache_page;
        flush_data_cache_page   = r4k_flush_data_cache_page;
        flush_icache_range      = r4k_flush_icache_range;
+       local_flush_icache_range        = local_r4k_flush_icache_range;
 
 #if defined(CONFIG_DMA_NONCOHERENT)
        if (coherentio) {
index a9f7f1f5e9b4ae90a50993bd06335b77ac8f47f5..f7c8f9ce39c1b1e983d54b6414c3a4bd1a2b8010 100644 (file)
@@ -362,6 +362,7 @@ void __cpuinit tx39_cache_init(void)
                flush_cache_range       = (void *) tx39h_flush_icache_all;
                flush_cache_page        = (void *) tx39h_flush_icache_all;
                flush_icache_range      = (void *) tx39h_flush_icache_all;
+               local_flush_icache_range = (void *) tx39h_flush_icache_all;
 
                flush_cache_sigtramp    = (void *) tx39h_flush_icache_all;
                local_flush_data_cache_page     = (void *) tx39h_flush_icache_all;
@@ -390,6 +391,7 @@ void __cpuinit tx39_cache_init(void)
                flush_cache_range = tx39_flush_cache_range;
                flush_cache_page = tx39_flush_cache_page;
                flush_icache_range = tx39_flush_icache_range;
+               local_flush_icache_range = tx39_flush_icache_range;
 
                flush_cache_sigtramp = tx39_flush_cache_sigtramp;
                local_flush_data_cache_page = local_tx39_flush_data_cache_page;
index 034e8506f6ea712a9554d9f13de28f622d8db1d4..1eb7c71e3d6adfe25916070e180ae87e0b3eedbf 100644 (file)
@@ -29,6 +29,7 @@ void (*flush_cache_range)(struct vm_area_struct *vma, unsigned long start,
 void (*flush_cache_page)(struct vm_area_struct *vma, unsigned long page,
        unsigned long pfn);
 void (*flush_icache_range)(unsigned long start, unsigned long end);
+void (*local_flush_icache_range)(unsigned long start, unsigned long end);
 
 void (*__flush_cache_vmap)(void);
 void (*__flush_cache_vunmap)(void);
index 76da73a5ab3caff4fcf43921ed8a132a8a739897..979cf9197282ca1f315a0ca8430da4d527332cd8 100644 (file)
@@ -1273,10 +1273,10 @@ void __cpuinit build_tlb_refill_handler(void)
 
 void __cpuinit flush_tlb_handlers(void)
 {
-       flush_icache_range((unsigned long)handle_tlbl,
+       local_flush_icache_range((unsigned long)handle_tlbl,
                           (unsigned long)handle_tlbl + sizeof(handle_tlbl));
-       flush_icache_range((unsigned long)handle_tlbs,
+       local_flush_icache_range((unsigned long)handle_tlbs,
                           (unsigned long)handle_tlbs + sizeof(handle_tlbs));
-       flush_icache_range((unsigned long)handle_tlbm,
+       local_flush_icache_range((unsigned long)handle_tlbm,
                           (unsigned long)handle_tlbm + sizeof(handle_tlbm));
 }
index 0afe94c48fb65e82ee283f5fbd2fbce6362dcdb9..fe6bee09cecea23e640a40861a9dcbc4e4adfe94 100644 (file)
@@ -53,6 +53,7 @@ txx9_reg_res_init(unsigned int pcode, unsigned long base, unsigned long size)
                txx9_ce_res[i].name = txx9_ce_res_name[i];
        }
 
+       txx9_pcode = pcode;
        sprintf(txx9_pcode_str, "TX%x", pcode);
        if (base) {
                txx9_reg_res.start = base & 0xfffffffffULL;
index d5c0f2fda51bb0fc8cace8174d2865a3e0a27c98..03b1d69b142fcf4650b1dc16cb0fb1683fe94b88 100644 (file)
@@ -63,6 +63,7 @@ static inline void flush_icache_page(struct vm_area_struct *vma,
 }
 
 extern void (*flush_icache_range)(unsigned long start, unsigned long end);
+extern void (*local_flush_icache_range)(unsigned long start, unsigned long end);
 
 extern void (*__flush_cache_vmap)(void);