Merge master.kernel.org:/home/rmk/linux-2.6-arm
authorLinus Torvalds <torvalds@woody.osdl.org>
Mon, 8 Jan 2007 23:06:39 +0000 (15:06 -0800)
committerLinus Torvalds <torvalds@woody.osdl.org>
Mon, 8 Jan 2007 23:06:39 +0000 (15:06 -0800)
* master.kernel.org:/home/rmk/linux-2.6-arm:
  [ARM] Provide basic printk_clock() implementation
  [ARM] Resolve fuse and direct-IO failures due to missing cache flushes
  [ARM] pass vma for flush_anon_page()
  [ARM] Fix potential MMCI bug
  [ARM] Fix kernel-mode undefined instruction aborts
  [ARM] 4082/1: iop3xx: fix iop33x gpio register offset
  [ARM] 4070/1: arch/arm/kernel: fix warnings from missing includes
  [ARM] 4079/1: iop: Update MAINTAINERS

13 files changed:
Documentation/cachetlb.txt
MAINTAINERS
arch/arm/kernel/entry-armv.S
arch/arm/kernel/time.c
arch/arm/kernel/traps.c
arch/arm/mm/flush.c
drivers/mmc/mmci.c
include/asm-arm/arch-iop32x/iop32x.h
include/asm-arm/cacheflush.h
include/asm-arm/hardware/iop3xx.h
include/asm-parisc/cacheflush.h
include/linux/highmem.h
mm/memory.c

index 73e794f..debf681 100644 (file)
@@ -373,14 +373,15 @@ maps this page at its virtual address.
        likely that you will need to flush the instruction cache
        for copy_to_user_page().
 
-  void flush_anon_page(struct page *page, unsigned long vmaddr)
+  void flush_anon_page(struct vm_area_struct *vma, struct page *page,
+                       unsigned long vmaddr)
        When the kernel needs to access the contents of an anonymous
        page, it calls this function (currently only
        get_user_pages()).  Note: flush_dcache_page() deliberately
        doesn't work for an anonymous page.  The default
        implementation is a nop (and should remain so for all coherent
        architectures).  For incoherent architectures, it should flush
-       the cache of the page at vmaddr in the current user process.
+       the cache of the page at vmaddr.
 
   void flush_kernel_dcache_page(struct page *page)
        When the kernel needs to modify a user page is has obtained
index 2bd34ef..4ccc5fa 100644 (file)
@@ -412,20 +412,32 @@ S:      Maintained
 ARM/INTEL IOP32X ARM ARCHITECTURE
 P:     Lennert Buytenhek
 M:     kernel@wantstofly.org
+P:     Dan Williams
+M:     dan.j.williams@intel.com
 L:     linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
-S:     Maintained
+S:     Supported
+
+ARM/INTEL IOP33X ARM ARCHITECTURE
+P:     Dan Williams
+M:     dan.j.williams@intel.com
+L:     linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
+S:     Supported
 
 ARM/INTEL IOP13XX ARM ARCHITECTURE
 P:     Lennert Buytenhek
 M:     kernel@wantstofly.org
+P:     Dan Williams
+M:     dan.j.williams@intel.com
 L:     linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
-S:     Maintained
+S:     Supported
 
 ARM/INTEL IQ81342EX MACHINE SUPPORT
 P:     Lennert Buytenhek
 M:     kernel@wantstofly.org
+P:     Dan Williams
+M:     dan.j.williams@intel.com
 L:     linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
-S:     Maintained
+S:     Supported
 
 ARM/INTEL IXP2000 ARM ARCHITECTURE
 P:     Lennert Buytenhek
@@ -448,8 +460,10 @@ S: Maintained
 ARM/INTEL XSC3 (MANZANO) ARM CORE
 P:     Lennert Buytenhek
 M:     kernel@wantstofly.org
+P:     Dan Williams
+M:     dan.j.williams@intel.com
 L:     linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
-S:     Maintained
+S:     Supported
 
 ARM/IP FABRICS DOUBLE ESPRESSO MACHINE SUPPORT
 P:     Lennert Buytenhek
index 2db42b1..8517c3c 100644 (file)
@@ -436,7 +436,7 @@ __und_usr:
        usr_entry
 
        tst     r3, #PSR_T_BIT                  @ Thumb mode?
-       bne     fpundefinstr                    @ ignore FP
+       bne     __und_usr_unknown               @ ignore FP
        sub     r4, r2, #4
 
        @
@@ -448,7 +448,7 @@ __und_usr:
        @
 1:     ldrt    r0, [r4]
        adr     r9, ret_from_exception
-       adr     lr, fpundefinstr
+       adr     lr, __und_usr_unknown
        @
        @ fallthrough to call_fpe
        @
@@ -476,7 +476,9 @@ __und_usr:
  * Emulators may wish to make use of the following registers:
  *  r0  = instruction opcode.
  *  r2  = PC+4
+ *  r9  = normal "successful" return address
  *  r10 = this threads thread_info structure.
+ *  lr  = unrecognised instruction return address
  */
 call_fpe:
        tst     r0, #0x08000000                 @ only CDP/CPRT/LDC/STC have bit 27
@@ -545,10 +547,12 @@ do_fpe:
 
        .data
 ENTRY(fp_enter)
-       .word   fpundefinstr
+       .word   no_fp
        .text
 
-fpundefinstr:
+no_fp: mov     pc, lr
+
+__und_usr_unknown:
        mov     r0, sp
        adr     lr, ret_from_exception
        b       do_undefinstr
index 6ff5e3f..3c8cdcf 100644 (file)
@@ -29,6 +29,8 @@
 #include <linux/timer.h>
 #include <linux/irq.h>
 
+#include <linux/mc146818rtc.h>
+
 #include <asm/leds.h>
 #include <asm/thread_info.h>
 #include <asm/mach/time.h>
@@ -85,6 +87,17 @@ unsigned long long __attribute__((weak)) sched_clock(void)
        return (unsigned long long)jiffies * (1000000000 / HZ);
 }
 
+/*
+ * An implementation of printk_clock() independent from
+ * sched_clock().  This avoids non-bootable kernels when
+ * printk_clock is enabled.
+ */
+unsigned long long printk_clock(void)
+{
+       return (unsigned long long)(jiffies - INITIAL_JIFFIES) *
+                       (1000000000 / HZ);
+}
+
 static unsigned long next_rtc_update;
 
 /*
index 042a129..9089156 100644 (file)
@@ -27,6 +27,7 @@
 #include <asm/uaccess.h>
 #include <asm/unistd.h>
 #include <asm/traps.h>
+#include <asm/io.h>
 
 #include "ptrace.h"
 #include "signal.h"
index 628348c..9df507d 100644 (file)
@@ -202,3 +202,42 @@ void flush_dcache_page(struct page *page)
        }
 }
 EXPORT_SYMBOL(flush_dcache_page);
+
+/*
+ * Flush an anonymous page so that users of get_user_pages()
+ * can safely access the data.  The expected sequence is:
+ *
+ *  get_user_pages()
+ *    -> flush_anon_page
+ *  memcpy() to/from page
+ *  if written to page, flush_dcache_page()
+ */
+void __flush_anon_page(struct vm_area_struct *vma, struct page *page, unsigned long vmaddr)
+{
+       unsigned long pfn;
+
+       /* VIPT non-aliasing caches need do nothing */
+       if (cache_is_vipt_nonaliasing())
+               return;
+
+       /*
+        * Write back and invalidate userspace mapping.
+        */
+       pfn = page_to_pfn(page);
+       if (cache_is_vivt()) {
+               flush_cache_page(vma, vmaddr, pfn);
+       } else {
+               /*
+                * For aliasing VIPT, we can flush an alias of the
+                * userspace address only.
+                */
+               flush_pfn_alias(pfn, vmaddr);
+       }
+
+       /*
+        * Invalidate kernel mapping.  No data should be contained
+        * in this mapping of the page.  FIXME: this is overkill
+        * since we actually ask for a write-back and invalidate.
+        */
+       __cpuc_flush_dcache_page(page_address(page));
+}
index e9b80e9..ccfe656 100644 (file)
@@ -42,6 +42,8 @@ mmci_request_end(struct mmci_host *host, struct mmc_request *mrq)
 {
        writel(0, host->base + MMCICOMMAND);
 
+       BUG_ON(host->data);
+
        host->mrq = NULL;
        host->cmd = NULL;
 
@@ -198,6 +200,8 @@ mmci_cmd_irq(struct mmci_host *host, struct mmc_command *cmd,
        }
 
        if (!cmd->data || cmd->error != MMC_ERR_NONE) {
+               if (host->data)
+                       mmci_stop_data(host);
                mmci_request_end(host, cmd->mrq);
        } else if (!(cmd->data->flags & MMC_DATA_READ)) {
                mmci_start_data(host, cmd->data);
index 4bbd85f..2e94690 100644 (file)
@@ -19,7 +19,7 @@
  * Peripherals that are shared between the iop32x and iop33x but
  * located at different addresses.
  */
-#define IOP3XX_GPIO_REG(reg)   (IOP3XX_PERIPHERAL_VIRT_BASE + 0x07c0 + (reg))
+#define IOP3XX_GPIO_REG(reg)   (IOP3XX_PERIPHERAL_VIRT_BASE + 0x07c4 + (reg))
 #define IOP3XX_TIMER_REG(reg)  (IOP3XX_PERIPHERAL_VIRT_BASE + 0x07e0 + (reg))
 
 #include <asm/hardware/iop3xx.h>
index d510495..5f531ea 100644 (file)
@@ -357,6 +357,16 @@ extern void flush_dcache_page(struct page *);
 
 extern void __flush_dcache_page(struct address_space *mapping, struct page *page);
 
+#define ARCH_HAS_FLUSH_ANON_PAGE
+static inline void flush_anon_page(struct vm_area_struct *vma,
+                        struct page *page, unsigned long vmaddr)
+{
+       extern void __flush_anon_page(struct vm_area_struct *vma,
+                               struct page *, unsigned long);
+       if (PageAnon(page))
+               __flush_anon_page(vma, page, vmaddr);
+}
+
 #define flush_dcache_mmap_lock(mapping) \
        write_lock_irq(&(mapping)->tree_lock)
 #define flush_dcache_mmap_unlock(mapping) \
index 1018a74..13ac8a4 100644 (file)
@@ -168,9 +168,9 @@ extern void gpio_line_set(int line, int value);
 #define IOP3XX_PERCR0          (volatile u32 *)IOP3XX_REG_ADDR(0x0710)
 
 /* General Purpose I/O  */
-#define IOP3XX_GPOE            (volatile u32 *)IOP3XX_GPIO_REG(0x0004)
-#define IOP3XX_GPID            (volatile u32 *)IOP3XX_GPIO_REG(0x0008)
-#define IOP3XX_GPOD            (volatile u32 *)IOP3XX_GPIO_REG(0x000c)
+#define IOP3XX_GPOE            (volatile u32 *)IOP3XX_GPIO_REG(0x0000)
+#define IOP3XX_GPID            (volatile u32 *)IOP3XX_GPIO_REG(0x0004)
+#define IOP3XX_GPOD            (volatile u32 *)IOP3XX_GPIO_REG(0x0008)
 
 /* Timers  */
 #define IOP3XX_TU_TMR0         (volatile u32 *)IOP3XX_TIMER_REG(0x0000)
index aedb051..a799dd8 100644 (file)
@@ -186,7 +186,7 @@ flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr, unsigned long
 }
 
 static inline void
-flush_anon_page(struct page *page, unsigned long vmaddr)
+flush_anon_page(struct vm_area_struct *vma, struct page *page, unsigned long vmaddr)
 {
        if (PageAnon(page))
                flush_user_dcache_page(vmaddr);
index ca9a602..645d440 100644 (file)
@@ -8,7 +8,7 @@
 #include <asm/cacheflush.h>
 
 #ifndef ARCH_HAS_FLUSH_ANON_PAGE
-static inline void flush_anon_page(struct page *page, unsigned long vmaddr)
+static inline void flush_anon_page(struct vm_area_struct *vma, struct page *page, unsigned long vmaddr)
 {
 }
 #endif
index 563792f..af227d2 100644 (file)
@@ -1091,7 +1091,7 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
                        if (pages) {
                                pages[i] = page;
 
-                               flush_anon_page(page, start);
+                               flush_anon_page(vma, page, start);
                                flush_dcache_page(page);
                        }
                        if (vmas)