Merge branch 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-linus
authorLinus Torvalds <torvalds@woody.osdl.org>
Mon, 8 Jan 2007 23:07:31 +0000 (15:07 -0800)
committerLinus Torvalds <torvalds@woody.osdl.org>
Mon, 8 Jan 2007 23:07:31 +0000 (15:07 -0800)
* 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-linus:
  [MIPS] PNX8550: Fix system timer support
  [MIPS] TX49: Fix use of CDEX build_store_reg()
  [MIPS] pnx8550: Fix write_config_byte() PCI config space accessor
  [MIPS] Fix build errors on SEAD
  [MIPS] SMTC build fix
  [MIPS] csum_partial and copy in parallel
  [MIPS] Malta: Add missing MTD file.

13 files changed:
arch/mips/kernel/mips_ksyms.c
arch/mips/kernel/time.c
arch/mips/lib/Makefile
arch/mips/lib/csum_partial.S
arch/mips/lib/csum_partial_copy.c [deleted file]
arch/mips/mips-boards/generic/time.c
arch/mips/mips-boards/malta/malta_mtd.c [new file with mode: 0644]
arch/mips/mips-boards/sead/sead_int.c
arch/mips/mm/pg-r4k.c
arch/mips/pci/ops-pnx8550.c
arch/mips/philips/pnx8550/common/time.c
include/asm-mips/checksum.h
include/asm-mips/irq.h

index f44a013..2ef857c 100644 (file)
@@ -46,5 +46,7 @@ EXPORT_SYMBOL(__strnlen_user_nocheck_asm);
 EXPORT_SYMBOL(__strnlen_user_asm);
 
 EXPORT_SYMBOL(csum_partial);
+EXPORT_SYMBOL(csum_partial_copy_nocheck);
+EXPORT_SYMBOL(__csum_partial_copy_user);
 
 EXPORT_SYMBOL(invalid_pte_table);
index 11aab6d..8aa544f 100644 (file)
@@ -94,10 +94,8 @@ static void c0_timer_ack(void)
 {
        unsigned int count;
 
-#ifndef CONFIG_SOC_PNX8550     /* pnx8550 resets to zero */
        /* Ack this timer interrupt and set the next one.  */
        expirelo += cycles_per_jiffy;
-#endif
        write_c0_compare(expirelo);
 
        /* Check to see if we have missed any timer interrupts.  */
index 888b61e..989c900 100644 (file)
@@ -2,7 +2,7 @@
 # Makefile for MIPS-specific library files..
 #
 
-lib-y  += csum_partial.o csum_partial_copy.o memcpy.o promlib.o \
+lib-y  += csum_partial.o memcpy.o promlib.o \
           strlen_user.o strncpy_user.o strnlen_user.o uncached.o
 
 obj-y  += iomap.o
index 9db3572..c0a77fe 100644 (file)
@@ -8,7 +8,9 @@
  * Copyright (C) 1998, 1999 Ralf Baechle
  * Copyright (C) 1999 Silicon Graphics, Inc.
  */
+#include <linux/errno.h>
 #include <asm/asm.h>
+#include <asm/asm-offsets.h>
 #include <asm/regdef.h>
 
 #ifdef CONFIG_64BIT
@@ -271,3 +273,443 @@ small_csumcpy:
        jr      ra
        .set    noreorder
        END(csum_partial)
+
+
+/*
+ * checksum and copy routines based on memcpy.S
+ *
+ *     csum_partial_copy_nocheck(src, dst, len, sum)
+ *     __csum_partial_copy_user(src, dst, len, sum, errp)
+ *
+ * See "Spec" in memcpy.S for details.  Unlike __copy_user, all
+ * function in this file use the standard calling convention.
+ */
+
+#define src a0
+#define dst a1
+#define len a2
+#define psum a3
+#define sum v0
+#define odd t8
+#define errptr t9
+
+/*
+ * The exception handler for loads requires that:
+ *  1- AT contain the address of the byte just past the end of the source
+ *     of the copy,
+ *  2- src_entry <= src < AT, and
+ *  3- (dst - src) == (dst_entry - src_entry),
+ * The _entry suffix denotes values when __copy_user was called.
+ *
+ * (1) is set up up by __csum_partial_copy_from_user and maintained by
+ *     not writing AT in __csum_partial_copy
+ * (2) is met by incrementing src by the number of bytes copied
+ * (3) is met by not doing loads between a pair of increments of dst and src
+ *
+ * The exception handlers for stores stores -EFAULT to errptr and return.
+ * These handlers do not need to overwrite any data.
+ */
+
+#define EXC(inst_reg,addr,handler)             \
+9:     inst_reg, addr;                         \
+       .section __ex_table,"a";                \
+       PTR     9b, handler;                    \
+       .previous
+
+#ifdef USE_DOUBLE
+
+#define LOAD   ld
+#define LOADL  ldl
+#define LOADR  ldr
+#define STOREL sdl
+#define STORER sdr
+#define STORE  sd
+#define ADD    daddu
+#define SUB    dsubu
+#define SRL    dsrl
+#define SLL    dsll
+#define SLLV   dsllv
+#define SRLV   dsrlv
+#define NBYTES 8
+#define LOG_NBYTES 3
+
+#else
+
+#define LOAD   lw
+#define LOADL  lwl
+#define LOADR  lwr
+#define STOREL swl
+#define STORER swr
+#define STORE  sw
+#define ADD    addu
+#define SUB    subu
+#define SRL    srl
+#define SLL    sll
+#define SLLV   sllv
+#define SRLV   srlv
+#define NBYTES 4
+#define LOG_NBYTES 2
+
+#endif /* USE_DOUBLE */
+
+#ifdef CONFIG_CPU_LITTLE_ENDIAN
+#define LDFIRST LOADR
+#define LDREST  LOADL
+#define STFIRST STORER
+#define STREST  STOREL
+#define SHIFT_DISCARD SLLV
+#define SHIFT_DISCARD_REVERT SRLV
+#else
+#define LDFIRST LOADL
+#define LDREST  LOADR
+#define STFIRST STOREL
+#define STREST  STORER
+#define SHIFT_DISCARD SRLV
+#define SHIFT_DISCARD_REVERT SLLV
+#endif
+
+#define FIRST(unit) ((unit)*NBYTES)
+#define REST(unit)  (FIRST(unit)+NBYTES-1)
+
+#define ADDRMASK (NBYTES-1)
+
+       .set    noat
+
+LEAF(__csum_partial_copy_user)
+       PTR_ADDU        AT, src, len    /* See (1) above. */
+#ifdef CONFIG_64BIT
+       move    errptr, a4
+#else
+       lw      errptr, 16(sp)
+#endif
+FEXPORT(csum_partial_copy_nocheck)
+       move    sum, zero
+       move    odd, zero
+       /*
+        * Note: dst & src may be unaligned, len may be 0
+        * Temps
+        */
+       /*
+        * The "issue break"s below are very approximate.
+        * Issue delays for dcache fills will perturb the schedule, as will
+        * load queue full replay traps, etc.
+        *
+        * If len < NBYTES use byte operations.
+        */
+       sltu    t2, len, NBYTES
+       and     t1, dst, ADDRMASK
+       bnez    t2, copy_bytes_checklen
+        and    t0, src, ADDRMASK
+       andi    odd, dst, 0x1                   /* odd buffer? */
+       bnez    t1, dst_unaligned
+        nop
+       bnez    t0, src_unaligned_dst_aligned
+       /*
+        * use delay slot for fall-through
+        * src and dst are aligned; need to compute rem
+        */
+both_aligned:
+        SRL    t0, len, LOG_NBYTES+3    # +3 for 8 units/iter
+       beqz    t0, cleanup_both_aligned # len < 8*NBYTES
+        nop
+       SUB     len, 8*NBYTES           # subtract here for bgez loop
+       .align  4
+1:
+EXC(   LOAD    t0, UNIT(0)(src),       l_exc)
+EXC(   LOAD    t1, UNIT(1)(src),       l_exc_copy)
+EXC(   LOAD    t2, UNIT(2)(src),       l_exc_copy)
+EXC(   LOAD    t3, UNIT(3)(src),       l_exc_copy)
+EXC(   LOAD    t4, UNIT(4)(src),       l_exc_copy)
+EXC(   LOAD    t5, UNIT(5)(src),       l_exc_copy)
+EXC(   LOAD    t6, UNIT(6)(src),       l_exc_copy)
+EXC(   LOAD    t7, UNIT(7)(src),       l_exc_copy)
+       SUB     len, len, 8*NBYTES
+       ADD     src, src, 8*NBYTES
+EXC(   STORE   t0, UNIT(0)(dst),       s_exc)
+       ADDC(sum, t0)
+EXC(   STORE   t1, UNIT(1)(dst),       s_exc)
+       ADDC(sum, t1)
+EXC(   STORE   t2, UNIT(2)(dst),       s_exc)
+       ADDC(sum, t2)
+EXC(   STORE   t3, UNIT(3)(dst),       s_exc)
+       ADDC(sum, t3)
+EXC(   STORE   t4, UNIT(4)(dst),       s_exc)
+       ADDC(sum, t4)
+EXC(   STORE   t5, UNIT(5)(dst),       s_exc)
+       ADDC(sum, t5)
+EXC(   STORE   t6, UNIT(6)(dst),       s_exc)
+       ADDC(sum, t6)
+EXC(   STORE   t7, UNIT(7)(dst),       s_exc)
+       ADDC(sum, t7)
+       bgez    len, 1b
+        ADD    dst, dst, 8*NBYTES
+       ADD     len, 8*NBYTES           # revert len (see above)
+
+       /*
+        * len == the number of bytes left to copy < 8*NBYTES
+        */
+cleanup_both_aligned:
+#define rem t7
+       beqz    len, done
+        sltu   t0, len, 4*NBYTES
+       bnez    t0, less_than_4units
+        and    rem, len, (NBYTES-1)    # rem = len % NBYTES
+       /*
+        * len >= 4*NBYTES
+        */
+EXC(   LOAD    t0, UNIT(0)(src),       l_exc)
+EXC(   LOAD    t1, UNIT(1)(src),       l_exc_copy)
+EXC(   LOAD    t2, UNIT(2)(src),       l_exc_copy)
+EXC(   LOAD    t3, UNIT(3)(src),       l_exc_copy)
+       SUB     len, len, 4*NBYTES
+       ADD     src, src, 4*NBYTES
+EXC(   STORE   t0, UNIT(0)(dst),       s_exc)
+       ADDC(sum, t0)
+EXC(   STORE   t1, UNIT(1)(dst),       s_exc)
+       ADDC(sum, t1)
+EXC(   STORE   t2, UNIT(2)(dst),       s_exc)
+       ADDC(sum, t2)
+EXC(   STORE   t3, UNIT(3)(dst),       s_exc)
+       ADDC(sum, t3)
+       beqz    len, done
+        ADD    dst, dst, 4*NBYTES
+less_than_4units:
+       /*
+        * rem = len % NBYTES
+        */
+       beq     rem, len, copy_bytes
+        nop
+1:
+EXC(   LOAD    t0, 0(src),             l_exc)
+       ADD     src, src, NBYTES
+       SUB     len, len, NBYTES
+EXC(   STORE   t0, 0(dst),             s_exc)
+       ADDC(sum, t0)
+       bne     rem, len, 1b
+        ADD    dst, dst, NBYTES
+
+       /*
+        * src and dst are aligned, need to copy rem bytes (rem < NBYTES)
+        * A loop would do only a byte at a time with possible branch
+        * mispredicts.  Can't do an explicit LOAD dst,mask,or,STORE
+        * because can't assume read-access to dst.  Instead, use
+        * STREST dst, which doesn't require read access to dst.
+        *
+        * This code should perform better than a simple loop on modern,
+        * wide-issue mips processors because the code has fewer branches and
+        * more instruction-level parallelism.
+        */
+#define bits t2
+       beqz    len, done
+        ADD    t1, dst, len    # t1 is just past last byte of dst
+       li      bits, 8*NBYTES
+       SLL     rem, len, 3     # rem = number of bits to keep
+EXC(   LOAD    t0, 0(src),             l_exc)
+       SUB     bits, bits, rem # bits = number of bits to discard
+       SHIFT_DISCARD t0, t0, bits
+EXC(   STREST  t0, -1(t1),             s_exc)
+       SHIFT_DISCARD_REVERT t0, t0, bits
+       .set reorder
+       ADDC(sum, t0)
+       b       done
+       .set noreorder
+dst_unaligned:
+       /*
+        * dst is unaligned
+        * t0 = src & ADDRMASK
+        * t1 = dst & ADDRMASK; T1 > 0
+        * len >= NBYTES
+        *
+        * Copy enough bytes to align dst
+        * Set match = (src and dst have same alignment)
+        */
+#define match rem
+EXC(   LDFIRST t3, FIRST(0)(src),      l_exc)
+       ADD     t2, zero, NBYTES
+EXC(   LDREST  t3, REST(0)(src),       l_exc_copy)
+       SUB     t2, t2, t1      # t2 = number of bytes copied
+       xor     match, t0, t1
+EXC(   STFIRST t3, FIRST(0)(dst),      s_exc)
+       SLL     t4, t1, 3               # t4 = number of bits to discard
+       SHIFT_DISCARD t3, t3, t4
+       /* no SHIFT_DISCARD_REVERT to handle odd buffer properly */
+       ADDC(sum, t3)
+       beq     len, t2, done
+        SUB    len, len, t2
+       ADD     dst, dst, t2
+       beqz    match, both_aligned
+        ADD    src, src, t2
+
+src_unaligned_dst_aligned:
+       SRL     t0, len, LOG_NBYTES+2    # +2 for 4 units/iter
+       beqz    t0, cleanup_src_unaligned
+        and    rem, len, (4*NBYTES-1)   # rem = len % 4*NBYTES
+1:
+/*
+ * Avoid consecutive LD*'s to the same register since some mips
+ * implementations can't issue them in the same cycle.
+ * It's OK to load FIRST(N+1) before REST(N) because the two addresses
+ * are to the same unit (unless src is aligned, but it's not).
+ */
+EXC(   LDFIRST t0, FIRST(0)(src),      l_exc)
+EXC(   LDFIRST t1, FIRST(1)(src),      l_exc_copy)
+       SUB     len, len, 4*NBYTES
+EXC(   LDREST  t0, REST(0)(src),       l_exc_copy)
+EXC(   LDREST  t1, REST(1)(src),       l_exc_copy)
+EXC(   LDFIRST t2, FIRST(2)(src),      l_exc_copy)
+EXC(   LDFIRST t3, FIRST(3)(src),      l_exc_copy)
+EXC(   LDREST  t2, REST(2)(src),       l_exc_copy)
+EXC(   LDREST  t3, REST(3)(src),       l_exc_copy)
+       ADD     src, src, 4*NBYTES
+#ifdef CONFIG_CPU_SB1
+       nop                             # improves slotting
+#endif
+EXC(   STORE   t0, UNIT(0)(dst),       s_exc)
+       ADDC(sum, t0)
+EXC(   STORE   t1, UNIT(1)(dst),       s_exc)
+       ADDC(sum, t1)
+EXC(   STORE   t2, UNIT(2)(dst),       s_exc)
+       ADDC(sum, t2)
+EXC(   STORE   t3, UNIT(3)(dst),       s_exc)
+       ADDC(sum, t3)
+       bne     len, rem, 1b
+        ADD    dst, dst, 4*NBYTES
+
+cleanup_src_unaligned:
+       beqz    len, done
+        and    rem, len, NBYTES-1  # rem = len % NBYTES
+       beq     rem, len, copy_bytes
+        nop
+1:
+EXC(   LDFIRST t0, FIRST(0)(src),      l_exc)
+EXC(   LDREST  t0, REST(0)(src),       l_exc_copy)
+       ADD     src, src, NBYTES
+       SUB     len, len, NBYTES
+EXC(   STORE   t0, 0(dst),             s_exc)
+       ADDC(sum, t0)
+       bne     len, rem, 1b
+        ADD    dst, dst, NBYTES
+
+copy_bytes_checklen:
+       beqz    len, done
+        nop
+copy_bytes:
+       /* 0 < len < NBYTES  */
+#ifdef CONFIG_CPU_LITTLE_ENDIAN
+#define SHIFT_START 0
+#define SHIFT_INC 8
+#else
+#define SHIFT_START 8*(NBYTES-1)
+#define SHIFT_INC -8
+#endif
+       move    t2, zero        # partial word
+       li      t3, SHIFT_START # shift
+/* use l_exc_copy here to return correct sum on fault */
+#define COPY_BYTE(N)                   \
+EXC(   lbu     t0, N(src), l_exc_copy);        \
+       SUB     len, len, 1;            \
+EXC(   sb      t0, N(dst), s_exc);     \
+       SLLV    t0, t0, t3;             \
+       addu    t3, SHIFT_INC;          \
+       beqz    len, copy_bytes_done;   \
+        or     t2, t0
+
+       COPY_BYTE(0)
+       COPY_BYTE(1)
+#ifdef USE_DOUBLE
+       COPY_BYTE(2)
+       COPY_BYTE(3)
+       COPY_BYTE(4)
+       COPY_BYTE(5)
+#endif
+EXC(   lbu     t0, NBYTES-2(src), l_exc_copy)
+       SUB     len, len, 1
+EXC(   sb      t0, NBYTES-2(dst), s_exc)
+       SLLV    t0, t0, t3
+       or      t2, t0
+copy_bytes_done:
+       ADDC(sum, t2)
+done:
+       /* fold checksum */
+#ifdef USE_DOUBLE
+       dsll32  v1, sum, 0
+       daddu   sum, v1
+       sltu    v1, sum, v1
+       dsra32  sum, sum, 0
+       addu    sum, v1
+#endif
+       sll     v1, sum, 16
+       addu    sum, v1
+       sltu    v1, sum, v1
+       srl     sum, sum, 16
+       addu    sum, v1
+
+       /* odd buffer alignment? */
+       beqz    odd, 1f
+        nop
+       sll     v1, sum, 8
+       srl     sum, sum, 8
+       or      sum, v1
+       andi    sum, 0xffff
+1:
+       .set reorder
+       ADDC(sum, psum)
+       jr      ra
+       .set noreorder
+
+l_exc_copy:
+       /*
+        * Copy bytes from src until faulting load address (or until a
+        * lb faults)
+        *
+        * When reached by a faulting LDFIRST/LDREST, THREAD_BUADDR($28)
+        * may be more than a byte beyond the last address.
+        * Hence, the lb below may get an exception.
+        *
+        * Assumes src < THREAD_BUADDR($28)
+        */
+       LOAD    t0, TI_TASK($28)
+        li     t2, SHIFT_START
+       LOAD    t0, THREAD_BUADDR(t0)
+1:
+EXC(   lbu     t1, 0(src),     l_exc)
+       ADD     src, src, 1
+       sb      t1, 0(dst)      # can't fault -- we're copy_from_user
+       SLLV    t1, t1, t2
+       addu    t2, SHIFT_INC
+       ADDC(sum, t1)
+       bne     src, t0, 1b
+        ADD    dst, dst, 1
+l_exc:
+       LOAD    t0, TI_TASK($28)
+        nop
+       LOAD    t0, THREAD_BUADDR(t0)   # t0 is just past last good address
+        nop
+       SUB     len, AT, t0             # len number of uncopied bytes
+       /*
+        * Here's where we rely on src and dst being incremented in tandem,
+        *   See (3) above.
+        * dst += (fault addr - src) to put dst at first byte to clear
+        */
+       ADD     dst, t0                 # compute start address in a1
+       SUB     dst, src
+       /*
+        * Clear len bytes starting at dst.  Can't call __bzero because it
+        * might modify len.  An inefficient loop for these rare times...
+        */
+       beqz    len, done
+        SUB    src, len, 1
+1:     sb      zero, 0(dst)
+       ADD     dst, dst, 1
+       bnez    src, 1b
+        SUB    src, src, 1
+       li      v1, -EFAULT
+       b       done
+        sw     v1, (errptr)
+
+s_exc:
+       li      v0, -1 /* invalid checksum */
+       li      v1, -EFAULT
+       jr      ra
+        sw     v1, (errptr)
+       END(__csum_partial_copy_user)
diff --git a/arch/mips/lib/csum_partial_copy.c b/arch/mips/lib/csum_partial_copy.c
deleted file mode 100644 (file)
index 0677104..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1994, 1995 Waldorf Electronics GmbH
- * Copyright (C) 1998, 1999 Ralf Baechle
- */
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/types.h>
-#include <asm/byteorder.h>
-#include <asm/string.h>
-#include <asm/uaccess.h>
-#include <net/checksum.h>
-
-/*
- * copy while checksumming, otherwise like csum_partial
- */
-__wsum csum_partial_copy_nocheck(const void *src,
-       void *dst, int len, __wsum sum)
-{
-       /*
-        * It's 2:30 am and I don't feel like doing it real ...
-        * This is lots slower than the real thing (tm)
-        */
-       sum = csum_partial(src, len, sum);
-       memcpy(dst, src, len);
-
-       return sum;
-}
-
-EXPORT_SYMBOL(csum_partial_copy_nocheck);
-
-/*
- * Copy from userspace and compute checksum.  If we catch an exception
- * then zero the rest of the buffer.
- */
-__wsum csum_partial_copy_from_user (const void __user *src,
-       void *dst, int len, __wsum sum, int *err_ptr)
-{
-       int missing;
-
-       might_sleep();
-       missing = copy_from_user(dst, src, len);
-       if (missing) {
-               memset(dst + len - missing, 0, missing);
-               *err_ptr = -EFAULT;
-       }
-
-       return csum_partial(dst, len, sum);
-}
index e4604c7..a3c3a1d 100644 (file)
@@ -47,6 +47,9 @@
 #ifdef CONFIG_MIPS_MALTA
 #include <asm/mips-boards/maltaint.h>
 #endif
+#ifdef CONFIG_MIPS_SEAD
+#include <asm/mips-boards/seadint.h>
+#endif
 
 unsigned long cpu_khz;
 
@@ -263,11 +266,13 @@ void __init mips_time_init(void)
 
 void __init plat_timer_setup(struct irqaction *irq)
 {
+#ifdef MSC01E_INT_BASE
        if (cpu_has_veic) {
                set_vi_handler (MSC01E_INT_CPUCTR, mips_timer_dispatch);
                mips_cpu_timer_irq = MSC01E_INT_BASE + MSC01E_INT_CPUCTR;
-       }
-       else {
+       } else
+#endif
+       {
                if (cpu_has_vint)
                        set_vi_handler (MIPSCPU_INT_CPUCTR, mips_timer_dispatch);
                mips_cpu_timer_irq = MIPSCPU_INT_BASE + MIPSCPU_INT_CPUCTR;
diff --git a/arch/mips/mips-boards/malta/malta_mtd.c b/arch/mips/mips-boards/malta/malta_mtd.c
new file mode 100644 (file)
index 0000000..8ad9bdf
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 MIPS Technologies, Inc.
+ *     written by Ralf Baechle <ralf@linux-mips.org>
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <mtd/mtd-abi.h>
+
+static struct mtd_partition malta_mtd_partitions[] = {
+       {
+               .name =         "YAMON",
+               .offset =       0x0,
+               .size =         0x100000,
+               .mask_flags =   MTD_WRITEABLE
+       }, {
+               .name =         "User FS",
+               .offset =       0x100000,
+               .size =         0x2e0000
+       }, {
+               .name =         "Board Config",
+               .offset =       0x3e0000,
+               .size =         0x020000,
+               .mask_flags =   MTD_WRITEABLE
+       }
+};
+
+static struct physmap_flash_data malta_flash_data = {
+       .width          = 4,
+       .nr_parts       = ARRAY_SIZE(malta_mtd_partitions),
+       .parts          = malta_mtd_partitions
+};
+
+static struct resource malta_flash_resource = {
+       .start          = 0x1e000000,
+       .end            = 0x1e3fffff,
+       .flags          = IORESOURCE_MEM
+};
+
+static struct platform_device malta_flash = {
+       .name           = "physmap-flash",
+       .id             = 0,
+       .dev            = {
+               .platform_data  = &malta_flash_data,
+       },
+       .num_resources  = 1,
+       .resource       = &malta_flash_resource,
+};
+
+static int __init malta_mtd_init(void)
+{
+       platform_device_register(&malta_flash);
+
+       return 0;
+}
+
+module_init(malta_mtd_init)
index f445fcd..874ccb0 100644 (file)
@@ -21,7 +21,7 @@
  * Sead board.
  */
 #include <linux/init.h>
-#include <linux/irq.h>
+#include <linux/interrupt.h>
 
 #include <asm/irq_cpu.h>
 #include <asm/mipsregs.h>
@@ -108,7 +108,7 @@ asmlinkage void plat_irq_dispatch(void)
        if (irq >= 0)
                do_IRQ(MIPSCPU_INT_BASE + irq);
        else
-               spurious_interrupt(regs);
+               spurious_interrupt();
 }
 
 void __init arch_init_irq(void)
index d41fc58..dc795be 100644 (file)
@@ -243,11 +243,10 @@ static void __init __build_store_reg(int reg)
 
 static inline void build_store_reg(int reg)
 {
-       if (cpu_has_prefetch)
-               if (reg)
-                       build_dst_pref(pref_offset_copy);
-               else
-                       build_dst_pref(pref_offset_clear);
+       int pref_off = cpu_has_prefetch ?
+               (reg ? pref_offset_copy : pref_offset_clear) : 0;
+       if (pref_off)
+               build_dst_pref(pref_off);
        else if (cpu_has_cache_cdex_s)
                build_cdex_s();
        else if (cpu_has_cache_cdex_p)
index 454b65c..f556b7a 100644 (file)
@@ -202,7 +202,7 @@ write_config_byte(struct pci_bus *bus, unsigned int devfn, int where, u8 val)
                break;
        }
 
-       err = config_access(PCI_CMD_CONFIG_READ, bus, devfn, where, ~(1 << (where & 3)), &data);
+       err = config_access(PCI_CMD_CONFIG_WRITE, bus, devfn, where, ~(1 << (where & 3)), &data);
 
        return err;
 }
index 65c440e..f80acae 100644 (file)
 #include <int.h>
 #include <cm.h>
 
-extern unsigned int mips_hpt_frequency;
+static unsigned long cpj;
+
+static cycle_t hpt_read(void)
+{
+       return read_c0_count2();
+}
+
+static void timer_ack(void)
+{
+       write_c0_compare(cpj);
+}
 
 /*
  * pnx8550_time_init() - it does the following things:
@@ -68,27 +78,47 @@ void pnx8550_time_init(void)
         * HZ timer interrupts per second.
         */
        mips_hpt_frequency = 27UL * ((1000000UL * n)/(m * pow2p));
+       cpj = (mips_hpt_frequency + HZ / 2) / HZ;
+       timer_ack();
+
+       /* Setup Timer 2 */
+       write_c0_count2(0);
+       write_c0_compare2(0xffffffff);
+
+       clocksource_mips.read = hpt_read;
+       mips_timer_ack = timer_ack;
+}
+
+static irqreturn_t monotonic_interrupt(int irq, void *dev_id)
+{
+       /* Timer 2 clear interrupt */
+       write_c0_compare2(-1);
+       return IRQ_HANDLED;
 }
 
+static struct irqaction monotonic_irqaction = {
+       .handler = monotonic_interrupt,
+       .flags = IRQF_DISABLED,
+       .name = "Monotonic timer",
+};
+
 void __init plat_timer_setup(struct irqaction *irq)
 {
        int configPR;
 
        setup_irq(PNX8550_INT_TIMER1, irq);
+       setup_irq(PNX8550_INT_TIMER2, &monotonic_irqaction);
 
-       /* Start timer1 */
+       /* Timer 1 start */
        configPR = read_c0_config7();
        configPR &= ~0x00000008;
        write_c0_config7(configPR);
 
-       /* Timer 2 stop */
+       /* Timer 2 start */
        configPR = read_c0_config7();
-       configPR |= 0x00000010;
+       configPR &= ~0x00000010;
        write_c0_config7(configPR);
 
-       write_c0_count2(0);
-       write_c0_compare2(0xffffffff);
-
        /* Timer 3 stop */
        configPR = read_c0_config7();
        configPR |= 0x00000020;
index 9b768c3..24cdcc6 100644 (file)
  */
 __wsum csum_partial(const void *buff, int len, __wsum sum);
 
+__wsum __csum_partial_copy_user(const void *src, void *dst,
+                               int len, __wsum sum, int *err_ptr);
+
 /*
  * this is a new version of the above that records errors it finds in *errp,
  * but continues and zeros the rest of the buffer.
  */
-__wsum csum_partial_copy_from_user(const void __user *src,
-                                        void *dst, int len,
-                                        __wsum sum, int *errp);
+static inline
+__wsum csum_partial_copy_from_user(const void __user *src, void *dst, int len,
+                                  __wsum sum, int *err_ptr)
+{
+       might_sleep();
+       return __csum_partial_copy_user((__force void *)src, dst,
+                                       len, sum, err_ptr);
+}
 
 /*
  * Copy and checksum to user
  */
 #define HAVE_CSUM_COPY_USER
-static inline __wsum csum_and_copy_to_user (const void *src, void __user *dst,
-                                                 int len, __wsum sum,
-                                                 int *err_ptr)
+static inline
+__wsum csum_and_copy_to_user(const void *src, void __user *dst, int len,
+                            __wsum sum, int *err_ptr)
 {
        might_sleep();
-       sum = csum_partial(src, len, sum);
-
-       if (copy_to_user(dst, src, len)) {
+       if (access_ok(VERIFY_WRITE, dst, len))
+               return __csum_partial_copy_user(src, (__force void *)dst,
+                                               len, sum, err_ptr);
+       if (len)
                *err_ptr = -EFAULT;
-               return (__force __wsum)-1;
-       }
 
-       return sum;
+       return (__force __wsum)-1; /* invalid checksum */
 }
 
 /*
index 6765708..386da82 100644 (file)
@@ -31,14 +31,14 @@ static inline int irq_canonicalize(int irq)
  * functions will take over re-enabling the low-level mask.
  * Otherwise it will be done on return from exception.
  */
-#define __DO_IRQ_SMTC_HOOK()                                           \
+#define __DO_IRQ_SMTC_HOOK(irq)                                                \
 do {                                                                   \
        if (irq_hwmask[irq] & 0x0000ff00)                               \
                write_c0_tccontext(read_c0_tccontext() &                \
                                   ~(irq_hwmask[irq] & 0x0000ff00));    \
 } while (0)
 #else
-#define __DO_IRQ_SMTC_HOOK() do { } while (0)
+#define __DO_IRQ_SMTC_HOOK(irq) do { } while (0)
 #endif
 
 /*
@@ -52,7 +52,7 @@ do {                                                                  \
 #define do_IRQ(irq)                                                    \
 do {                                                                   \
        irq_enter();                                                    \
-       __DO_IRQ_SMTC_HOOK();                                           \
+       __DO_IRQ_SMTC_HOOK(irq);                                        \
        generic_handle_irq(irq);                                        \
        irq_exit();                                                     \
 } while (0)