diff options
| author | Linus Torvalds <torvalds@evo.osdl.org> | 2005-09-02 03:52:05 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@evo.osdl.org> | 2005-09-02 03:52:05 -0400 |
| commit | 66f3767376e2bbffb4c2c78ea171e1fdcb62201b (patch) | |
| tree | 2006a0d4e087d34b4f8767574e36946c0254fbbc | |
| parent | 5d8c397f304e1363f8ff9749b08172eb59e6534a (diff) | |
| parent | 86a8a83963a3f6beeca4900d26da93c7d2a9d92d (diff) | |
Merge HEAD from master.kernel.org:/home/rmk/linux-2.6-arm
| -rw-r--r-- | arch/arm/Kconfig | 4 | ||||
| -rw-r--r-- | arch/arm/kernel/calls.S | 2 | ||||
| -rw-r--r-- | arch/arm/kernel/entry-common.S | 4 | ||||
| -rw-r--r-- | arch/arm/kernel/sys_arm.c | 10 | ||||
| -rw-r--r-- | arch/arm/mach-pxa/time.c | 58 | ||||
| -rw-r--r-- | arch/arm/mach-sa1100/time.c | 68 | ||||
| -rw-r--r-- | arch/arm/mm/mm-armv.c | 26 | ||||
| -rw-r--r-- | include/asm-arm/unistd.h | 2 |
8 files changed, 143 insertions, 31 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 4bf0e8737e1f..68dfdba71d74 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
| @@ -365,8 +365,8 @@ config NO_IDLE_HZ | |||
| 365 | 365 | ||
| 366 | Please note that dynamic tick may affect the accuracy of | 366 | Please note that dynamic tick may affect the accuracy of |
| 367 | timekeeping on some platforms depending on the implementation. | 367 | timekeeping on some platforms depending on the implementation. |
| 368 | Currently at least OMAP platform is known to have accurate | 368 | Currently at least OMAP, PXA2xx and SA11x0 platforms are known |
| 369 | timekeeping with dynamic tick. | 369 | to have accurate timekeeping with dynamic tick. |
| 370 | 370 | ||
| 371 | config ARCH_DISCONTIGMEM_ENABLE | 371 | config ARCH_DISCONTIGMEM_ENABLE |
| 372 | bool | 372 | bool |
diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S index 2b6b4c786e65..db07ce42b3b2 100644 --- a/arch/arm/kernel/calls.S +++ b/arch/arm/kernel/calls.S | |||
| @@ -284,7 +284,7 @@ __syscall_start: | |||
| 284 | .long sys_fstatfs64 | 284 | .long sys_fstatfs64 |
| 285 | .long sys_tgkill | 285 | .long sys_tgkill |
| 286 | .long sys_utimes | 286 | .long sys_utimes |
| 287 | /* 270 */ .long sys_fadvise64_64 | 287 | /* 270 */ .long sys_arm_fadvise64_64_wrapper |
| 288 | .long sys_pciconfig_iobase | 288 | .long sys_pciconfig_iobase |
| 289 | .long sys_pciconfig_read | 289 | .long sys_pciconfig_read |
| 290 | .long sys_pciconfig_write | 290 | .long sys_pciconfig_write |
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S index 3f8d0e3aefab..6281d488ac97 100644 --- a/arch/arm/kernel/entry-common.S +++ b/arch/arm/kernel/entry-common.S | |||
| @@ -265,6 +265,10 @@ sys_futex_wrapper: | |||
| 265 | str r5, [sp, #4] @ push sixth arg | 265 | str r5, [sp, #4] @ push sixth arg |
| 266 | b sys_futex | 266 | b sys_futex |
| 267 | 267 | ||
| 268 | sys_arm_fadvise64_64_wrapper: | ||
| 269 | str r5, [sp, #4] @ push r5 to stack | ||
| 270 | b sys_arm_fadvise64_64 | ||
| 271 | |||
| 268 | /* | 272 | /* |
| 269 | * Note: off_4k (r5) is always units of 4K. If we can't do the requested | 273 | * Note: off_4k (r5) is always units of 4K. If we can't do the requested |
| 270 | * offset, we return EINVAL. | 274 | * offset, we return EINVAL. |
diff --git a/arch/arm/kernel/sys_arm.c b/arch/arm/kernel/sys_arm.c index f897ce2ccf0d..42629ff84f5a 100644 --- a/arch/arm/kernel/sys_arm.c +++ b/arch/arm/kernel/sys_arm.c | |||
| @@ -311,3 +311,13 @@ long execve(const char *filename, char **argv, char **envp) | |||
| 311 | return ret; | 311 | return ret; |
| 312 | } | 312 | } |
| 313 | EXPORT_SYMBOL(execve); | 313 | EXPORT_SYMBOL(execve); |
| 314 | |||
| 315 | /* | ||
| 316 | * Since loff_t is a 64 bit type we avoid a lot of ABI hastle | ||
| 317 | * with a different argument ordering. | ||
| 318 | */ | ||
| 319 | asmlinkage long sys_arm_fadvise64_64(int fd, int advice, | ||
| 320 | loff_t offset, loff_t len) | ||
| 321 | { | ||
| 322 | return sys_fadvise64_64(fd, offset, len, advice); | ||
| 323 | } | ||
diff --git a/arch/arm/mach-pxa/time.c b/arch/arm/mach-pxa/time.c index 6e5202154f91..7dad3f1465e0 100644 --- a/arch/arm/mach-pxa/time.c +++ b/arch/arm/mach-pxa/time.c | |||
| @@ -70,6 +70,11 @@ static unsigned long pxa_gettimeoffset (void) | |||
| 70 | return usec; | 70 | return usec; |
| 71 | } | 71 | } |
| 72 | 72 | ||
| 73 | #ifdef CONFIG_NO_IDLE_HZ | ||
| 74 | static unsigned long initial_match; | ||
| 75 | static int match_posponed; | ||
| 76 | #endif | ||
| 77 | |||
| 73 | static irqreturn_t | 78 | static irqreturn_t |
| 74 | pxa_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) | 79 | pxa_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) |
| 75 | { | 80 | { |
| @@ -77,11 +82,19 @@ pxa_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |||
| 77 | 82 | ||
| 78 | write_seqlock(&xtime_lock); | 83 | write_seqlock(&xtime_lock); |
| 79 | 84 | ||
| 85 | #ifdef CONFIG_NO_IDLE_HZ | ||
| 86 | if (match_posponed) { | ||
| 87 | match_posponed = 0; | ||
| 88 | OSMR0 = initial_match; | ||
| 89 | } | ||
| 90 | #endif | ||
| 91 | |||
| 80 | /* Loop until we get ahead of the free running timer. | 92 | /* Loop until we get ahead of the free running timer. |
| 81 | * This ensures an exact clock tick count and time accuracy. | 93 | * This ensures an exact clock tick count and time accuracy. |
| 82 | * IRQs are disabled inside the loop to ensure coherence between | 94 | * Since IRQs are disabled at this point, coherence between |
| 83 | * lost_ticks (updated in do_timer()) and the match reg value, so we | 95 | * lost_ticks(updated in do_timer()) and the match reg value is |
| 84 | * can use do_gettimeofday() from interrupt handlers. | 96 | * ensured, hence we can use do_gettimeofday() from interrupt |
| 97 | * handlers. | ||
| 85 | * | 98 | * |
| 86 | * HACK ALERT: it seems that the PXA timer regs aren't updated right | 99 | * HACK ALERT: it seems that the PXA timer regs aren't updated right |
| 87 | * away in all cases when a write occurs. We therefore compare with | 100 | * away in all cases when a write occurs. We therefore compare with |
| @@ -126,6 +139,42 @@ static void __init pxa_timer_init(void) | |||
| 126 | OSCR = 0; /* initialize free-running timer, force first match */ | 139 | OSCR = 0; /* initialize free-running timer, force first match */ |
| 127 | } | 140 | } |
| 128 | 141 | ||
| 142 | #ifdef CONFIG_NO_IDLE_HZ | ||
| 143 | static int pxa_dyn_tick_enable_disable(void) | ||
| 144 | { | ||
| 145 | /* nothing to do */ | ||
| 146 | return 0; | ||
| 147 | } | ||
| 148 | |||
| 149 | static void pxa_dyn_tick_reprogram(unsigned long ticks) | ||
| 150 | { | ||
| 151 | if (ticks > 1) { | ||
| 152 | initial_match = OSMR0; | ||
| 153 | OSMR0 = initial_match + ticks * LATCH; | ||
| 154 | match_posponed = 1; | ||
| 155 | } | ||
| 156 | } | ||
| 157 | |||
| 158 | static irqreturn_t | ||
| 159 | pxa_dyn_tick_handler(int irq, void *dev_id, struct pt_regs *regs) | ||
| 160 | { | ||
| 161 | if (match_posponed) { | ||
| 162 | match_posponed = 0; | ||
| 163 | OSMR0 = initial_match; | ||
| 164 | if ( (signed long)(initial_match - OSCR) <= 8 ) | ||
| 165 | return pxa_timer_interrupt(irq, dev_id, regs); | ||
| 166 | } | ||
| 167 | return IRQ_NONE; | ||
| 168 | } | ||
| 169 | |||
| 170 | static struct dyn_tick_timer pxa_dyn_tick = { | ||
| 171 | .enable = pxa_dyn_tick_enable_disable, | ||
| 172 | .disable = pxa_dyn_tick_enable_disable, | ||
| 173 | .reprogram = pxa_dyn_tick_reprogram, | ||
| 174 | .handler = pxa_dyn_tick_handler, | ||
| 175 | }; | ||
| 176 | #endif | ||
| 177 | |||
| 129 | #ifdef CONFIG_PM | 178 | #ifdef CONFIG_PM |
| 130 | static unsigned long osmr[4], oier; | 179 | static unsigned long osmr[4], oier; |
| 131 | 180 | ||
| @@ -161,4 +210,7 @@ struct sys_timer pxa_timer = { | |||
| 161 | .suspend = pxa_timer_suspend, | 210 | .suspend = pxa_timer_suspend, |
| 162 | .resume = pxa_timer_resume, | 211 | .resume = pxa_timer_resume, |
| 163 | .offset = pxa_gettimeoffset, | 212 | .offset = pxa_gettimeoffset, |
| 213 | #ifdef CONFIG_NO_IDLE_HZ | ||
| 214 | .dyn_tick = &pxa_dyn_tick, | ||
| 215 | #endif | ||
| 164 | }; | 216 | }; |
diff --git a/arch/arm/mach-sa1100/time.c b/arch/arm/mach-sa1100/time.c index 0eeb3616ffea..47e0420623fc 100644 --- a/arch/arm/mach-sa1100/time.c +++ b/arch/arm/mach-sa1100/time.c | |||
| @@ -70,15 +70,11 @@ static unsigned long sa1100_gettimeoffset (void) | |||
| 70 | return usec; | 70 | return usec; |
| 71 | } | 71 | } |
| 72 | 72 | ||
| 73 | /* | 73 | #ifdef CONFIG_NO_IDLE_HZ |
| 74 | * We will be entered with IRQs enabled. | 74 | static unsigned long initial_match; |
| 75 | * | 75 | static int match_posponed; |
| 76 | * Loop until we get ahead of the free running timer. | 76 | #endif |
| 77 | * This ensures an exact clock tick count and time accuracy. | 77 | |
| 78 | * IRQs are disabled inside the loop to ensure coherence between | ||
| 79 | * lost_ticks (updated in do_timer()) and the match reg value, so we | ||
| 80 | * can use do_gettimeofday() from interrupt handlers. | ||
| 81 | */ | ||
| 82 | static irqreturn_t | 78 | static irqreturn_t |
| 83 | sa1100_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) | 79 | sa1100_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) |
| 84 | { | 80 | { |
| @@ -86,6 +82,21 @@ sa1100_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |||
| 86 | 82 | ||
| 87 | write_seqlock(&xtime_lock); | 83 | write_seqlock(&xtime_lock); |
| 88 | 84 | ||
| 85 | #ifdef CONFIG_NO_IDLE_HZ | ||
| 86 | if (match_posponed) { | ||
| 87 | match_posponed = 0; | ||
| 88 | OSMR0 = initial_match; | ||
| 89 | } | ||
| 90 | #endif | ||
| 91 | |||
| 92 | /* | ||
| 93 | * Loop until we get ahead of the free running timer. | ||
| 94 | * This ensures an exact clock tick count and time accuracy. | ||
| 95 | * Since IRQs are disabled at this point, coherence between | ||
| 96 | * lost_ticks(updated in do_timer()) and the match reg value is | ||
| 97 | * ensured, hence we can use do_gettimeofday() from interrupt | ||
| 98 | * handlers. | ||
| 99 | */ | ||
| 89 | do { | 100 | do { |
| 90 | timer_tick(regs); | 101 | timer_tick(regs); |
| 91 | OSSR = OSSR_M0; /* Clear match on timer 0 */ | 102 | OSSR = OSSR_M0; /* Clear match on timer 0 */ |
| @@ -120,6 +131,42 @@ static void __init sa1100_timer_init(void) | |||
| 120 | OSCR = 0; /* initialize free-running timer, force first match */ | 131 | OSCR = 0; /* initialize free-running timer, force first match */ |
| 121 | } | 132 | } |
| 122 | 133 | ||
| 134 | #ifdef CONFIG_NO_IDLE_HZ | ||
| 135 | static int sa1100_dyn_tick_enable_disable(void) | ||
| 136 | { | ||
| 137 | /* nothing to do */ | ||
| 138 | return 0; | ||
| 139 | } | ||
| 140 | |||
| 141 | static void sa1100_dyn_tick_reprogram(unsigned long ticks) | ||
| 142 | { | ||
| 143 | if (ticks > 1) { | ||
| 144 | initial_match = OSMR0; | ||
| 145 | OSMR0 = initial_match + ticks * LATCH; | ||
| 146 | match_posponed = 1; | ||
| 147 | } | ||
| 148 | } | ||
| 149 | |||
| 150 | static irqreturn_t | ||
| 151 | sa1100_dyn_tick_handler(int irq, void *dev_id, struct pt_regs *regs) | ||
| 152 | { | ||
| 153 | if (match_posponed) { | ||
| 154 | match_posponed = 0; | ||
| 155 | OSMR0 = initial_match; | ||
| 156 | if ((signed long)(initial_match - OSCR) <= 0) | ||
| 157 | return sa1100_timer_interrupt(irq, dev_id, regs); | ||
| 158 | } | ||
| 159 | return IRQ_NONE; | ||
| 160 | } | ||
| 161 | |||
| 162 | static struct dyn_tick_timer sa1100_dyn_tick = { | ||
| 163 | .enable = sa1100_dyn_tick_enable_disable, | ||
| 164 | .disable = sa1100_dyn_tick_enable_disable, | ||
| 165 | .reprogram = sa1100_dyn_tick_reprogram, | ||
| 166 | .handler = sa1100_dyn_tick_handler, | ||
| 167 | }; | ||
| 168 | #endif | ||
| 169 | |||
| 123 | #ifdef CONFIG_PM | 170 | #ifdef CONFIG_PM |
| 124 | unsigned long osmr[4], oier; | 171 | unsigned long osmr[4], oier; |
| 125 | 172 | ||
| @@ -156,4 +203,7 @@ struct sys_timer sa1100_timer = { | |||
| 156 | .suspend = sa1100_timer_suspend, | 203 | .suspend = sa1100_timer_suspend, |
| 157 | .resume = sa1100_timer_resume, | 204 | .resume = sa1100_timer_resume, |
| 158 | .offset = sa1100_gettimeoffset, | 205 | .offset = sa1100_gettimeoffset, |
| 206 | #ifdef CONFIG_NO_IDLE_HZ | ||
| 207 | .dyn_tick = &sa1100_dyn_tick, | ||
| 208 | #endif | ||
| 159 | }; | 209 | }; |
diff --git a/arch/arm/mm/mm-armv.c b/arch/arm/mm/mm-armv.c index 4dae00bf7a56..d125a3dc061c 100644 --- a/arch/arm/mm/mm-armv.c +++ b/arch/arm/mm/mm-armv.c | |||
| @@ -295,14 +295,10 @@ alloc_init_page(unsigned long virt, unsigned long phys, unsigned int prot_l1, pg | |||
| 295 | pte_t *ptep; | 295 | pte_t *ptep; |
| 296 | 296 | ||
| 297 | if (pmd_none(*pmdp)) { | 297 | if (pmd_none(*pmdp)) { |
| 298 | unsigned long pmdval; | ||
| 299 | ptep = alloc_bootmem_low_pages(2 * PTRS_PER_PTE * | 298 | ptep = alloc_bootmem_low_pages(2 * PTRS_PER_PTE * |
| 300 | sizeof(pte_t)); | 299 | sizeof(pte_t)); |
| 301 | 300 | ||
| 302 | pmdval = __pa(ptep) | prot_l1; | 301 | __pmd_populate(pmdp, __pa(ptep) | prot_l1); |
| 303 | pmdp[0] = __pmd(pmdval); | ||
| 304 | pmdp[1] = __pmd(pmdval + 256 * sizeof(pte_t)); | ||
| 305 | flush_pmd_entry(pmdp); | ||
| 306 | } | 302 | } |
| 307 | ptep = pte_offset_kernel(pmdp, virt); | 303 | ptep = pte_offset_kernel(pmdp, virt); |
| 308 | 304 | ||
| @@ -457,7 +453,7 @@ static void __init build_mem_type_table(void) | |||
| 457 | 453 | ||
| 458 | for (i = 0; i < 16; i++) { | 454 | for (i = 0; i < 16; i++) { |
| 459 | unsigned long v = pgprot_val(protection_map[i]); | 455 | unsigned long v = pgprot_val(protection_map[i]); |
| 460 | v &= (~(PTE_BUFFERABLE|PTE_CACHEABLE)) | user_pgprot; | 456 | v = (v & ~(PTE_BUFFERABLE|PTE_CACHEABLE)) | user_pgprot; |
| 461 | protection_map[i] = __pgprot(v); | 457 | protection_map[i] = __pgprot(v); |
| 462 | } | 458 | } |
| 463 | 459 | ||
| @@ -581,23 +577,23 @@ static void __init create_mapping(struct map_desc *md) | |||
| 581 | */ | 577 | */ |
| 582 | void setup_mm_for_reboot(char mode) | 578 | void setup_mm_for_reboot(char mode) |
| 583 | { | 579 | { |
| 584 | unsigned long pmdval; | 580 | unsigned long base_pmdval; |
| 585 | pgd_t *pgd; | 581 | pgd_t *pgd; |
| 586 | pmd_t *pmd; | ||
| 587 | int i; | 582 | int i; |
| 588 | int cpu_arch = cpu_architecture(); | ||
| 589 | 583 | ||
| 590 | if (current->mm && current->mm->pgd) | 584 | if (current->mm && current->mm->pgd) |
| 591 | pgd = current->mm->pgd; | 585 | pgd = current->mm->pgd; |
| 592 | else | 586 | else |
| 593 | pgd = init_mm.pgd; | 587 | pgd = init_mm.pgd; |
| 594 | 588 | ||
| 595 | for (i = 0; i < FIRST_USER_PGD_NR + USER_PTRS_PER_PGD; i++) { | 589 | base_pmdval = PMD_SECT_AP_WRITE | PMD_SECT_AP_READ | PMD_TYPE_SECT; |
| 596 | pmdval = (i << PGDIR_SHIFT) | | 590 | if (cpu_architecture() <= CPU_ARCH_ARMv5TEJ) |
| 597 | PMD_SECT_AP_WRITE | PMD_SECT_AP_READ | | 591 | base_pmdval |= PMD_BIT4; |
| 598 | PMD_TYPE_SECT; | 592 | |
| 599 | if (cpu_arch <= CPU_ARCH_ARMv5TEJ) | 593 | for (i = 0; i < FIRST_USER_PGD_NR + USER_PTRS_PER_PGD; i++, pgd++) { |
| 600 | pmdval |= PMD_BIT4; | 594 | unsigned long pmdval = (i << PGDIR_SHIFT) | base_pmdval; |
| 595 | pmd_t *pmd; | ||
| 596 | |||
| 601 | pmd = pmd_off(pgd, i << PGDIR_SHIFT); | 597 | pmd = pmd_off(pgd, i << PGDIR_SHIFT); |
| 602 | pmd[0] = __pmd(pmdval); | 598 | pmd[0] = __pmd(pmdval); |
| 603 | pmd[1] = __pmd(pmdval + (1 << (PGDIR_SHIFT - 1))); | 599 | pmd[1] = __pmd(pmdval + (1 << (PGDIR_SHIFT - 1))); |
diff --git a/include/asm-arm/unistd.h b/include/asm-arm/unistd.h index 94619ccee789..278de61224d1 100644 --- a/include/asm-arm/unistd.h +++ b/include/asm-arm/unistd.h | |||
| @@ -295,7 +295,7 @@ | |||
| 295 | #define __NR_fstatfs64 (__NR_SYSCALL_BASE+267) | 295 | #define __NR_fstatfs64 (__NR_SYSCALL_BASE+267) |
| 296 | #define __NR_tgkill (__NR_SYSCALL_BASE+268) | 296 | #define __NR_tgkill (__NR_SYSCALL_BASE+268) |
| 297 | #define __NR_utimes (__NR_SYSCALL_BASE+269) | 297 | #define __NR_utimes (__NR_SYSCALL_BASE+269) |
| 298 | #define __NR_fadvise64_64 (__NR_SYSCALL_BASE+270) | 298 | #define __NR_arm_fadvise64_64 (__NR_SYSCALL_BASE+270) |
| 299 | #define __NR_pciconfig_iobase (__NR_SYSCALL_BASE+271) | 299 | #define __NR_pciconfig_iobase (__NR_SYSCALL_BASE+271) |
| 300 | #define __NR_pciconfig_read (__NR_SYSCALL_BASE+272) | 300 | #define __NR_pciconfig_read (__NR_SYSCALL_BASE+272) |
| 301 | #define __NR_pciconfig_write (__NR_SYSCALL_BASE+273) | 301 | #define __NR_pciconfig_write (__NR_SYSCALL_BASE+273) |
