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) |