diff options
| author | Linus Torvalds <torvalds@woody.osdl.org> | 2007-01-08 18:06:39 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@woody.osdl.org> | 2007-01-08 18:06:39 -0500 |
| commit | 74bda9310fe9776f3d940057ac2e7881214577d6 (patch) | |
| tree | 38989eda1ce69bcf580a6b82c977d0862497151c | |
| parent | fea5f1e19611d94fbf3905875a427c4cb959cd06 (diff) | |
| parent | e97126cd9056b3b42cdc862ace2ed66f8026f55b (diff) | |
Merge master.kernel.org:/home/rmk/linux-2.6-arm
* 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
| -rw-r--r-- | Documentation/cachetlb.txt | 5 | ||||
| -rw-r--r-- | MAINTAINERS | 22 | ||||
| -rw-r--r-- | arch/arm/kernel/entry-armv.S | 12 | ||||
| -rw-r--r-- | arch/arm/kernel/time.c | 13 | ||||
| -rw-r--r-- | arch/arm/kernel/traps.c | 1 | ||||
| -rw-r--r-- | arch/arm/mm/flush.c | 39 | ||||
| -rw-r--r-- | drivers/mmc/mmci.c | 4 | ||||
| -rw-r--r-- | include/asm-arm/arch-iop32x/iop32x.h | 2 | ||||
| -rw-r--r-- | include/asm-arm/cacheflush.h | 10 | ||||
| -rw-r--r-- | include/asm-arm/hardware/iop3xx.h | 6 | ||||
| -rw-r--r-- | include/asm-parisc/cacheflush.h | 2 | ||||
| -rw-r--r-- | include/linux/highmem.h | 2 | ||||
| -rw-r--r-- | mm/memory.c | 2 |
13 files changed, 103 insertions, 17 deletions
diff --git a/Documentation/cachetlb.txt b/Documentation/cachetlb.txt index 73e794f0ff09..debf6813934a 100644 --- a/Documentation/cachetlb.txt +++ b/Documentation/cachetlb.txt | |||
| @@ -373,14 +373,15 @@ maps this page at its virtual address. | |||
| 373 | likely that you will need to flush the instruction cache | 373 | likely that you will need to flush the instruction cache |
| 374 | for copy_to_user_page(). | 374 | for copy_to_user_page(). |
| 375 | 375 | ||
| 376 | void flush_anon_page(struct page *page, unsigned long vmaddr) | 376 | void flush_anon_page(struct vm_area_struct *vma, struct page *page, |
| 377 | unsigned long vmaddr) | ||
| 377 | When the kernel needs to access the contents of an anonymous | 378 | When the kernel needs to access the contents of an anonymous |
| 378 | page, it calls this function (currently only | 379 | page, it calls this function (currently only |
| 379 | get_user_pages()). Note: flush_dcache_page() deliberately | 380 | get_user_pages()). Note: flush_dcache_page() deliberately |
| 380 | doesn't work for an anonymous page. The default | 381 | doesn't work for an anonymous page. The default |
| 381 | implementation is a nop (and should remain so for all coherent | 382 | implementation is a nop (and should remain so for all coherent |
| 382 | architectures). For incoherent architectures, it should flush | 383 | architectures). For incoherent architectures, it should flush |
| 383 | the cache of the page at vmaddr in the current user process. | 384 | the cache of the page at vmaddr. |
| 384 | 385 | ||
| 385 | void flush_kernel_dcache_page(struct page *page) | 386 | void flush_kernel_dcache_page(struct page *page) |
| 386 | When the kernel needs to modify a user page is has obtained | 387 | When the kernel needs to modify a user page is has obtained |
diff --git a/MAINTAINERS b/MAINTAINERS index 2bd34ef58ffa..4ccc5fa06d09 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
| @@ -412,20 +412,32 @@ S: Maintained | |||
| 412 | ARM/INTEL IOP32X ARM ARCHITECTURE | 412 | ARM/INTEL IOP32X ARM ARCHITECTURE |
| 413 | P: Lennert Buytenhek | 413 | P: Lennert Buytenhek |
| 414 | M: kernel@wantstofly.org | 414 | M: kernel@wantstofly.org |
| 415 | P: Dan Williams | ||
| 416 | M: dan.j.williams@intel.com | ||
| 415 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) | 417 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) |
| 416 | S: Maintained | 418 | S: Supported |
| 419 | |||
| 420 | ARM/INTEL IOP33X ARM ARCHITECTURE | ||
| 421 | P: Dan Williams | ||
| 422 | M: dan.j.williams@intel.com | ||
| 423 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) | ||
| 424 | S: Supported | ||
| 417 | 425 | ||
| 418 | ARM/INTEL IOP13XX ARM ARCHITECTURE | 426 | ARM/INTEL IOP13XX ARM ARCHITECTURE |
| 419 | P: Lennert Buytenhek | 427 | P: Lennert Buytenhek |
| 420 | M: kernel@wantstofly.org | 428 | M: kernel@wantstofly.org |
| 429 | P: Dan Williams | ||
| 430 | M: dan.j.williams@intel.com | ||
| 421 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) | 431 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) |
| 422 | S: Maintained | 432 | S: Supported |
| 423 | 433 | ||
| 424 | ARM/INTEL IQ81342EX MACHINE SUPPORT | 434 | ARM/INTEL IQ81342EX MACHINE SUPPORT |
| 425 | P: Lennert Buytenhek | 435 | P: Lennert Buytenhek |
| 426 | M: kernel@wantstofly.org | 436 | M: kernel@wantstofly.org |
| 437 | P: Dan Williams | ||
| 438 | M: dan.j.williams@intel.com | ||
| 427 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) | 439 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) |
| 428 | S: Maintained | 440 | S: Supported |
| 429 | 441 | ||
| 430 | ARM/INTEL IXP2000 ARM ARCHITECTURE | 442 | ARM/INTEL IXP2000 ARM ARCHITECTURE |
| 431 | P: Lennert Buytenhek | 443 | P: Lennert Buytenhek |
| @@ -448,8 +460,10 @@ S: Maintained | |||
| 448 | ARM/INTEL XSC3 (MANZANO) ARM CORE | 460 | ARM/INTEL XSC3 (MANZANO) ARM CORE |
| 449 | P: Lennert Buytenhek | 461 | P: Lennert Buytenhek |
| 450 | M: kernel@wantstofly.org | 462 | M: kernel@wantstofly.org |
| 463 | P: Dan Williams | ||
| 464 | M: dan.j.williams@intel.com | ||
| 451 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) | 465 | L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) |
| 452 | S: Maintained | 466 | S: Supported |
| 453 | 467 | ||
| 454 | ARM/IP FABRICS DOUBLE ESPRESSO MACHINE SUPPORT | 468 | ARM/IP FABRICS DOUBLE ESPRESSO MACHINE SUPPORT |
| 455 | P: Lennert Buytenhek | 469 | P: Lennert Buytenhek |
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index 2db42b18f53f..8517c3c3eb33 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S | |||
| @@ -436,7 +436,7 @@ __und_usr: | |||
| 436 | usr_entry | 436 | usr_entry |
| 437 | 437 | ||
| 438 | tst r3, #PSR_T_BIT @ Thumb mode? | 438 | tst r3, #PSR_T_BIT @ Thumb mode? |
| 439 | bne fpundefinstr @ ignore FP | 439 | bne __und_usr_unknown @ ignore FP |
| 440 | sub r4, r2, #4 | 440 | sub r4, r2, #4 |
| 441 | 441 | ||
| 442 | @ | 442 | @ |
| @@ -448,7 +448,7 @@ __und_usr: | |||
| 448 | @ | 448 | @ |
| 449 | 1: ldrt r0, [r4] | 449 | 1: ldrt r0, [r4] |
| 450 | adr r9, ret_from_exception | 450 | adr r9, ret_from_exception |
| 451 | adr lr, fpundefinstr | 451 | adr lr, __und_usr_unknown |
| 452 | @ | 452 | @ |
| 453 | @ fallthrough to call_fpe | 453 | @ fallthrough to call_fpe |
| 454 | @ | 454 | @ |
| @@ -476,7 +476,9 @@ __und_usr: | |||
| 476 | * Emulators may wish to make use of the following registers: | 476 | * Emulators may wish to make use of the following registers: |
| 477 | * r0 = instruction opcode. | 477 | * r0 = instruction opcode. |
| 478 | * r2 = PC+4 | 478 | * r2 = PC+4 |
| 479 | * r9 = normal "successful" return address | ||
| 479 | * r10 = this threads thread_info structure. | 480 | * r10 = this threads thread_info structure. |
| 481 | * lr = unrecognised instruction return address | ||
| 480 | */ | 482 | */ |
| 481 | call_fpe: | 483 | call_fpe: |
| 482 | tst r0, #0x08000000 @ only CDP/CPRT/LDC/STC have bit 27 | 484 | tst r0, #0x08000000 @ only CDP/CPRT/LDC/STC have bit 27 |
| @@ -545,10 +547,12 @@ do_fpe: | |||
| 545 | 547 | ||
| 546 | .data | 548 | .data |
| 547 | ENTRY(fp_enter) | 549 | ENTRY(fp_enter) |
| 548 | .word fpundefinstr | 550 | .word no_fp |
| 549 | .text | 551 | .text |
| 550 | 552 | ||
| 551 | fpundefinstr: | 553 | no_fp: mov pc, lr |
| 554 | |||
| 555 | __und_usr_unknown: | ||
| 552 | mov r0, sp | 556 | mov r0, sp |
| 553 | adr lr, ret_from_exception | 557 | adr lr, ret_from_exception |
| 554 | b do_undefinstr | 558 | b do_undefinstr |
diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c index 6ff5e3ff6cb5..3c8cdcfe8d4a 100644 --- a/arch/arm/kernel/time.c +++ b/arch/arm/kernel/time.c | |||
| @@ -29,6 +29,8 @@ | |||
| 29 | #include <linux/timer.h> | 29 | #include <linux/timer.h> |
| 30 | #include <linux/irq.h> | 30 | #include <linux/irq.h> |
| 31 | 31 | ||
| 32 | #include <linux/mc146818rtc.h> | ||
| 33 | |||
| 32 | #include <asm/leds.h> | 34 | #include <asm/leds.h> |
| 33 | #include <asm/thread_info.h> | 35 | #include <asm/thread_info.h> |
| 34 | #include <asm/mach/time.h> | 36 | #include <asm/mach/time.h> |
| @@ -85,6 +87,17 @@ unsigned long long __attribute__((weak)) sched_clock(void) | |||
| 85 | return (unsigned long long)jiffies * (1000000000 / HZ); | 87 | return (unsigned long long)jiffies * (1000000000 / HZ); |
| 86 | } | 88 | } |
| 87 | 89 | ||
| 90 | /* | ||
| 91 | * An implementation of printk_clock() independent from | ||
| 92 | * sched_clock(). This avoids non-bootable kernels when | ||
| 93 | * printk_clock is enabled. | ||
| 94 | */ | ||
| 95 | unsigned long long printk_clock(void) | ||
| 96 | { | ||
| 97 | return (unsigned long long)(jiffies - INITIAL_JIFFIES) * | ||
| 98 | (1000000000 / HZ); | ||
| 99 | } | ||
| 100 | |||
| 88 | static unsigned long next_rtc_update; | 101 | static unsigned long next_rtc_update; |
| 89 | 102 | ||
| 90 | /* | 103 | /* |
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index 042a12982e98..908915675edc 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c | |||
| @@ -27,6 +27,7 @@ | |||
| 27 | #include <asm/uaccess.h> | 27 | #include <asm/uaccess.h> |
| 28 | #include <asm/unistd.h> | 28 | #include <asm/unistd.h> |
| 29 | #include <asm/traps.h> | 29 | #include <asm/traps.h> |
| 30 | #include <asm/io.h> | ||
| 30 | 31 | ||
| 31 | #include "ptrace.h" | 32 | #include "ptrace.h" |
| 32 | #include "signal.h" | 33 | #include "signal.h" |
diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c index 628348c9f6c5..9df507d36e0b 100644 --- a/arch/arm/mm/flush.c +++ b/arch/arm/mm/flush.c | |||
| @@ -202,3 +202,42 @@ void flush_dcache_page(struct page *page) | |||
| 202 | } | 202 | } |
| 203 | } | 203 | } |
| 204 | EXPORT_SYMBOL(flush_dcache_page); | 204 | EXPORT_SYMBOL(flush_dcache_page); |
| 205 | |||
| 206 | /* | ||
| 207 | * Flush an anonymous page so that users of get_user_pages() | ||
| 208 | * can safely access the data. The expected sequence is: | ||
| 209 | * | ||
| 210 | * get_user_pages() | ||
| 211 | * -> flush_anon_page | ||
| 212 | * memcpy() to/from page | ||
| 213 | * if written to page, flush_dcache_page() | ||
| 214 | */ | ||
| 215 | void __flush_anon_page(struct vm_area_struct *vma, struct page *page, unsigned long vmaddr) | ||
| 216 | { | ||
| 217 | unsigned long pfn; | ||
| 218 | |||
| 219 | /* VIPT non-aliasing caches need do nothing */ | ||
| 220 | if (cache_is_vipt_nonaliasing()) | ||
| 221 | return; | ||
| 222 | |||
| 223 | /* | ||
| 224 | * Write back and invalidate userspace mapping. | ||
| 225 | */ | ||
| 226 | pfn = page_to_pfn(page); | ||
| 227 | if (cache_is_vivt()) { | ||
| 228 | flush_cache_page(vma, vmaddr, pfn); | ||
| 229 | } else { | ||
| 230 | /* | ||
| 231 | * For aliasing VIPT, we can flush an alias of the | ||
| 232 | * userspace address only. | ||
| 233 | */ | ||
| 234 | flush_pfn_alias(pfn, vmaddr); | ||
| 235 | } | ||
| 236 | |||
| 237 | /* | ||
| 238 | * Invalidate kernel mapping. No data should be contained | ||
| 239 | * in this mapping of the page. FIXME: this is overkill | ||
| 240 | * since we actually ask for a write-back and invalidate. | ||
| 241 | */ | ||
| 242 | __cpuc_flush_dcache_page(page_address(page)); | ||
| 243 | } | ||
diff --git a/drivers/mmc/mmci.c b/drivers/mmc/mmci.c index e9b80e920266..ccfe6561be24 100644 --- a/drivers/mmc/mmci.c +++ b/drivers/mmc/mmci.c | |||
| @@ -42,6 +42,8 @@ mmci_request_end(struct mmci_host *host, struct mmc_request *mrq) | |||
| 42 | { | 42 | { |
| 43 | writel(0, host->base + MMCICOMMAND); | 43 | writel(0, host->base + MMCICOMMAND); |
| 44 | 44 | ||
| 45 | BUG_ON(host->data); | ||
| 46 | |||
| 45 | host->mrq = NULL; | 47 | host->mrq = NULL; |
| 46 | host->cmd = NULL; | 48 | host->cmd = NULL; |
| 47 | 49 | ||
| @@ -198,6 +200,8 @@ mmci_cmd_irq(struct mmci_host *host, struct mmc_command *cmd, | |||
| 198 | } | 200 | } |
| 199 | 201 | ||
| 200 | if (!cmd->data || cmd->error != MMC_ERR_NONE) { | 202 | if (!cmd->data || cmd->error != MMC_ERR_NONE) { |
| 203 | if (host->data) | ||
| 204 | mmci_stop_data(host); | ||
| 201 | mmci_request_end(host, cmd->mrq); | 205 | mmci_request_end(host, cmd->mrq); |
| 202 | } else if (!(cmd->data->flags & MMC_DATA_READ)) { | 206 | } else if (!(cmd->data->flags & MMC_DATA_READ)) { |
| 203 | mmci_start_data(host, cmd->data); | 207 | mmci_start_data(host, cmd->data); |
diff --git a/include/asm-arm/arch-iop32x/iop32x.h b/include/asm-arm/arch-iop32x/iop32x.h index 4bbd85f3ed2a..2e9469047eb1 100644 --- a/include/asm-arm/arch-iop32x/iop32x.h +++ b/include/asm-arm/arch-iop32x/iop32x.h | |||
| @@ -19,7 +19,7 @@ | |||
| 19 | * Peripherals that are shared between the iop32x and iop33x but | 19 | * Peripherals that are shared between the iop32x and iop33x but |
| 20 | * located at different addresses. | 20 | * located at different addresses. |
| 21 | */ | 21 | */ |
| 22 | #define IOP3XX_GPIO_REG(reg) (IOP3XX_PERIPHERAL_VIRT_BASE + 0x07c0 + (reg)) | 22 | #define IOP3XX_GPIO_REG(reg) (IOP3XX_PERIPHERAL_VIRT_BASE + 0x07c4 + (reg)) |
| 23 | #define IOP3XX_TIMER_REG(reg) (IOP3XX_PERIPHERAL_VIRT_BASE + 0x07e0 + (reg)) | 23 | #define IOP3XX_TIMER_REG(reg) (IOP3XX_PERIPHERAL_VIRT_BASE + 0x07e0 + (reg)) |
| 24 | 24 | ||
| 25 | #include <asm/hardware/iop3xx.h> | 25 | #include <asm/hardware/iop3xx.h> |
diff --git a/include/asm-arm/cacheflush.h b/include/asm-arm/cacheflush.h index d51049522cd0..5f531ea03059 100644 --- a/include/asm-arm/cacheflush.h +++ b/include/asm-arm/cacheflush.h | |||
| @@ -357,6 +357,16 @@ extern void flush_dcache_page(struct page *); | |||
| 357 | 357 | ||
| 358 | extern void __flush_dcache_page(struct address_space *mapping, struct page *page); | 358 | extern void __flush_dcache_page(struct address_space *mapping, struct page *page); |
| 359 | 359 | ||
| 360 | #define ARCH_HAS_FLUSH_ANON_PAGE | ||
| 361 | static inline void flush_anon_page(struct vm_area_struct *vma, | ||
| 362 | struct page *page, unsigned long vmaddr) | ||
| 363 | { | ||
| 364 | extern void __flush_anon_page(struct vm_area_struct *vma, | ||
| 365 | struct page *, unsigned long); | ||
| 366 | if (PageAnon(page)) | ||
| 367 | __flush_anon_page(vma, page, vmaddr); | ||
| 368 | } | ||
| 369 | |||
| 360 | #define flush_dcache_mmap_lock(mapping) \ | 370 | #define flush_dcache_mmap_lock(mapping) \ |
| 361 | write_lock_irq(&(mapping)->tree_lock) | 371 | write_lock_irq(&(mapping)->tree_lock) |
| 362 | #define flush_dcache_mmap_unlock(mapping) \ | 372 | #define flush_dcache_mmap_unlock(mapping) \ |
diff --git a/include/asm-arm/hardware/iop3xx.h b/include/asm-arm/hardware/iop3xx.h index 1018a7486ab7..13ac8a4cd01f 100644 --- a/include/asm-arm/hardware/iop3xx.h +++ b/include/asm-arm/hardware/iop3xx.h | |||
| @@ -168,9 +168,9 @@ extern void gpio_line_set(int line, int value); | |||
| 168 | #define IOP3XX_PERCR0 (volatile u32 *)IOP3XX_REG_ADDR(0x0710) | 168 | #define IOP3XX_PERCR0 (volatile u32 *)IOP3XX_REG_ADDR(0x0710) |
| 169 | 169 | ||
| 170 | /* General Purpose I/O */ | 170 | /* General Purpose I/O */ |
| 171 | #define IOP3XX_GPOE (volatile u32 *)IOP3XX_GPIO_REG(0x0004) | 171 | #define IOP3XX_GPOE (volatile u32 *)IOP3XX_GPIO_REG(0x0000) |
| 172 | #define IOP3XX_GPID (volatile u32 *)IOP3XX_GPIO_REG(0x0008) | 172 | #define IOP3XX_GPID (volatile u32 *)IOP3XX_GPIO_REG(0x0004) |
| 173 | #define IOP3XX_GPOD (volatile u32 *)IOP3XX_GPIO_REG(0x000c) | 173 | #define IOP3XX_GPOD (volatile u32 *)IOP3XX_GPIO_REG(0x0008) |
| 174 | 174 | ||
| 175 | /* Timers */ | 175 | /* Timers */ |
| 176 | #define IOP3XX_TU_TMR0 (volatile u32 *)IOP3XX_TIMER_REG(0x0000) | 176 | #define IOP3XX_TU_TMR0 (volatile u32 *)IOP3XX_TIMER_REG(0x0000) |
diff --git a/include/asm-parisc/cacheflush.h b/include/asm-parisc/cacheflush.h index aedb0512cb04..a799dd8ef395 100644 --- a/include/asm-parisc/cacheflush.h +++ b/include/asm-parisc/cacheflush.h | |||
| @@ -186,7 +186,7 @@ flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr, unsigned long | |||
| 186 | } | 186 | } |
| 187 | 187 | ||
| 188 | static inline void | 188 | static inline void |
| 189 | flush_anon_page(struct page *page, unsigned long vmaddr) | 189 | flush_anon_page(struct vm_area_struct *vma, struct page *page, unsigned long vmaddr) |
| 190 | { | 190 | { |
| 191 | if (PageAnon(page)) | 191 | if (PageAnon(page)) |
| 192 | flush_user_dcache_page(vmaddr); | 192 | flush_user_dcache_page(vmaddr); |
diff --git a/include/linux/highmem.h b/include/linux/highmem.h index ca9a602cffd7..645d440807c2 100644 --- a/include/linux/highmem.h +++ b/include/linux/highmem.h | |||
| @@ -8,7 +8,7 @@ | |||
| 8 | #include <asm/cacheflush.h> | 8 | #include <asm/cacheflush.h> |
| 9 | 9 | ||
| 10 | #ifndef ARCH_HAS_FLUSH_ANON_PAGE | 10 | #ifndef ARCH_HAS_FLUSH_ANON_PAGE |
| 11 | static inline void flush_anon_page(struct page *page, unsigned long vmaddr) | 11 | static inline void flush_anon_page(struct vm_area_struct *vma, struct page *page, unsigned long vmaddr) |
| 12 | { | 12 | { |
| 13 | } | 13 | } |
| 14 | #endif | 14 | #endif |
diff --git a/mm/memory.c b/mm/memory.c index 563792f4f687..af227d26e104 100644 --- a/mm/memory.c +++ b/mm/memory.c | |||
| @@ -1091,7 +1091,7 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, | |||
| 1091 | if (pages) { | 1091 | if (pages) { |
| 1092 | pages[i] = page; | 1092 | pages[i] = page; |
| 1093 | 1093 | ||
| 1094 | flush_anon_page(page, start); | 1094 | flush_anon_page(vma, page, start); |
| 1095 | flush_dcache_page(page); | 1095 | flush_dcache_page(page); |
| 1096 | } | 1096 | } |
| 1097 | if (vmas) | 1097 | if (vmas) |
