diff options
Diffstat (limited to 'arch/arm')
52 files changed, 1401 insertions, 240 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 296bc03d1cf1..ec77721507cb 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
| @@ -324,7 +324,7 @@ menu "Kernel Features" | |||
| 324 | 324 | ||
| 325 | config SMP | 325 | config SMP |
| 326 | bool "Symmetric Multi-Processing (EXPERIMENTAL)" | 326 | bool "Symmetric Multi-Processing (EXPERIMENTAL)" |
| 327 | depends on EXPERIMENTAL && BROKEN #&& n | 327 | depends on EXPERIMENTAL && REALVIEW_MPCORE |
| 328 | help | 328 | help |
| 329 | This enables support for systems with more than one CPU. If you have | 329 | This enables support for systems with more than one CPU. If you have |
| 330 | a system with only one CPU, like most personal computers, say N. If | 330 | a system with only one CPU, like most personal computers, say N. If |
| @@ -356,6 +356,16 @@ config HOTPLUG_CPU | |||
| 356 | Say Y here to experiment with turning CPUs off and on. CPUs | 356 | Say Y here to experiment with turning CPUs off and on. CPUs |
| 357 | can be controlled through /sys/devices/system/cpu. | 357 | can be controlled through /sys/devices/system/cpu. |
| 358 | 358 | ||
| 359 | config LOCAL_TIMERS | ||
| 360 | bool "Use local timer interrupts" | ||
| 361 | depends on SMP && REALVIEW_MPCORE | ||
| 362 | default y | ||
| 363 | help | ||
| 364 | Enable support for local timers on SMP platforms, rather then the | ||
| 365 | legacy IPI broadcast method. Local timers allows the system | ||
| 366 | accounting to be spread across the timer interval, preventing a | ||
| 367 | "thundering herd" at every timer tick. | ||
| 368 | |||
| 359 | config PREEMPT | 369 | config PREEMPT |
| 360 | bool "Preemptible Kernel (EXPERIMENTAL)" | 370 | bool "Preemptible Kernel (EXPERIMENTAL)" |
| 361 | depends on EXPERIMENTAL | 371 | depends on EXPERIMENTAL |
| @@ -585,7 +595,7 @@ config FPE_NWFPE | |||
| 585 | 595 | ||
| 586 | config FPE_NWFPE_XP | 596 | config FPE_NWFPE_XP |
| 587 | bool "Support extended precision" | 597 | bool "Support extended precision" |
| 588 | depends on FPE_NWFPE && !CPU_BIG_ENDIAN | 598 | depends on FPE_NWFPE |
| 589 | help | 599 | help |
| 590 | Say Y to include 80-bit support in the kernel floating-point | 600 | Say Y to include 80-bit support in the kernel floating-point |
| 591 | emulator. Otherwise, only 32 and 64-bit support is compiled in. | 601 | emulator. Otherwise, only 32 and 64-bit support is compiled in. |
diff --git a/arch/arm/boot/compressed/misc.c b/arch/arm/boot/compressed/misc.c index 50f13eec6cd7..5ab94584baee 100644 --- a/arch/arm/boot/compressed/misc.c +++ b/arch/arm/boot/compressed/misc.c | |||
| @@ -283,8 +283,14 @@ void flush_window(void) | |||
| 283 | putstr("."); | 283 | putstr("."); |
| 284 | } | 284 | } |
| 285 | 285 | ||
| 286 | #ifndef arch_error | ||
| 287 | #define arch_error(x) | ||
| 288 | #endif | ||
| 289 | |||
| 286 | static void error(char *x) | 290 | static void error(char *x) |
| 287 | { | 291 | { |
| 292 | arch_error(x); | ||
| 293 | |||
| 288 | putstr("\n\n"); | 294 | putstr("\n\n"); |
| 289 | putstr(x); | 295 | putstr(x); |
| 290 | putstr("\n\n -- System halted"); | 296 | putstr("\n\n -- System halted"); |
diff --git a/arch/arm/common/scoop.c b/arch/arm/common/scoop.c index bb4eff614413..c7fdf390cef9 100644 --- a/arch/arm/common/scoop.c +++ b/arch/arm/common/scoop.c | |||
| @@ -19,12 +19,6 @@ | |||
| 19 | 19 | ||
| 20 | #define SCOOP_REG(d,adr) (*(volatile unsigned short*)(d +(adr))) | 20 | #define SCOOP_REG(d,adr) (*(volatile unsigned short*)(d +(adr))) |
| 21 | 21 | ||
| 22 | /* PCMCIA to Scoop linkage structures for pxa2xx_sharpsl.c | ||
| 23 | There is no easy way to link multiple scoop devices into one | ||
| 24 | single entity for the pxa2xx_pcmcia device */ | ||
| 25 | int scoop_num; | ||
| 26 | struct scoop_pcmcia_dev *scoop_devs; | ||
| 27 | |||
| 28 | struct scoop_dev { | 22 | struct scoop_dev { |
| 29 | void *base; | 23 | void *base; |
| 30 | spinlock_t scoop_lock; | 24 | spinlock_t scoop_lock; |
diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c index 7b17a87a3311..7a3261f0bf79 100644 --- a/arch/arm/kernel/armksyms.c +++ b/arch/arm/kernel/armksyms.c | |||
| @@ -9,6 +9,7 @@ | |||
| 9 | */ | 9 | */ |
| 10 | #include <linux/module.h> | 10 | #include <linux/module.h> |
| 11 | #include <linux/string.h> | 11 | #include <linux/string.h> |
| 12 | #include <linux/cryptohash.h> | ||
| 12 | #include <linux/delay.h> | 13 | #include <linux/delay.h> |
| 13 | #include <linux/in6.h> | 14 | #include <linux/in6.h> |
| 14 | #include <linux/syscalls.h> | 15 | #include <linux/syscalls.h> |
| @@ -126,6 +127,9 @@ EXPORT_SYMBOL(__put_user_2); | |||
| 126 | EXPORT_SYMBOL(__put_user_4); | 127 | EXPORT_SYMBOL(__put_user_4); |
| 127 | EXPORT_SYMBOL(__put_user_8); | 128 | EXPORT_SYMBOL(__put_user_8); |
| 128 | 129 | ||
| 130 | /* crypto hash */ | ||
| 131 | EXPORT_SYMBOL(sha_transform); | ||
| 132 | |||
| 129 | /* gcc lib functions */ | 133 | /* gcc lib functions */ |
| 130 | EXPORT_SYMBOL(__ashldi3); | 134 | EXPORT_SYMBOL(__ashldi3); |
| 131 | EXPORT_SYMBOL(__ashrdi3); | 135 | EXPORT_SYMBOL(__ashrdi3); |
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index be439cab92c6..d9fb819bf7cc 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S | |||
| @@ -47,6 +47,13 @@ | |||
| 47 | movne r0, sp | 47 | movne r0, sp |
| 48 | adrne lr, 1b | 48 | adrne lr, 1b |
| 49 | bne do_IPI | 49 | bne do_IPI |
| 50 | |||
| 51 | #ifdef CONFIG_LOCAL_TIMERS | ||
| 52 | test_for_ltirq r0, r6, r5, lr | ||
| 53 | movne r0, sp | ||
| 54 | adrne lr, 1b | ||
| 55 | bne do_local_timer | ||
| 56 | #endif | ||
| 50 | #endif | 57 | #endif |
| 51 | 58 | ||
| 52 | .endm | 59 | .endm |
| @@ -785,7 +792,7 @@ __kuser_helper_end: | |||
| 785 | * SP points to a minimal amount of processor-private memory, the address | 792 | * SP points to a minimal amount of processor-private memory, the address |
| 786 | * of which is copied into r0 for the mode specific abort handler. | 793 | * of which is copied into r0 for the mode specific abort handler. |
| 787 | */ | 794 | */ |
| 788 | .macro vector_stub, name, correction=0 | 795 | .macro vector_stub, name, mode, correction=0 |
| 789 | .align 5 | 796 | .align 5 |
| 790 | 797 | ||
| 791 | vector_\name: | 798 | vector_\name: |
| @@ -805,15 +812,14 @@ vector_\name: | |||
| 805 | @ Prepare for SVC32 mode. IRQs remain disabled. | 812 | @ Prepare for SVC32 mode. IRQs remain disabled. |
| 806 | @ | 813 | @ |
| 807 | mrs r0, cpsr | 814 | mrs r0, cpsr |
| 808 | bic r0, r0, #MODE_MASK | 815 | eor r0, r0, #(\mode ^ SVC_MODE) |
| 809 | orr r0, r0, #SVC_MODE | ||
| 810 | msr spsr_cxsf, r0 | 816 | msr spsr_cxsf, r0 |
| 811 | 817 | ||
| 812 | @ | 818 | @ |
| 813 | @ the branch table must immediately follow this code | 819 | @ the branch table must immediately follow this code |
| 814 | @ | 820 | @ |
| 815 | mov r0, sp | ||
| 816 | and lr, lr, #0x0f | 821 | and lr, lr, #0x0f |
| 822 | mov r0, sp | ||
| 817 | ldr lr, [pc, lr, lsl #2] | 823 | ldr lr, [pc, lr, lsl #2] |
| 818 | movs pc, lr @ branch to handler in SVC mode | 824 | movs pc, lr @ branch to handler in SVC mode |
| 819 | .endm | 825 | .endm |
| @@ -823,7 +829,7 @@ __stubs_start: | |||
| 823 | /* | 829 | /* |
| 824 | * Interrupt dispatcher | 830 | * Interrupt dispatcher |
| 825 | */ | 831 | */ |
| 826 | vector_stub irq, 4 | 832 | vector_stub irq, IRQ_MODE, 4 |
| 827 | 833 | ||
| 828 | .long __irq_usr @ 0 (USR_26 / USR_32) | 834 | .long __irq_usr @ 0 (USR_26 / USR_32) |
| 829 | .long __irq_invalid @ 1 (FIQ_26 / FIQ_32) | 835 | .long __irq_invalid @ 1 (FIQ_26 / FIQ_32) |
| @@ -846,7 +852,7 @@ __stubs_start: | |||
| 846 | * Data abort dispatcher | 852 | * Data abort dispatcher |
| 847 | * Enter in ABT mode, spsr = USR CPSR, lr = USR PC | 853 | * Enter in ABT mode, spsr = USR CPSR, lr = USR PC |
| 848 | */ | 854 | */ |
| 849 | vector_stub dabt, 8 | 855 | vector_stub dabt, ABT_MODE, 8 |
| 850 | 856 | ||
| 851 | .long __dabt_usr @ 0 (USR_26 / USR_32) | 857 | .long __dabt_usr @ 0 (USR_26 / USR_32) |
| 852 | .long __dabt_invalid @ 1 (FIQ_26 / FIQ_32) | 858 | .long __dabt_invalid @ 1 (FIQ_26 / FIQ_32) |
| @@ -869,7 +875,7 @@ __stubs_start: | |||
| 869 | * Prefetch abort dispatcher | 875 | * Prefetch abort dispatcher |
| 870 | * Enter in ABT mode, spsr = USR CPSR, lr = USR PC | 876 | * Enter in ABT mode, spsr = USR CPSR, lr = USR PC |
| 871 | */ | 877 | */ |
| 872 | vector_stub pabt, 4 | 878 | vector_stub pabt, ABT_MODE, 4 |
| 873 | 879 | ||
| 874 | .long __pabt_usr @ 0 (USR_26 / USR_32) | 880 | .long __pabt_usr @ 0 (USR_26 / USR_32) |
| 875 | .long __pabt_invalid @ 1 (FIQ_26 / FIQ_32) | 881 | .long __pabt_invalid @ 1 (FIQ_26 / FIQ_32) |
| @@ -892,7 +898,7 @@ __stubs_start: | |||
| 892 | * Undef instr entry dispatcher | 898 | * Undef instr entry dispatcher |
| 893 | * Enter in UND mode, spsr = SVC/USR CPSR, lr = SVC/USR PC | 899 | * Enter in UND mode, spsr = SVC/USR CPSR, lr = SVC/USR PC |
| 894 | */ | 900 | */ |
| 895 | vector_stub und | 901 | vector_stub und, UND_MODE |
| 896 | 902 | ||
| 897 | .long __und_usr @ 0 (USR_26 / USR_32) | 903 | .long __und_usr @ 0 (USR_26 / USR_32) |
| 898 | .long __und_invalid @ 1 (FIQ_26 / FIQ_32) | 904 | .long __und_invalid @ 1 (FIQ_26 / FIQ_32) |
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c index 9def4404e1f2..d7099dbbb879 100644 --- a/arch/arm/kernel/irq.c +++ b/arch/arm/kernel/irq.c | |||
| @@ -264,6 +264,7 @@ unlock: | |||
| 264 | #endif | 264 | #endif |
| 265 | #ifdef CONFIG_SMP | 265 | #ifdef CONFIG_SMP |
| 266 | show_ipi_list(p); | 266 | show_ipi_list(p); |
| 267 | show_local_irqs(p); | ||
| 267 | #endif | 268 | #endif |
| 268 | seq_printf(p, "Err: %10lu\n", irq_err_count); | 269 | seq_printf(p, "Err: %10lu\n", irq_err_count); |
| 269 | } | 270 | } |
| @@ -995,7 +996,7 @@ void __init init_irq_proc(void) | |||
| 995 | struct proc_dir_entry *dir; | 996 | struct proc_dir_entry *dir; |
| 996 | int irq; | 997 | int irq; |
| 997 | 998 | ||
| 998 | dir = proc_mkdir("irq", 0); | 999 | dir = proc_mkdir("irq", NULL); |
| 999 | if (!dir) | 1000 | if (!dir) |
| 1000 | return; | 1001 | return; |
| 1001 | 1002 | ||
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index ba298277becd..30494aab829a 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c | |||
| @@ -86,12 +86,16 @@ EXPORT_SYMBOL(pm_power_off); | |||
| 86 | */ | 86 | */ |
| 87 | void default_idle(void) | 87 | void default_idle(void) |
| 88 | { | 88 | { |
| 89 | local_irq_disable(); | 89 | if (hlt_counter) |
| 90 | if (!need_resched() && !hlt_counter) { | 90 | cpu_relax(); |
| 91 | timer_dyn_reprogram(); | 91 | else { |
| 92 | arch_idle(); | 92 | local_irq_disable(); |
| 93 | if (!need_resched()) { | ||
| 94 | timer_dyn_reprogram(); | ||
| 95 | arch_idle(); | ||
| 96 | } | ||
| 97 | local_irq_enable(); | ||
| 93 | } | 98 | } |
| 94 | local_irq_enable(); | ||
| 95 | } | 99 | } |
| 96 | 100 | ||
| 97 | /* | 101 | /* |
| @@ -116,13 +120,13 @@ void cpu_idle(void) | |||
| 116 | 120 | ||
| 117 | if (!idle) | 121 | if (!idle) |
| 118 | idle = default_idle; | 122 | idle = default_idle; |
| 119 | preempt_disable(); | ||
| 120 | leds_event(led_idle_start); | 123 | leds_event(led_idle_start); |
| 121 | while (!need_resched()) | 124 | while (!need_resched()) |
| 122 | idle(); | 125 | idle(); |
| 123 | leds_event(led_idle_end); | 126 | leds_event(led_idle_end); |
| 124 | preempt_enable(); | 127 | preempt_enable_no_resched(); |
| 125 | schedule(); | 128 | schedule(); |
| 129 | preempt_disable(); | ||
| 126 | } | 130 | } |
| 127 | } | 131 | } |
| 128 | 132 | ||
| @@ -355,7 +359,7 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long stack_start, | |||
| 355 | struct thread_info *thread = p->thread_info; | 359 | struct thread_info *thread = p->thread_info; |
| 356 | struct pt_regs *childregs; | 360 | struct pt_regs *childregs; |
| 357 | 361 | ||
| 358 | childregs = ((struct pt_regs *)((unsigned long)thread + THREAD_START_SP)) - 1; | 362 | childregs = (void *)thread + THREAD_START_SP - sizeof(*regs); |
| 359 | *childregs = *regs; | 363 | *childregs = *regs; |
| 360 | childregs->ARM_r0 = 0; | 364 | childregs->ARM_r0 = 0; |
| 361 | childregs->ARM_sp = stack_start; | 365 | childregs->ARM_sp = stack_start; |
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c index 9bd8609a2926..9a340e790da5 100644 --- a/arch/arm/kernel/ptrace.c +++ b/arch/arm/kernel/ptrace.c | |||
| @@ -648,7 +648,7 @@ static int ptrace_setwmmxregs(struct task_struct *tsk, void __user *ufp) | |||
| 648 | 648 | ||
| 649 | #endif | 649 | #endif |
| 650 | 650 | ||
| 651 | static int do_ptrace(int request, struct task_struct *child, long addr, long data) | 651 | long arch_ptrace(struct task_struct *child, long request, long addr, long data) |
| 652 | { | 652 | { |
| 653 | unsigned long tmp; | 653 | unsigned long tmp; |
| 654 | int ret; | 654 | int ret; |
| @@ -782,53 +782,6 @@ static int do_ptrace(int request, struct task_struct *child, long addr, long dat | |||
| 782 | return ret; | 782 | return ret; |
| 783 | } | 783 | } |
| 784 | 784 | ||
| 785 | asmlinkage long sys_ptrace(long request, long pid, long addr, long data) | ||
| 786 | { | ||
| 787 | struct task_struct *child; | ||
| 788 | int ret; | ||
| 789 | |||
| 790 | lock_kernel(); | ||
| 791 | ret = -EPERM; | ||
| 792 | if (request == PTRACE_TRACEME) { | ||
| 793 | /* are we already being traced? */ | ||
| 794 | if (current->ptrace & PT_PTRACED) | ||
| 795 | goto out; | ||
| 796 | ret = security_ptrace(current->parent, current); | ||
| 797 | if (ret) | ||
| 798 | goto out; | ||
| 799 | /* set the ptrace bit in the process flags. */ | ||
| 800 | current->ptrace |= PT_PTRACED; | ||
| 801 | ret = 0; | ||
| 802 | goto out; | ||
| 803 | } | ||
| 804 | ret = -ESRCH; | ||
| 805 | read_lock(&tasklist_lock); | ||
| 806 | child = find_task_by_pid(pid); | ||
| 807 | if (child) | ||
| 808 | get_task_struct(child); | ||
| 809 | read_unlock(&tasklist_lock); | ||
| 810 | if (!child) | ||
| 811 | goto out; | ||
| 812 | |||
| 813 | ret = -EPERM; | ||
| 814 | if (pid == 1) /* you may not mess with init */ | ||
| 815 | goto out_tsk; | ||
| 816 | |||
| 817 | if (request == PTRACE_ATTACH) { | ||
| 818 | ret = ptrace_attach(child); | ||
| 819 | goto out_tsk; | ||
| 820 | } | ||
| 821 | ret = ptrace_check_attach(child, request == PTRACE_KILL); | ||
| 822 | if (ret == 0) | ||
| 823 | ret = do_ptrace(request, child, addr, data); | ||
| 824 | |||
| 825 | out_tsk: | ||
| 826 | put_task_struct(child); | ||
| 827 | out: | ||
| 828 | unlock_kernel(); | ||
| 829 | return ret; | ||
| 830 | } | ||
| 831 | |||
| 832 | asmlinkage void syscall_trace(int why, struct pt_regs *regs) | 785 | asmlinkage void syscall_trace(int why, struct pt_regs *regs) |
| 833 | { | 786 | { |
| 834 | unsigned long ip; | 787 | unsigned long ip; |
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index c9b69771f92e..85774165e9fd 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c | |||
| @@ -338,7 +338,8 @@ void cpu_init(void) | |||
| 338 | BUG(); | 338 | BUG(); |
| 339 | } | 339 | } |
| 340 | 340 | ||
| 341 | dump_cpu_info(cpu); | 341 | if (system_state == SYSTEM_BOOTING) |
| 342 | dump_cpu_info(cpu); | ||
| 342 | 343 | ||
| 343 | /* | 344 | /* |
| 344 | * setup stacks for re-entrant exception handlers | 345 | * setup stacks for re-entrant exception handlers |
| @@ -838,7 +839,12 @@ static int c_show(struct seq_file *m, void *v) | |||
| 838 | 839 | ||
| 839 | #if defined(CONFIG_SMP) | 840 | #if defined(CONFIG_SMP) |
| 840 | for_each_online_cpu(i) { | 841 | for_each_online_cpu(i) { |
| 841 | seq_printf(m, "Processor\t: %d\n", i); | 842 | /* |
| 843 | * glibc reads /proc/cpuinfo to determine the number of | ||
| 844 | * online processors, looking for lines beginning with | ||
| 845 | * "processor". Give glibc what it expects. | ||
| 846 | */ | ||
| 847 | seq_printf(m, "processor\t: %d\n", i); | ||
| 842 | seq_printf(m, "BogoMIPS\t: %lu.%02lu\n\n", | 848 | seq_printf(m, "BogoMIPS\t: %lu.%02lu\n\n", |
| 843 | per_cpu(cpu_data, i).loops_per_jiffy / (500000UL/HZ), | 849 | per_cpu(cpu_data, i).loops_per_jiffy / (500000UL/HZ), |
| 844 | (per_cpu(cpu_data, i).loops_per_jiffy / (5000UL/HZ)) % 100); | 850 | (per_cpu(cpu_data, i).loops_per_jiffy / (5000UL/HZ)) % 100); |
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index edb5a406922f..e55ea952f7aa 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c | |||
| @@ -142,7 +142,7 @@ int __cpuinit __cpu_up(unsigned int cpu) | |||
| 142 | ret = -EIO; | 142 | ret = -EIO; |
| 143 | } | 143 | } |
| 144 | 144 | ||
| 145 | secondary_data.stack = 0; | 145 | secondary_data.stack = NULL; |
| 146 | secondary_data.pgdir = 0; | 146 | secondary_data.pgdir = 0; |
| 147 | 147 | ||
| 148 | *pmd_offset(pgd, PHYS_OFFSET) = __pmd(0); | 148 | *pmd_offset(pgd, PHYS_OFFSET) = __pmd(0); |
| @@ -185,6 +185,11 @@ int __cpuexit __cpu_disable(void) | |||
| 185 | migrate_irqs(); | 185 | migrate_irqs(); |
| 186 | 186 | ||
| 187 | /* | 187 | /* |
| 188 | * Stop the local timer for this CPU. | ||
| 189 | */ | ||
| 190 | local_timer_stop(cpu); | ||
| 191 | |||
| 192 | /* | ||
| 188 | * Flush user cache and TLB mappings, and then remove this CPU | 193 | * Flush user cache and TLB mappings, and then remove this CPU |
| 189 | * from the vm mask set of all processes. | 194 | * from the vm mask set of all processes. |
| 190 | */ | 195 | */ |
| @@ -251,7 +256,9 @@ void __cpuexit cpu_die(void) | |||
| 251 | asmlinkage void __cpuinit secondary_start_kernel(void) | 256 | asmlinkage void __cpuinit secondary_start_kernel(void) |
| 252 | { | 257 | { |
| 253 | struct mm_struct *mm = &init_mm; | 258 | struct mm_struct *mm = &init_mm; |
| 254 | unsigned int cpu = smp_processor_id(); | 259 | unsigned int cpu; |
| 260 | |||
| 261 | cpu = smp_processor_id(); | ||
| 255 | 262 | ||
| 256 | printk("CPU%u: Booted secondary processor\n", cpu); | 263 | printk("CPU%u: Booted secondary processor\n", cpu); |
| 257 | 264 | ||
| @@ -268,6 +275,7 @@ asmlinkage void __cpuinit secondary_start_kernel(void) | |||
| 268 | local_flush_tlb_all(); | 275 | local_flush_tlb_all(); |
| 269 | 276 | ||
| 270 | cpu_init(); | 277 | cpu_init(); |
| 278 | preempt_disable(); | ||
| 271 | 279 | ||
| 272 | /* | 280 | /* |
| 273 | * Give the platform a chance to do its own initialisation. | 281 | * Give the platform a chance to do its own initialisation. |
| @@ -290,6 +298,11 @@ asmlinkage void __cpuinit secondary_start_kernel(void) | |||
| 290 | cpu_set(cpu, cpu_online_map); | 298 | cpu_set(cpu, cpu_online_map); |
| 291 | 299 | ||
| 292 | /* | 300 | /* |
| 301 | * Setup local timer for this CPU. | ||
| 302 | */ | ||
| 303 | local_timer_setup(cpu); | ||
| 304 | |||
| 305 | /* | ||
| 293 | * OK, it's off to the idle thread for us | 306 | * OK, it's off to the idle thread for us |
| 294 | */ | 307 | */ |
| 295 | cpu_idle(); | 308 | cpu_idle(); |
| @@ -359,8 +372,8 @@ static void send_ipi_message(cpumask_t callmap, enum ipi_msg_type msg) | |||
| 359 | * You must not call this function with disabled interrupts, from a | 372 | * You must not call this function with disabled interrupts, from a |
| 360 | * hardware interrupt handler, nor from a bottom half handler. | 373 | * hardware interrupt handler, nor from a bottom half handler. |
| 361 | */ | 374 | */ |
| 362 | int smp_call_function_on_cpu(void (*func)(void *info), void *info, int retry, | 375 | static int smp_call_function_on_cpu(void (*func)(void *info), void *info, |
| 363 | int wait, cpumask_t callmap) | 376 | int retry, int wait, cpumask_t callmap) |
| 364 | { | 377 | { |
| 365 | struct smp_call_struct data; | 378 | struct smp_call_struct data; |
| 366 | unsigned long timeout; | 379 | unsigned long timeout; |
| @@ -454,6 +467,18 @@ void show_ipi_list(struct seq_file *p) | |||
| 454 | seq_putc(p, '\n'); | 467 | seq_putc(p, '\n'); |
| 455 | } | 468 | } |
| 456 | 469 | ||
| 470 | void show_local_irqs(struct seq_file *p) | ||
| 471 | { | ||
| 472 | unsigned int cpu; | ||
| 473 | |||
| 474 | seq_printf(p, "LOC: "); | ||
| 475 | |||
| 476 | for_each_present_cpu(cpu) | ||
| 477 | seq_printf(p, "%10u ", irq_stat[cpu].local_timer_irqs); | ||
| 478 | |||
| 479 | seq_putc(p, '\n'); | ||
| 480 | } | ||
| 481 | |||
| 457 | static void ipi_timer(struct pt_regs *regs) | 482 | static void ipi_timer(struct pt_regs *regs) |
| 458 | { | 483 | { |
| 459 | int user = user_mode(regs); | 484 | int user = user_mode(regs); |
| @@ -464,6 +489,18 @@ static void ipi_timer(struct pt_regs *regs) | |||
| 464 | irq_exit(); | 489 | irq_exit(); |
| 465 | } | 490 | } |
| 466 | 491 | ||
| 492 | #ifdef CONFIG_LOCAL_TIMERS | ||
| 493 | asmlinkage void do_local_timer(struct pt_regs *regs) | ||
| 494 | { | ||
| 495 | int cpu = smp_processor_id(); | ||
| 496 | |||
| 497 | if (local_timer_ack()) { | ||
| 498 | irq_stat[cpu].local_timer_irqs++; | ||
| 499 | ipi_timer(regs); | ||
| 500 | } | ||
| 501 | } | ||
| 502 | #endif | ||
| 503 | |||
| 467 | /* | 504 | /* |
| 468 | * ipi_call_function - handle IPI from smp_call_function() | 505 | * ipi_call_function - handle IPI from smp_call_function() |
| 469 | * | 506 | * |
| @@ -515,7 +552,7 @@ static void ipi_cpu_stop(unsigned int cpu) | |||
| 515 | * | 552 | * |
| 516 | * Bit 0 - Inter-processor function call | 553 | * Bit 0 - Inter-processor function call |
| 517 | */ | 554 | */ |
| 518 | void do_IPI(struct pt_regs *regs) | 555 | asmlinkage void do_IPI(struct pt_regs *regs) |
| 519 | { | 556 | { |
| 520 | unsigned int cpu = smp_processor_id(); | 557 | unsigned int cpu = smp_processor_id(); |
| 521 | struct ipi_data *ipi = &per_cpu(ipi_data, cpu); | 558 | struct ipi_data *ipi = &per_cpu(ipi_data, cpu); |
diff --git a/arch/arm/lib/bitops.h b/arch/arm/lib/bitops.h index f35d91fbe117..b8c14e936697 100644 --- a/arch/arm/lib/bitops.h +++ b/arch/arm/lib/bitops.h | |||
| @@ -34,7 +34,7 @@ | |||
| 34 | and r2, r0, #7 | 34 | and r2, r0, #7 |
| 35 | mov r3, #1 | 35 | mov r3, #1 |
| 36 | mov r3, r3, lsl r2 | 36 | mov r3, r3, lsl r2 |
| 37 | save_and_disable_irqs ip, r2 | 37 | save_and_disable_irqs ip |
| 38 | ldrb r2, [r1, r0, lsr #3] | 38 | ldrb r2, [r1, r0, lsr #3] |
| 39 | \instr r2, r2, r3 | 39 | \instr r2, r2, r3 |
| 40 | strb r2, [r1, r0, lsr #3] | 40 | strb r2, [r1, r0, lsr #3] |
| @@ -54,7 +54,7 @@ | |||
| 54 | add r1, r1, r0, lsr #3 | 54 | add r1, r1, r0, lsr #3 |
| 55 | and r3, r0, #7 | 55 | and r3, r0, #7 |
| 56 | mov r0, #1 | 56 | mov r0, #1 |
| 57 | save_and_disable_irqs ip, r2 | 57 | save_and_disable_irqs ip |
| 58 | ldrb r2, [r1] | 58 | ldrb r2, [r1] |
| 59 | tst r2, r0, lsl r3 | 59 | tst r2, r0, lsl r3 |
| 60 | \instr r2, r2, r0, lsl r3 | 60 | \instr r2, r2, r0, lsl r3 |
diff --git a/arch/arm/mach-aaec2000/clock.c b/arch/arm/mach-aaec2000/clock.c index 99e019169dda..0340ddc4824e 100644 --- a/arch/arm/mach-aaec2000/clock.c +++ b/arch/arm/mach-aaec2000/clock.c | |||
| @@ -14,6 +14,7 @@ | |||
| 14 | #include <linux/list.h> | 14 | #include <linux/list.h> |
| 15 | #include <linux/errno.h> | 15 | #include <linux/errno.h> |
| 16 | #include <linux/err.h> | 16 | #include <linux/err.h> |
| 17 | #include <linux/string.h> | ||
| 17 | 18 | ||
| 18 | #include <asm/semaphore.h> | 19 | #include <asm/semaphore.h> |
| 19 | #include <asm/hardware/clock.h> | 20 | #include <asm/hardware/clock.h> |
diff --git a/arch/arm/mach-epxa10db/mm.c b/arch/arm/mach-epxa10db/mm.c index e8832d0910ee..cfd0d2182d44 100644 --- a/arch/arm/mach-epxa10db/mm.c +++ b/arch/arm/mach-epxa10db/mm.c | |||
| @@ -25,6 +25,7 @@ | |||
| 25 | #include <asm/hardware.h> | 25 | #include <asm/hardware.h> |
| 26 | #include <asm/io.h> | 26 | #include <asm/io.h> |
| 27 | #include <asm/sizes.h> | 27 | #include <asm/sizes.h> |
| 28 | #include <asm/page.h> | ||
| 28 | 29 | ||
| 29 | #include <asm/mach/map.h> | 30 | #include <asm/mach/map.h> |
| 30 | 31 | ||
diff --git a/arch/arm/mach-integrator/impd1.c b/arch/arm/mach-integrator/impd1.c index a1b153d1626c..a4bafee77a06 100644 --- a/arch/arm/mach-integrator/impd1.c +++ b/arch/arm/mach-integrator/impd1.c | |||
| @@ -420,8 +420,7 @@ static int impd1_probe(struct lm_device *dev) | |||
| 420 | free_impd1: | 420 | free_impd1: |
| 421 | if (impd1 && impd1->base) | 421 | if (impd1 && impd1->base) |
| 422 | iounmap(impd1->base); | 422 | iounmap(impd1->base); |
| 423 | if (impd1) | 423 | kfree(impd1); |
| 424 | kfree(impd1); | ||
| 425 | release_lm: | 424 | release_lm: |
| 426 | release_mem_region(dev->resource.start, SZ_4K); | 425 | release_mem_region(dev->resource.start, SZ_4K); |
| 427 | return ret; | 426 | return ret; |
diff --git a/arch/arm/mach-ixp2000/core.c b/arch/arm/mach-ixp2000/core.c index df140962bb0f..6851abaf5524 100644 --- a/arch/arm/mach-ixp2000/core.c +++ b/arch/arm/mach-ixp2000/core.c | |||
| @@ -84,63 +84,54 @@ static struct map_desc ixp2000_io_desc[] __initdata = { | |||
| 84 | .virtual = IXP2000_CAP_VIRT_BASE, | 84 | .virtual = IXP2000_CAP_VIRT_BASE, |
| 85 | .pfn = __phys_to_pfn(IXP2000_CAP_PHYS_BASE), | 85 | .pfn = __phys_to_pfn(IXP2000_CAP_PHYS_BASE), |
| 86 | .length = IXP2000_CAP_SIZE, | 86 | .length = IXP2000_CAP_SIZE, |
| 87 | .type = MT_DEVICE | 87 | .type = MT_IXP2000_DEVICE, |
| 88 | }, { | 88 | }, { |
| 89 | .virtual = IXP2000_INTCTL_VIRT_BASE, | 89 | .virtual = IXP2000_INTCTL_VIRT_BASE, |
| 90 | .pfn = __phys_to_pfn(IXP2000_INTCTL_PHYS_BASE), | 90 | .pfn = __phys_to_pfn(IXP2000_INTCTL_PHYS_BASE), |
| 91 | .length = IXP2000_INTCTL_SIZE, | 91 | .length = IXP2000_INTCTL_SIZE, |
| 92 | .type = MT_DEVICE | 92 | .type = MT_IXP2000_DEVICE, |
| 93 | }, { | 93 | }, { |
| 94 | .virtual = IXP2000_PCI_CREG_VIRT_BASE, | 94 | .virtual = IXP2000_PCI_CREG_VIRT_BASE, |
| 95 | .pfn = __phys_to_pfn(IXP2000_PCI_CREG_PHYS_BASE), | 95 | .pfn = __phys_to_pfn(IXP2000_PCI_CREG_PHYS_BASE), |
| 96 | .length = IXP2000_PCI_CREG_SIZE, | 96 | .length = IXP2000_PCI_CREG_SIZE, |
| 97 | .type = MT_DEVICE | 97 | .type = MT_IXP2000_DEVICE, |
| 98 | }, { | 98 | }, { |
| 99 | .virtual = IXP2000_PCI_CSR_VIRT_BASE, | 99 | .virtual = IXP2000_PCI_CSR_VIRT_BASE, |
| 100 | .pfn = __phys_to_pfn(IXP2000_PCI_CSR_PHYS_BASE), | 100 | .pfn = __phys_to_pfn(IXP2000_PCI_CSR_PHYS_BASE), |
| 101 | .length = IXP2000_PCI_CSR_SIZE, | 101 | .length = IXP2000_PCI_CSR_SIZE, |
| 102 | .type = MT_DEVICE | 102 | .type = MT_IXP2000_DEVICE, |
| 103 | }, { | 103 | }, { |
| 104 | .virtual = IXP2000_MSF_VIRT_BASE, | 104 | .virtual = IXP2000_MSF_VIRT_BASE, |
| 105 | .pfn = __phys_to_pfn(IXP2000_MSF_PHYS_BASE), | 105 | .pfn = __phys_to_pfn(IXP2000_MSF_PHYS_BASE), |
| 106 | .length = IXP2000_MSF_SIZE, | 106 | .length = IXP2000_MSF_SIZE, |
| 107 | .type = MT_DEVICE | 107 | .type = MT_IXP2000_DEVICE, |
| 108 | }, { | 108 | }, { |
| 109 | .virtual = IXP2000_PCI_IO_VIRT_BASE, | 109 | .virtual = IXP2000_PCI_IO_VIRT_BASE, |
| 110 | .pfn = __phys_to_pfn(IXP2000_PCI_IO_PHYS_BASE), | 110 | .pfn = __phys_to_pfn(IXP2000_PCI_IO_PHYS_BASE), |
| 111 | .length = IXP2000_PCI_IO_SIZE, | 111 | .length = IXP2000_PCI_IO_SIZE, |
| 112 | .type = MT_DEVICE | 112 | .type = MT_IXP2000_DEVICE, |
| 113 | }, { | 113 | }, { |
| 114 | .virtual = IXP2000_PCI_CFG0_VIRT_BASE, | 114 | .virtual = IXP2000_PCI_CFG0_VIRT_BASE, |
| 115 | .pfn = __phys_to_pfn(IXP2000_PCI_CFG0_PHYS_BASE), | 115 | .pfn = __phys_to_pfn(IXP2000_PCI_CFG0_PHYS_BASE), |
| 116 | .length = IXP2000_PCI_CFG0_SIZE, | 116 | .length = IXP2000_PCI_CFG0_SIZE, |
| 117 | .type = MT_DEVICE | 117 | .type = MT_IXP2000_DEVICE, |
| 118 | }, { | 118 | }, { |
| 119 | .virtual = IXP2000_PCI_CFG1_VIRT_BASE, | 119 | .virtual = IXP2000_PCI_CFG1_VIRT_BASE, |
| 120 | .pfn = __phys_to_pfn(IXP2000_PCI_CFG1_PHYS_BASE), | 120 | .pfn = __phys_to_pfn(IXP2000_PCI_CFG1_PHYS_BASE), |
| 121 | .length = IXP2000_PCI_CFG1_SIZE, | 121 | .length = IXP2000_PCI_CFG1_SIZE, |
| 122 | .type = MT_DEVICE | 122 | .type = MT_IXP2000_DEVICE, |
| 123 | } | 123 | } |
| 124 | }; | 124 | }; |
| 125 | 125 | ||
| 126 | void __init ixp2000_map_io(void) | 126 | void __init ixp2000_map_io(void) |
| 127 | { | 127 | { |
| 128 | extern unsigned int processor_id; | ||
| 129 | |||
| 130 | /* | 128 | /* |
| 131 | * On IXP2400 CPUs we need to use MT_IXP2000_DEVICE for | 129 | * On IXP2400 CPUs we need to use MT_IXP2000_DEVICE so that |
| 132 | * tweaking the PMDs so XCB=101. On IXP2800s we use the normal | 130 | * XCB=101 (to avoid triggering erratum #66), and given that |
| 133 | * PMD flags. | 131 | * this mode speeds up I/O accesses and we have write buffer |
| 132 | * flushes in the right places anyway, it doesn't hurt to use | ||
| 133 | * XCB=101 for all IXP2000s. | ||
| 134 | */ | 134 | */ |
| 135 | if ((processor_id & 0xfffffff0) == 0x69054190) { | ||
| 136 | int i; | ||
| 137 | |||
| 138 | printk(KERN_INFO "Enabling IXP2400 erratum #66 workaround\n"); | ||
| 139 | |||
| 140 | for(i=0;i<ARRAY_SIZE(ixp2000_io_desc);i++) | ||
| 141 | ixp2000_io_desc[i].type = MT_IXP2000_DEVICE; | ||
| 142 | } | ||
| 143 | |||
| 144 | iotable_init(ixp2000_io_desc, ARRAY_SIZE(ixp2000_io_desc)); | 135 | iotable_init(ixp2000_io_desc, ARRAY_SIZE(ixp2000_io_desc)); |
| 145 | 136 | ||
| 146 | /* Set slowport to 8-bit mode. */ | 137 | /* Set slowport to 8-bit mode. */ |
diff --git a/arch/arm/mach-ixp2000/uengine.c b/arch/arm/mach-ixp2000/uengine.c index 43e234349d4a..ec4e007a22ef 100644 --- a/arch/arm/mach-ixp2000/uengine.c +++ b/arch/arm/mach-ixp2000/uengine.c | |||
| @@ -91,8 +91,8 @@ EXPORT_SYMBOL(ixp2000_uengine_csr_write); | |||
| 91 | 91 | ||
| 92 | void ixp2000_uengine_reset(u32 uengine_mask) | 92 | void ixp2000_uengine_reset(u32 uengine_mask) |
| 93 | { | 93 | { |
| 94 | ixp2000_reg_write(IXP2000_RESET1, uengine_mask & ixp2000_uengine_mask); | 94 | ixp2000_reg_wrb(IXP2000_RESET1, uengine_mask & ixp2000_uengine_mask); |
| 95 | ixp2000_reg_write(IXP2000_RESET1, 0); | 95 | ixp2000_reg_wrb(IXP2000_RESET1, 0); |
| 96 | } | 96 | } |
| 97 | EXPORT_SYMBOL(ixp2000_uengine_reset); | 97 | EXPORT_SYMBOL(ixp2000_uengine_reset); |
| 98 | 98 | ||
| @@ -452,21 +452,20 @@ static int __init ixp2000_uengine_init(void) | |||
| 452 | /* | 452 | /* |
| 453 | * Reset microengines. | 453 | * Reset microengines. |
| 454 | */ | 454 | */ |
| 455 | ixp2000_reg_write(IXP2000_RESET1, ixp2000_uengine_mask); | 455 | ixp2000_uengine_reset(ixp2000_uengine_mask); |
| 456 | ixp2000_reg_write(IXP2000_RESET1, 0); | ||
| 457 | 456 | ||
| 458 | /* | 457 | /* |
| 459 | * Synchronise timestamp counters across all microengines. | 458 | * Synchronise timestamp counters across all microengines. |
| 460 | */ | 459 | */ |
| 461 | value = ixp2000_reg_read(IXP2000_MISC_CONTROL); | 460 | value = ixp2000_reg_read(IXP2000_MISC_CONTROL); |
| 462 | ixp2000_reg_write(IXP2000_MISC_CONTROL, value & ~0x80); | 461 | ixp2000_reg_wrb(IXP2000_MISC_CONTROL, value & ~0x80); |
| 463 | for (uengine = 0; uengine < 32; uengine++) { | 462 | for (uengine = 0; uengine < 32; uengine++) { |
| 464 | if (ixp2000_uengine_mask & (1 << uengine)) { | 463 | if (ixp2000_uengine_mask & (1 << uengine)) { |
| 465 | ixp2000_uengine_csr_write(uengine, TIMESTAMP_LOW, 0); | 464 | ixp2000_uengine_csr_write(uengine, TIMESTAMP_LOW, 0); |
| 466 | ixp2000_uengine_csr_write(uengine, TIMESTAMP_HIGH, 0); | 465 | ixp2000_uengine_csr_write(uengine, TIMESTAMP_HIGH, 0); |
| 467 | } | 466 | } |
| 468 | } | 467 | } |
| 469 | ixp2000_reg_write(IXP2000_MISC_CONTROL, value | 0x80); | 468 | ixp2000_reg_wrb(IXP2000_MISC_CONTROL, value | 0x80); |
| 470 | 469 | ||
| 471 | return 0; | 470 | return 0; |
| 472 | } | 471 | } |
diff --git a/arch/arm/mach-ixp4xx/common-pci.c b/arch/arm/mach-ixp4xx/common-pci.c index 2b544363c078..9795da270e3a 100644 --- a/arch/arm/mach-ixp4xx/common-pci.c +++ b/arch/arm/mach-ixp4xx/common-pci.c | |||
| @@ -427,7 +427,7 @@ void __init ixp4xx_pci_preinit(void) | |||
| 427 | #ifdef __ARMEB__ | 427 | #ifdef __ARMEB__ |
| 428 | *PCI_CSR = PCI_CSR_IC | PCI_CSR_ABE | PCI_CSR_PDS | PCI_CSR_ADS; | 428 | *PCI_CSR = PCI_CSR_IC | PCI_CSR_ABE | PCI_CSR_PDS | PCI_CSR_ADS; |
| 429 | #else | 429 | #else |
| 430 | *PCI_CSR = PCI_CSR_IC; | 430 | *PCI_CSR = PCI_CSR_IC | PCI_CSR_ABE; |
| 431 | #endif | 431 | #endif |
| 432 | 432 | ||
| 433 | pr_debug("DONE\n"); | 433 | pr_debug("DONE\n"); |
diff --git a/arch/arm/mach-omap1/leds-h2p2-debug.c b/arch/arm/mach-omap1/leds-h2p2-debug.c index be283cda63dd..399010c14036 100644 --- a/arch/arm/mach-omap1/leds-h2p2-debug.c +++ b/arch/arm/mach-omap1/leds-h2p2-debug.c | |||
| @@ -13,7 +13,6 @@ | |||
| 13 | #include <linux/init.h> | 13 | #include <linux/init.h> |
| 14 | #include <linux/kernel_stat.h> | 14 | #include <linux/kernel_stat.h> |
| 15 | #include <linux/sched.h> | 15 | #include <linux/sched.h> |
| 16 | #include <linux/version.h> | ||
| 17 | 16 | ||
| 18 | #include <asm/io.h> | 17 | #include <asm/io.h> |
| 19 | #include <asm/hardware.h> | 18 | #include <asm/hardware.h> |
diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig index 3e5f69bb5ac4..b380a438e68f 100644 --- a/arch/arm/mach-pxa/Kconfig +++ b/arch/arm/mach-pxa/Kconfig | |||
| @@ -27,7 +27,8 @@ config PXA_SHARPSL | |||
| 27 | Say Y here if you intend to run this kernel on a | 27 | Say Y here if you intend to run this kernel on a |
| 28 | Sharp Zaurus SL-5600 (Poodle), SL-C700 (Corgi), | 28 | Sharp Zaurus SL-5600 (Poodle), SL-C700 (Corgi), |
| 29 | SL-C750 (Shepherd), SL-C760 (Husky), SL-C1000 (Akita), | 29 | SL-C750 (Shepherd), SL-C760 (Husky), SL-C1000 (Akita), |
| 30 | SL-C3000 (Spitz) or SL-C3100 (Borzoi) handheld computer. | 30 | SL-C3000 (Spitz), SL-C3100 (Borzoi) or SL-C6000x (Tosa) |
| 31 | handheld computer. | ||
| 31 | 32 | ||
| 32 | endchoice | 33 | endchoice |
| 33 | 34 | ||
| @@ -37,7 +38,7 @@ choice | |||
| 37 | prompt "Select target Sharp Zaurus device range" | 38 | prompt "Select target Sharp Zaurus device range" |
| 38 | 39 | ||
| 39 | config PXA_SHARPSL_25x | 40 | config PXA_SHARPSL_25x |
| 40 | bool "Sharp PXA25x models (SL-5600 and SL-C7xx)" | 41 | bool "Sharp PXA25x models (SL-5600, SL-C7xx and SL-C6000x)" |
| 41 | select PXA25x | 42 | select PXA25x |
| 42 | 43 | ||
| 43 | config PXA_SHARPSL_27x | 44 | config PXA_SHARPSL_27x |
| @@ -80,6 +81,10 @@ config MACH_BORZOI | |||
| 80 | depends PXA_SHARPSL_27x | 81 | depends PXA_SHARPSL_27x |
| 81 | select PXA_SHARP_Cxx00 | 82 | select PXA_SHARP_Cxx00 |
| 82 | 83 | ||
| 84 | config MACH_TOSA | ||
| 85 | bool "Enable Sharp SL-6000x (Tosa) Support" | ||
| 86 | depends PXA_SHARPSL | ||
| 87 | |||
| 83 | config PXA25x | 88 | config PXA25x |
| 84 | bool | 89 | bool |
| 85 | help | 90 | help |
diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile index f609a0f232cb..8bc72d07cea8 100644 --- a/arch/arm/mach-pxa/Makefile +++ b/arch/arm/mach-pxa/Makefile | |||
| @@ -14,6 +14,7 @@ obj-$(CONFIG_ARCH_PXA_IDP) += idp.o | |||
| 14 | obj-$(CONFIG_PXA_SHARP_C7xx) += corgi.o corgi_ssp.o corgi_lcd.o ssp.o | 14 | obj-$(CONFIG_PXA_SHARP_C7xx) += corgi.o corgi_ssp.o corgi_lcd.o ssp.o |
| 15 | obj-$(CONFIG_PXA_SHARP_Cxx00) += spitz.o corgi_ssp.o corgi_lcd.o ssp.o | 15 | obj-$(CONFIG_PXA_SHARP_Cxx00) += spitz.o corgi_ssp.o corgi_lcd.o ssp.o |
| 16 | obj-$(CONFIG_MACH_POODLE) += poodle.o | 16 | obj-$(CONFIG_MACH_POODLE) += poodle.o |
| 17 | obj-$(CONFIG_MACH_TOSA) += tosa.o | ||
| 17 | 18 | ||
| 18 | # Support for blinky lights | 19 | # Support for blinky lights |
| 19 | led-y := leds.o | 20 | led-y := leds.o |
diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c index eb5f6d744a4a..100fb31b5156 100644 --- a/arch/arm/mach-pxa/corgi.c +++ b/arch/arm/mach-pxa/corgi.c | |||
| @@ -62,6 +62,37 @@ static struct scoop_config corgi_scoop_setup = { | |||
| 62 | .io_out = CORGI_SCOOP_IO_OUT, | 62 | .io_out = CORGI_SCOOP_IO_OUT, |
| 63 | }; | 63 | }; |
| 64 | 64 | ||
| 65 | struct platform_device corgiscoop_device = { | ||
| 66 | .name = "sharp-scoop", | ||
| 67 | .id = -1, | ||
| 68 | .dev = { | ||
| 69 | .platform_data = &corgi_scoop_setup, | ||
| 70 | }, | ||
| 71 | .num_resources = ARRAY_SIZE(corgi_scoop_resources), | ||
| 72 | .resource = corgi_scoop_resources, | ||
| 73 | }; | ||
| 74 | |||
| 75 | static void corgi_pcmcia_init(void) | ||
| 76 | { | ||
| 77 | /* Setup default state of GPIO outputs | ||
| 78 | before we enable them as outputs. */ | ||
| 79 | GPSR(GPIO48_nPOE) = GPIO_bit(GPIO48_nPOE) | | ||
| 80 | GPIO_bit(GPIO49_nPWE) | GPIO_bit(GPIO50_nPIOR) | | ||
| 81 | GPIO_bit(GPIO51_nPIOW) | GPIO_bit(GPIO52_nPCE_1) | | ||
| 82 | GPIO_bit(GPIO53_nPCE_2); | ||
| 83 | |||
| 84 | pxa_gpio_mode(GPIO48_nPOE_MD); | ||
| 85 | pxa_gpio_mode(GPIO49_nPWE_MD); | ||
| 86 | pxa_gpio_mode(GPIO50_nPIOR_MD); | ||
| 87 | pxa_gpio_mode(GPIO51_nPIOW_MD); | ||
| 88 | pxa_gpio_mode(GPIO55_nPREG_MD); | ||
| 89 | pxa_gpio_mode(GPIO56_nPWAIT_MD); | ||
| 90 | pxa_gpio_mode(GPIO57_nIOIS16_MD); | ||
| 91 | pxa_gpio_mode(GPIO52_nPCE_1_MD); | ||
| 92 | pxa_gpio_mode(GPIO53_nPCE_2_MD); | ||
| 93 | pxa_gpio_mode(GPIO54_pSKTSEL_MD); | ||
| 94 | } | ||
| 95 | |||
| 65 | static struct scoop_pcmcia_dev corgi_pcmcia_scoop[] = { | 96 | static struct scoop_pcmcia_dev corgi_pcmcia_scoop[] = { |
| 66 | { | 97 | { |
| 67 | .dev = &corgiscoop_device.dev, | 98 | .dev = &corgiscoop_device.dev, |
| @@ -71,16 +102,14 @@ static struct scoop_pcmcia_dev corgi_pcmcia_scoop[] = { | |||
| 71 | }, | 102 | }, |
| 72 | }; | 103 | }; |
| 73 | 104 | ||
| 74 | struct platform_device corgiscoop_device = { | 105 | static struct scoop_pcmcia_config corgi_pcmcia_config = { |
| 75 | .name = "sharp-scoop", | 106 | .devs = &corgi_pcmcia_scoop[0], |
| 76 | .id = -1, | 107 | .num_devs = 1, |
| 77 | .dev = { | 108 | .pcmcia_init = corgi_pcmcia_init, |
| 78 | .platform_data = &corgi_scoop_setup, | ||
| 79 | }, | ||
| 80 | .num_resources = ARRAY_SIZE(corgi_scoop_resources), | ||
| 81 | .resource = corgi_scoop_resources, | ||
| 82 | }; | 109 | }; |
| 83 | 110 | ||
| 111 | EXPORT_SYMBOL(corgiscoop_device); | ||
| 112 | |||
| 84 | 113 | ||
| 85 | /* | 114 | /* |
| 86 | * Corgi SSP Device | 115 | * Corgi SSP Device |
| @@ -294,8 +323,7 @@ static void __init corgi_init(void) | |||
| 294 | pxa_set_mci_info(&corgi_mci_platform_data); | 323 | pxa_set_mci_info(&corgi_mci_platform_data); |
| 295 | pxa_set_ficp_info(&corgi_ficp_platform_data); | 324 | pxa_set_ficp_info(&corgi_ficp_platform_data); |
| 296 | 325 | ||
| 297 | scoop_num = 1; | 326 | platform_scoop_config = &corgi_pcmcia_config; |
| 298 | scoop_devs = &corgi_pcmcia_scoop[0]; | ||
| 299 | 327 | ||
| 300 | platform_add_devices(devices, ARRAY_SIZE(devices)); | 328 | platform_add_devices(devices, ARRAY_SIZE(devices)); |
| 301 | } | 329 | } |
diff --git a/arch/arm/mach-pxa/corgi_lcd.c b/arch/arm/mach-pxa/corgi_lcd.c index 54162ba95414..698eb06545c4 100644 --- a/arch/arm/mach-pxa/corgi_lcd.c +++ b/arch/arm/mach-pxa/corgi_lcd.c | |||
| @@ -19,6 +19,7 @@ | |||
| 19 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
| 20 | #include <linux/platform_device.h> | 20 | #include <linux/platform_device.h> |
| 21 | #include <linux/module.h> | 21 | #include <linux/module.h> |
| 22 | #include <linux/string.h> | ||
| 22 | #include <asm/arch/akita.h> | 23 | #include <asm/arch/akita.h> |
| 23 | #include <asm/arch/corgi.h> | 24 | #include <asm/arch/corgi.h> |
| 24 | #include <asm/arch/hardware.h> | 25 | #include <asm/arch/hardware.h> |
diff --git a/arch/arm/mach-pxa/pm.c b/arch/arm/mach-pxa/pm.c index ac4dd4336160..f74b9af112dc 100644 --- a/arch/arm/mach-pxa/pm.c +++ b/arch/arm/mach-pxa/pm.c | |||
| @@ -12,6 +12,7 @@ | |||
| 12 | */ | 12 | */ |
| 13 | #include <linux/config.h> | 13 | #include <linux/config.h> |
| 14 | #include <linux/init.h> | 14 | #include <linux/init.h> |
| 15 | #include <linux/module.h> | ||
| 15 | #include <linux/suspend.h> | 16 | #include <linux/suspend.h> |
| 16 | #include <linux/errno.h> | 17 | #include <linux/errno.h> |
| 17 | #include <linux/time.h> | 18 | #include <linux/time.h> |
| @@ -19,6 +20,7 @@ | |||
| 19 | #include <asm/hardware.h> | 20 | #include <asm/hardware.h> |
| 20 | #include <asm/memory.h> | 21 | #include <asm/memory.h> |
| 21 | #include <asm/system.h> | 22 | #include <asm/system.h> |
| 23 | #include <asm/arch/pm.h> | ||
| 22 | #include <asm/arch/pxa-regs.h> | 24 | #include <asm/arch/pxa-regs.h> |
| 23 | #include <asm/arch/lubbock.h> | 25 | #include <asm/arch/lubbock.h> |
| 24 | #include <asm/mach/time.h> | 26 | #include <asm/mach/time.h> |
| @@ -72,7 +74,7 @@ enum { SLEEP_SAVE_START = 0, | |||
| 72 | }; | 74 | }; |
| 73 | 75 | ||
| 74 | 76 | ||
| 75 | static int pxa_pm_enter(suspend_state_t state) | 77 | int pxa_pm_enter(suspend_state_t state) |
| 76 | { | 78 | { |
| 77 | unsigned long sleep_save[SLEEP_SAVE_SIZE]; | 79 | unsigned long sleep_save[SLEEP_SAVE_SIZE]; |
| 78 | unsigned long checksum = 0; | 80 | unsigned long checksum = 0; |
| @@ -191,6 +193,8 @@ static int pxa_pm_enter(suspend_state_t state) | |||
| 191 | return 0; | 193 | return 0; |
| 192 | } | 194 | } |
| 193 | 195 | ||
| 196 | EXPORT_SYMBOL_GPL(pxa_pm_enter); | ||
| 197 | |||
| 194 | unsigned long sleep_phys_sp(void *sp) | 198 | unsigned long sleep_phys_sp(void *sp) |
| 195 | { | 199 | { |
| 196 | return virt_to_phys(sp); | 200 | return virt_to_phys(sp); |
| @@ -199,21 +203,25 @@ unsigned long sleep_phys_sp(void *sp) | |||
| 199 | /* | 203 | /* |
| 200 | * Called after processes are frozen, but before we shut down devices. | 204 | * Called after processes are frozen, but before we shut down devices. |
| 201 | */ | 205 | */ |
| 202 | static int pxa_pm_prepare(suspend_state_t state) | 206 | int pxa_pm_prepare(suspend_state_t state) |
| 203 | { | 207 | { |
| 204 | extern int pxa_cpu_pm_prepare(suspend_state_t state); | 208 | extern int pxa_cpu_pm_prepare(suspend_state_t state); |
| 205 | 209 | ||
| 206 | return pxa_cpu_pm_prepare(state); | 210 | return pxa_cpu_pm_prepare(state); |
| 207 | } | 211 | } |
| 208 | 212 | ||
| 213 | EXPORT_SYMBOL_GPL(pxa_pm_prepare); | ||
| 214 | |||
| 209 | /* | 215 | /* |
| 210 | * Called after devices are re-setup, but before processes are thawed. | 216 | * Called after devices are re-setup, but before processes are thawed. |
| 211 | */ | 217 | */ |
| 212 | static int pxa_pm_finish(suspend_state_t state) | 218 | int pxa_pm_finish(suspend_state_t state) |
| 213 | { | 219 | { |
| 214 | return 0; | 220 | return 0; |
| 215 | } | 221 | } |
| 216 | 222 | ||
| 223 | EXPORT_SYMBOL_GPL(pxa_pm_finish); | ||
| 224 | |||
| 217 | /* | 225 | /* |
| 218 | * Set to PM_DISK_FIRMWARE so we can quickly veto suspend-to-disk. | 226 | * Set to PM_DISK_FIRMWARE so we can quickly veto suspend-to-disk. |
| 219 | */ | 227 | */ |
| @@ -230,4 +238,4 @@ static int __init pxa_pm_init(void) | |||
| 230 | return 0; | 238 | return 0; |
| 231 | } | 239 | } |
| 232 | 240 | ||
| 233 | late_initcall(pxa_pm_init); | 241 | device_initcall(pxa_pm_init); |
diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c index ad6a13f95a62..eef3de26ad37 100644 --- a/arch/arm/mach-pxa/poodle.c +++ b/arch/arm/mach-pxa/poodle.c | |||
| @@ -65,6 +65,27 @@ struct platform_device poodle_scoop_device = { | |||
| 65 | .resource = poodle_scoop_resources, | 65 | .resource = poodle_scoop_resources, |
| 66 | }; | 66 | }; |
| 67 | 67 | ||
| 68 | static void poodle_pcmcia_init(void) | ||
| 69 | { | ||
| 70 | /* Setup default state of GPIO outputs | ||
| 71 | before we enable them as outputs. */ | ||
| 72 | GPSR(GPIO48_nPOE) = GPIO_bit(GPIO48_nPOE) | | ||
| 73 | GPIO_bit(GPIO49_nPWE) | GPIO_bit(GPIO50_nPIOR) | | ||
| 74 | GPIO_bit(GPIO51_nPIOW) | GPIO_bit(GPIO52_nPCE_1) | | ||
| 75 | GPIO_bit(GPIO53_nPCE_2); | ||
| 76 | |||
| 77 | pxa_gpio_mode(GPIO48_nPOE_MD); | ||
| 78 | pxa_gpio_mode(GPIO49_nPWE_MD); | ||
| 79 | pxa_gpio_mode(GPIO50_nPIOR_MD); | ||
| 80 | pxa_gpio_mode(GPIO51_nPIOW_MD); | ||
| 81 | pxa_gpio_mode(GPIO55_nPREG_MD); | ||
| 82 | pxa_gpio_mode(GPIO56_nPWAIT_MD); | ||
| 83 | pxa_gpio_mode(GPIO57_nIOIS16_MD); | ||
| 84 | pxa_gpio_mode(GPIO52_nPCE_1_MD); | ||
| 85 | pxa_gpio_mode(GPIO53_nPCE_2_MD); | ||
| 86 | pxa_gpio_mode(GPIO54_pSKTSEL_MD); | ||
| 87 | } | ||
| 88 | |||
| 68 | static struct scoop_pcmcia_dev poodle_pcmcia_scoop[] = { | 89 | static struct scoop_pcmcia_dev poodle_pcmcia_scoop[] = { |
| 69 | { | 90 | { |
| 70 | .dev = &poodle_scoop_device.dev, | 91 | .dev = &poodle_scoop_device.dev, |
| @@ -74,6 +95,14 @@ static struct scoop_pcmcia_dev poodle_pcmcia_scoop[] = { | |||
| 74 | }, | 95 | }, |
| 75 | }; | 96 | }; |
| 76 | 97 | ||
| 98 | static struct scoop_pcmcia_config poodle_pcmcia_config = { | ||
| 99 | .devs = &poodle_pcmcia_scoop[0], | ||
| 100 | .num_devs = 1, | ||
| 101 | .pcmcia_init = poodle_pcmcia_init, | ||
| 102 | }; | ||
| 103 | |||
| 104 | EXPORT_SYMBOL(poodle_scoop_device); | ||
| 105 | |||
| 77 | 106 | ||
| 78 | /* LoCoMo device */ | 107 | /* LoCoMo device */ |
| 79 | static struct resource locomo_resources[] = { | 108 | static struct resource locomo_resources[] = { |
| @@ -268,8 +297,7 @@ static void __init poodle_init(void) | |||
| 268 | pxa_set_mci_info(&poodle_mci_platform_data); | 297 | pxa_set_mci_info(&poodle_mci_platform_data); |
| 269 | pxa_set_ficp_info(&poodle_ficp_platform_data); | 298 | pxa_set_ficp_info(&poodle_ficp_platform_data); |
| 270 | 299 | ||
| 271 | scoop_num = 1; | 300 | platform_scoop_config = &poodle_pcmcia_config; |
| 272 | scoop_devs = &poodle_pcmcia_scoop[0]; | ||
| 273 | 301 | ||
| 274 | ret = platform_add_devices(devices, ARRAY_SIZE(devices)); | 302 | ret = platform_add_devices(devices, ARRAY_SIZE(devices)); |
| 275 | if (ret) { | 303 | if (ret) { |
diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c index 6c6878cd2207..4e9a699ee428 100644 --- a/arch/arm/mach-pxa/spitz.c +++ b/arch/arm/mach-pxa/spitz.c | |||
| @@ -104,6 +104,66 @@ struct platform_device spitzscoop2_device = { | |||
| 104 | .resource = spitz_scoop2_resources, | 104 | .resource = spitz_scoop2_resources, |
| 105 | }; | 105 | }; |
| 106 | 106 | ||
| 107 | #define SPITZ_PWR_SD 0x01 | ||
| 108 | #define SPITZ_PWR_CF 0x02 | ||
| 109 | |||
| 110 | /* Power control is shared with between one of the CF slots and SD */ | ||
| 111 | static void spitz_card_pwr_ctrl(int device, unsigned short new_cpr) | ||
| 112 | { | ||
| 113 | unsigned short cpr = read_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR); | ||
| 114 | |||
| 115 | if (new_cpr & 0x0007) { | ||
| 116 | set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_CF_POWER); | ||
| 117 | if (!(cpr & 0x0002) && !(cpr & 0x0004)) | ||
| 118 | mdelay(5); | ||
| 119 | if (device == SPITZ_PWR_CF) | ||
| 120 | cpr |= 0x0002; | ||
| 121 | if (device == SPITZ_PWR_SD) | ||
| 122 | cpr |= 0x0004; | ||
| 123 | write_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR, cpr | new_cpr); | ||
| 124 | } else { | ||
| 125 | if (device == SPITZ_PWR_CF) | ||
| 126 | cpr &= ~0x0002; | ||
| 127 | if (device == SPITZ_PWR_SD) | ||
| 128 | cpr &= ~0x0004; | ||
| 129 | write_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR, cpr | new_cpr); | ||
| 130 | if (!(cpr & 0x0002) && !(cpr & 0x0004)) { | ||
| 131 | mdelay(1); | ||
| 132 | reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_CF_POWER); | ||
| 133 | } | ||
| 134 | } | ||
| 135 | } | ||
| 136 | |||
| 137 | static void spitz_pcmcia_init(void) | ||
| 138 | { | ||
| 139 | /* Setup default state of GPIO outputs | ||
| 140 | before we enable them as outputs. */ | ||
| 141 | GPSR(GPIO48_nPOE) = GPIO_bit(GPIO48_nPOE) | | ||
| 142 | GPIO_bit(GPIO49_nPWE) | GPIO_bit(GPIO50_nPIOR) | | ||
| 143 | GPIO_bit(GPIO51_nPIOW) | GPIO_bit(GPIO54_nPCE_2); | ||
| 144 | GPSR(GPIO85_nPCE_1) = GPIO_bit(GPIO85_nPCE_1); | ||
| 145 | |||
| 146 | pxa_gpio_mode(GPIO48_nPOE_MD); | ||
| 147 | pxa_gpio_mode(GPIO49_nPWE_MD); | ||
| 148 | pxa_gpio_mode(GPIO50_nPIOR_MD); | ||
| 149 | pxa_gpio_mode(GPIO51_nPIOW_MD); | ||
| 150 | pxa_gpio_mode(GPIO55_nPREG_MD); | ||
| 151 | pxa_gpio_mode(GPIO56_nPWAIT_MD); | ||
| 152 | pxa_gpio_mode(GPIO57_nIOIS16_MD); | ||
| 153 | pxa_gpio_mode(GPIO85_nPCE_1_MD); | ||
| 154 | pxa_gpio_mode(GPIO54_nPCE_2_MD); | ||
| 155 | pxa_gpio_mode(GPIO104_pSKTSEL_MD); | ||
| 156 | } | ||
| 157 | |||
| 158 | static void spitz_pcmcia_pwr(struct device *scoop, unsigned short cpr, int nr) | ||
| 159 | { | ||
| 160 | /* Only need to override behaviour for slot 0 */ | ||
| 161 | if (nr == 0) | ||
| 162 | spitz_card_pwr_ctrl(SPITZ_PWR_CF, cpr); | ||
| 163 | else | ||
| 164 | write_scoop_reg(scoop, SCOOP_CPR, cpr); | ||
| 165 | } | ||
| 166 | |||
| 107 | static struct scoop_pcmcia_dev spitz_pcmcia_scoop[] = { | 167 | static struct scoop_pcmcia_dev spitz_pcmcia_scoop[] = { |
| 108 | { | 168 | { |
| 109 | .dev = &spitzscoop_device.dev, | 169 | .dev = &spitzscoop_device.dev, |
| @@ -117,6 +177,16 @@ static struct scoop_pcmcia_dev spitz_pcmcia_scoop[] = { | |||
| 117 | }, | 177 | }, |
| 118 | }; | 178 | }; |
| 119 | 179 | ||
| 180 | static struct scoop_pcmcia_config spitz_pcmcia_config = { | ||
| 181 | .devs = &spitz_pcmcia_scoop[0], | ||
| 182 | .num_devs = 2, | ||
| 183 | .pcmcia_init = spitz_pcmcia_init, | ||
| 184 | .power_ctrl = spitz_pcmcia_pwr, | ||
| 185 | }; | ||
| 186 | |||
| 187 | EXPORT_SYMBOL(spitzscoop_device); | ||
| 188 | EXPORT_SYMBOL(spitzscoop2_device); | ||
| 189 | |||
| 120 | 190 | ||
| 121 | /* | 191 | /* |
| 122 | * Spitz SSP Device | 192 | * Spitz SSP Device |
| @@ -235,27 +305,14 @@ static int spitz_mci_init(struct device *dev, irqreturn_t (*spitz_detect_int)(in | |||
| 235 | return 0; | 305 | return 0; |
| 236 | } | 306 | } |
| 237 | 307 | ||
| 238 | /* Power control is shared with one of the CF slots so we have a mess */ | ||
| 239 | static void spitz_mci_setpower(struct device *dev, unsigned int vdd) | 308 | static void spitz_mci_setpower(struct device *dev, unsigned int vdd) |
| 240 | { | 309 | { |
| 241 | struct pxamci_platform_data* p_d = dev->platform_data; | 310 | struct pxamci_platform_data* p_d = dev->platform_data; |
| 242 | 311 | ||
| 243 | unsigned short cpr = read_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR); | 312 | if (( 1 << vdd) & p_d->ocr_mask) |
| 244 | 313 | spitz_card_pwr_ctrl(SPITZ_PWR_SD, 0x0004); | |
| 245 | if (( 1 << vdd) & p_d->ocr_mask) { | 314 | else |
| 246 | /* printk(KERN_DEBUG "%s: on\n", __FUNCTION__); */ | 315 | spitz_card_pwr_ctrl(SPITZ_PWR_SD, 0x0000); |
| 247 | set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_CF_POWER); | ||
| 248 | mdelay(2); | ||
| 249 | write_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR, cpr | 0x04); | ||
| 250 | } else { | ||
| 251 | /* printk(KERN_DEBUG "%s: off\n", __FUNCTION__); */ | ||
| 252 | write_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR, cpr & ~0x04); | ||
| 253 | |||
| 254 | if (!(cpr | 0x02)) { | ||
| 255 | mdelay(1); | ||
| 256 | reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_CF_POWER); | ||
| 257 | } | ||
| 258 | } | ||
| 259 | } | 316 | } |
| 260 | 317 | ||
| 261 | static int spitz_mci_get_ro(struct device *dev) | 318 | static int spitz_mci_get_ro(struct device *dev) |
| @@ -351,8 +408,8 @@ static void __init common_init(void) | |||
| 351 | 408 | ||
| 352 | static void __init spitz_init(void) | 409 | static void __init spitz_init(void) |
| 353 | { | 410 | { |
| 354 | scoop_num = 2; | 411 | platform_scoop_config = &spitz_pcmcia_config; |
| 355 | scoop_devs = &spitz_pcmcia_scoop[0]; | 412 | |
| 356 | spitz_bl_machinfo.set_bl_intensity = spitz_bl_set_intensity; | 413 | spitz_bl_machinfo.set_bl_intensity = spitz_bl_set_intensity; |
| 357 | 414 | ||
| 358 | common_init(); | 415 | common_init(); |
diff --git a/arch/arm/mach-pxa/time.c b/arch/arm/mach-pxa/time.c index 7dad3f1465e0..b9b2057349eb 100644 --- a/arch/arm/mach-pxa/time.c +++ b/arch/arm/mach-pxa/time.c | |||
| @@ -132,11 +132,13 @@ static void __init pxa_timer_init(void) | |||
| 132 | tv.tv_sec = pxa_get_rtc_time(); | 132 | tv.tv_sec = pxa_get_rtc_time(); |
| 133 | do_settimeofday(&tv); | 133 | do_settimeofday(&tv); |
| 134 | 134 | ||
| 135 | OSMR0 = 0; /* set initial match at 0 */ | 135 | OIER = 0; /* disable any timer interrupts */ |
| 136 | OSCR = LATCH*2; /* push OSCR out of the way */ | ||
| 137 | OSMR0 = LATCH; /* set initial match */ | ||
| 136 | OSSR = 0xf; /* clear status on all timers */ | 138 | OSSR = 0xf; /* clear status on all timers */ |
| 137 | setup_irq(IRQ_OST0, &pxa_timer_irq); | 139 | setup_irq(IRQ_OST0, &pxa_timer_irq); |
| 138 | OIER |= OIER_E0; /* enable match on timer 0 to cause interrupts */ | 140 | OIER = OIER_E0; /* enable match on timer 0 to cause interrupts */ |
| 139 | OSCR = 0; /* initialize free-running timer, force first match */ | 141 | OSCR = 0; /* initialize free-running timer */ |
| 140 | } | 142 | } |
| 141 | 143 | ||
| 142 | #ifdef CONFIG_NO_IDLE_HZ | 144 | #ifdef CONFIG_NO_IDLE_HZ |
diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c new file mode 100644 index 000000000000..c312054dfb88 --- /dev/null +++ b/arch/arm/mach-pxa/tosa.c | |||
| @@ -0,0 +1,306 @@ | |||
| 1 | /* | ||
| 2 | * Support for Sharp SL-C6000x PDAs | ||
| 3 | * Model: (Tosa) | ||
| 4 | * | ||
| 5 | * Copyright (c) 2005 Dirk Opfer | ||
| 6 | * | ||
| 7 | * Based on code written by Sharp/Lineo for 2.4 kernels | ||
| 8 | * | ||
| 9 | * This program is free software; you can redistribute it and/or modify | ||
| 10 | * it under the terms of the GNU General Public License version 2 as | ||
| 11 | * published by the Free Software Foundation. | ||
| 12 | * | ||
| 13 | */ | ||
| 14 | |||
| 15 | #include <linux/kernel.h> | ||
| 16 | #include <linux/init.h> | ||
| 17 | #include <linux/device.h> | ||
| 18 | #include <linux/major.h> | ||
| 19 | #include <linux/fs.h> | ||
| 20 | #include <linux/interrupt.h> | ||
| 21 | #include <linux/mmc/host.h> | ||
| 22 | |||
| 23 | #include <asm/setup.h> | ||
| 24 | #include <asm/memory.h> | ||
| 25 | #include <asm/mach-types.h> | ||
| 26 | #include <asm/hardware.h> | ||
| 27 | #include <asm/irq.h> | ||
| 28 | #include <asm/arch/irda.h> | ||
| 29 | #include <asm/arch/mmc.h> | ||
| 30 | #include <asm/arch/udc.h> | ||
| 31 | |||
| 32 | #include <asm/mach/arch.h> | ||
| 33 | #include <asm/mach/map.h> | ||
| 34 | #include <asm/mach/irq.h> | ||
| 35 | |||
| 36 | #include <asm/arch/pxa-regs.h> | ||
| 37 | #include <asm/arch/irq.h> | ||
| 38 | #include <asm/arch/tosa.h> | ||
| 39 | |||
| 40 | #include <asm/hardware/scoop.h> | ||
| 41 | #include <asm/mach/sharpsl_param.h> | ||
| 42 | |||
| 43 | #include "generic.h" | ||
| 44 | |||
| 45 | |||
| 46 | /* | ||
| 47 | * SCOOP Device | ||
| 48 | */ | ||
| 49 | static struct resource tosa_scoop_resources[] = { | ||
| 50 | [0] = { | ||
| 51 | .start = TOSA_CF_PHYS, | ||
| 52 | .end = TOSA_CF_PHYS + 0xfff, | ||
| 53 | .flags = IORESOURCE_MEM, | ||
| 54 | }, | ||
| 55 | }; | ||
| 56 | |||
| 57 | static struct scoop_config tosa_scoop_setup = { | ||
| 58 | .io_dir = TOSA_SCOOP_IO_DIR, | ||
| 59 | .io_out = TOSA_SCOOP_IO_OUT, | ||
| 60 | |||
| 61 | }; | ||
| 62 | |||
| 63 | struct platform_device tosascoop_device = { | ||
| 64 | .name = "sharp-scoop", | ||
| 65 | .id = 0, | ||
| 66 | .dev = { | ||
| 67 | .platform_data = &tosa_scoop_setup, | ||
| 68 | }, | ||
| 69 | .num_resources = ARRAY_SIZE(tosa_scoop_resources), | ||
| 70 | .resource = tosa_scoop_resources, | ||
| 71 | }; | ||
| 72 | |||
| 73 | |||
| 74 | /* | ||
| 75 | * SCOOP Device Jacket | ||
| 76 | */ | ||
| 77 | static struct resource tosa_scoop_jc_resources[] = { | ||
| 78 | [0] = { | ||
| 79 | .start = TOSA_SCOOP_PHYS + 0x40, | ||
| 80 | .end = TOSA_SCOOP_PHYS + 0xfff, | ||
| 81 | .flags = IORESOURCE_MEM, | ||
| 82 | }, | ||
| 83 | }; | ||
| 84 | |||
| 85 | static struct scoop_config tosa_scoop_jc_setup = { | ||
| 86 | .io_dir = TOSA_SCOOP_JC_IO_DIR, | ||
| 87 | .io_out = TOSA_SCOOP_JC_IO_OUT, | ||
| 88 | }; | ||
| 89 | |||
| 90 | struct platform_device tosascoop_jc_device = { | ||
| 91 | .name = "sharp-scoop", | ||
| 92 | .id = 1, | ||
| 93 | .dev = { | ||
| 94 | .platform_data = &tosa_scoop_jc_setup, | ||
| 95 | .parent = &tosascoop_device.dev, | ||
| 96 | }, | ||
| 97 | .num_resources = ARRAY_SIZE(tosa_scoop_jc_resources), | ||
| 98 | .resource = tosa_scoop_jc_resources, | ||
| 99 | }; | ||
| 100 | |||
| 101 | /* | ||
| 102 | * PCMCIA | ||
| 103 | */ | ||
| 104 | static struct scoop_pcmcia_dev tosa_pcmcia_scoop[] = { | ||
| 105 | { | ||
| 106 | .dev = &tosascoop_device.dev, | ||
| 107 | .irq = TOSA_IRQ_GPIO_CF_IRQ, | ||
| 108 | .cd_irq = TOSA_IRQ_GPIO_CF_CD, | ||
| 109 | .cd_irq_str = "PCMCIA0 CD", | ||
| 110 | },{ | ||
| 111 | .dev = &tosascoop_jc_device.dev, | ||
| 112 | .irq = TOSA_IRQ_GPIO_JC_CF_IRQ, | ||
| 113 | .cd_irq = -1, | ||
| 114 | }, | ||
| 115 | }; | ||
| 116 | |||
| 117 | static void tosa_pcmcia_init(void) | ||
| 118 | { | ||
| 119 | /* Setup default state of GPIO outputs | ||
| 120 | before we enable them as outputs. */ | ||
| 121 | GPSR(GPIO48_nPOE) = GPIO_bit(GPIO48_nPOE) | | ||
| 122 | GPIO_bit(GPIO49_nPWE) | GPIO_bit(GPIO50_nPIOR) | | ||
| 123 | GPIO_bit(GPIO51_nPIOW) | GPIO_bit(GPIO52_nPCE_1) | | ||
| 124 | GPIO_bit(GPIO53_nPCE_2); | ||
| 125 | |||
| 126 | pxa_gpio_mode(GPIO48_nPOE_MD); | ||
| 127 | pxa_gpio_mode(GPIO49_nPWE_MD); | ||
| 128 | pxa_gpio_mode(GPIO50_nPIOR_MD); | ||
| 129 | pxa_gpio_mode(GPIO51_nPIOW_MD); | ||
| 130 | pxa_gpio_mode(GPIO55_nPREG_MD); | ||
| 131 | pxa_gpio_mode(GPIO56_nPWAIT_MD); | ||
| 132 | pxa_gpio_mode(GPIO57_nIOIS16_MD); | ||
| 133 | pxa_gpio_mode(GPIO52_nPCE_1_MD); | ||
| 134 | pxa_gpio_mode(GPIO53_nPCE_2_MD); | ||
| 135 | pxa_gpio_mode(GPIO54_pSKTSEL_MD); | ||
| 136 | } | ||
| 137 | |||
| 138 | static struct scoop_pcmcia_config tosa_pcmcia_config = { | ||
| 139 | .devs = &tosa_pcmcia_scoop[0], | ||
| 140 | .num_devs = 2, | ||
| 141 | .pcmcia_init = tosa_pcmcia_init, | ||
| 142 | }; | ||
| 143 | |||
| 144 | /* | ||
| 145 | * USB Device Controller | ||
| 146 | */ | ||
| 147 | static void tosa_udc_command(int cmd) | ||
| 148 | { | ||
| 149 | switch(cmd) { | ||
| 150 | case PXA2XX_UDC_CMD_CONNECT: | ||
| 151 | set_scoop_gpio(&tosascoop_jc_device.dev,TOSA_SCOOP_JC_USB_PULLUP); | ||
| 152 | break; | ||
| 153 | case PXA2XX_UDC_CMD_DISCONNECT: | ||
| 154 | reset_scoop_gpio(&tosascoop_jc_device.dev,TOSA_SCOOP_JC_USB_PULLUP); | ||
| 155 | break; | ||
| 156 | } | ||
| 157 | } | ||
| 158 | |||
| 159 | static int tosa_udc_is_connected(void) | ||
| 160 | { | ||
| 161 | return ((GPLR(TOSA_GPIO_USB_IN) & GPIO_bit(TOSA_GPIO_USB_IN)) == 0); | ||
| 162 | } | ||
| 163 | |||
| 164 | |||
| 165 | static struct pxa2xx_udc_mach_info udc_info __initdata = { | ||
| 166 | .udc_command = tosa_udc_command, | ||
| 167 | .udc_is_connected = tosa_udc_is_connected, | ||
| 168 | }; | ||
| 169 | |||
| 170 | /* | ||
| 171 | * MMC/SD Device | ||
| 172 | */ | ||
| 173 | static struct pxamci_platform_data tosa_mci_platform_data; | ||
| 174 | |||
| 175 | static int tosa_mci_init(struct device *dev, irqreturn_t (*tosa_detect_int)(int, void *, struct pt_regs *), void *data) | ||
| 176 | { | ||
| 177 | int err; | ||
| 178 | |||
| 179 | /* setup GPIO for PXA25x MMC controller */ | ||
| 180 | pxa_gpio_mode(GPIO6_MMCCLK_MD); | ||
| 181 | pxa_gpio_mode(GPIO8_MMCCS0_MD); | ||
| 182 | pxa_gpio_mode(TOSA_GPIO_nSD_DETECT | GPIO_IN); | ||
| 183 | |||
| 184 | tosa_mci_platform_data.detect_delay = msecs_to_jiffies(250); | ||
| 185 | |||
| 186 | err = request_irq(TOSA_IRQ_GPIO_nSD_DETECT, tosa_detect_int, SA_INTERRUPT, | ||
| 187 | "MMC/SD card detect", data); | ||
| 188 | if (err) { | ||
| 189 | printk(KERN_ERR "tosa_mci_init: MMC/SD: can't request MMC card detect IRQ\n"); | ||
| 190 | return -1; | ||
| 191 | } | ||
| 192 | |||
| 193 | set_irq_type(TOSA_IRQ_GPIO_nSD_DETECT, IRQT_BOTHEDGE); | ||
| 194 | |||
| 195 | return 0; | ||
| 196 | } | ||
| 197 | |||
| 198 | static void tosa_mci_setpower(struct device *dev, unsigned int vdd) | ||
| 199 | { | ||
| 200 | struct pxamci_platform_data* p_d = dev->platform_data; | ||
| 201 | |||
| 202 | if (( 1 << vdd) & p_d->ocr_mask) { | ||
| 203 | set_scoop_gpio(&tosascoop_device.dev,TOSA_SCOOP_PWR_ON); | ||
| 204 | } else { | ||
| 205 | reset_scoop_gpio(&tosascoop_device.dev,TOSA_SCOOP_PWR_ON); | ||
| 206 | } | ||
| 207 | } | ||
| 208 | |||
| 209 | static int tosa_mci_get_ro(struct device *dev) | ||
| 210 | { | ||
| 211 | return (read_scoop_reg(&tosascoop_device.dev, SCOOP_GPWR)&TOSA_SCOOP_SD_WP); | ||
| 212 | } | ||
| 213 | |||
| 214 | static void tosa_mci_exit(struct device *dev, void *data) | ||
| 215 | { | ||
| 216 | free_irq(TOSA_IRQ_GPIO_nSD_DETECT, data); | ||
| 217 | } | ||
| 218 | |||
| 219 | static struct pxamci_platform_data tosa_mci_platform_data = { | ||
| 220 | .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, | ||
| 221 | .init = tosa_mci_init, | ||
| 222 | .get_ro = tosa_mci_get_ro, | ||
| 223 | .setpower = tosa_mci_setpower, | ||
| 224 | .exit = tosa_mci_exit, | ||
| 225 | }; | ||
| 226 | |||
| 227 | /* | ||
| 228 | * Irda | ||
| 229 | */ | ||
| 230 | static void tosa_irda_transceiver_mode(struct device *dev, int mode) | ||
| 231 | { | ||
| 232 | if (mode & IR_OFF) { | ||
| 233 | reset_scoop_gpio(&tosascoop_device.dev,TOSA_SCOOP_IR_POWERDWN); | ||
| 234 | pxa_gpio_mode(GPIO47_STTXD|GPIO_DFLT_LOW); | ||
| 235 | pxa_gpio_mode(GPIO47_STTXD|GPIO_OUT); | ||
| 236 | } else { | ||
| 237 | pxa_gpio_mode(GPIO47_STTXD_MD); | ||
| 238 | set_scoop_gpio(&tosascoop_device.dev,TOSA_SCOOP_IR_POWERDWN); | ||
| 239 | } | ||
| 240 | } | ||
| 241 | |||
| 242 | static struct pxaficp_platform_data tosa_ficp_platform_data = { | ||
| 243 | .transceiver_cap = IR_SIRMODE | IR_OFF, | ||
| 244 | .transceiver_mode = tosa_irda_transceiver_mode, | ||
| 245 | }; | ||
| 246 | |||
| 247 | /* | ||
| 248 | * Tosa Keyboard | ||
| 249 | */ | ||
| 250 | static struct platform_device tosakbd_device = { | ||
| 251 | .name = "tosa-keyboard", | ||
| 252 | .id = -1, | ||
| 253 | }; | ||
| 254 | |||
| 255 | static struct platform_device *devices[] __initdata = { | ||
| 256 | &tosascoop_device, | ||
| 257 | &tosascoop_jc_device, | ||
| 258 | &tosakbd_device, | ||
| 259 | }; | ||
| 260 | |||
| 261 | static void __init tosa_init(void) | ||
| 262 | { | ||
| 263 | pxa_gpio_mode(TOSA_GPIO_ON_RESET | GPIO_IN); | ||
| 264 | pxa_gpio_mode(TOSA_GPIO_TC6393_INT | GPIO_IN); | ||
| 265 | pxa_gpio_mode(TOSA_GPIO_USB_IN | GPIO_IN); | ||
| 266 | |||
| 267 | /* setup sleep mode values */ | ||
| 268 | PWER = 0x00000002; | ||
| 269 | PFER = 0x00000000; | ||
| 270 | PRER = 0x00000002; | ||
| 271 | PGSR0 = 0x00000000; | ||
| 272 | PGSR1 = 0x00FF0002; | ||
| 273 | PGSR2 = 0x00014000; | ||
| 274 | PCFR |= PCFR_OPDE; | ||
| 275 | |||
| 276 | /* enable batt_fault */ | ||
| 277 | PMCR = 0x01; | ||
| 278 | |||
| 279 | pxa_set_mci_info(&tosa_mci_platform_data); | ||
| 280 | pxa_set_udc_info(&udc_info); | ||
| 281 | pxa_set_ficp_info(&tosa_ficp_platform_data); | ||
| 282 | platform_scoop_config = &tosa_pcmcia_config; | ||
| 283 | |||
| 284 | platform_add_devices(devices, ARRAY_SIZE(devices)); | ||
| 285 | } | ||
| 286 | |||
| 287 | static void __init fixup_tosa(struct machine_desc *desc, | ||
| 288 | struct tag *tags, char **cmdline, struct meminfo *mi) | ||
| 289 | { | ||
| 290 | sharpsl_save_param(); | ||
| 291 | mi->nr_banks=1; | ||
| 292 | mi->bank[0].start = 0xa0000000; | ||
| 293 | mi->bank[0].node = 0; | ||
| 294 | mi->bank[0].size = (64*1024*1024); | ||
| 295 | } | ||
| 296 | |||
| 297 | MACHINE_START(TOSA, "SHARP Tosa") | ||
| 298 | .phys_ram = 0xa0000000, | ||
| 299 | .phys_io = 0x40000000, | ||
| 300 | .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, | ||
| 301 | .fixup = fixup_tosa, | ||
| 302 | .map_io = pxa_map_io, | ||
| 303 | .init_irq = pxa_init_irq, | ||
| 304 | .init_machine = tosa_init, | ||
| 305 | .timer = &pxa_timer, | ||
| 306 | MACHINE_END | ||
diff --git a/arch/arm/mach-realview/Kconfig b/arch/arm/mach-realview/Kconfig index 4b63dc9eabfe..129976866d47 100644 --- a/arch/arm/mach-realview/Kconfig +++ b/arch/arm/mach-realview/Kconfig | |||
| @@ -8,4 +8,13 @@ config MACH_REALVIEW_EB | |||
| 8 | help | 8 | help |
| 9 | Include support for the ARM(R) RealView Emulation Baseboard platform. | 9 | Include support for the ARM(R) RealView Emulation Baseboard platform. |
| 10 | 10 | ||
| 11 | config REALVIEW_MPCORE | ||
| 12 | bool "Support MPcore tile" | ||
| 13 | depends on MACH_REALVIEW_EB | ||
| 14 | help | ||
| 15 | Enable support for the MPCore tile on the Realview platform. | ||
| 16 | Since there are device address and interrupt differences, a | ||
| 17 | kernel built with this option enabled is not compatible with | ||
| 18 | other tiles. | ||
| 19 | |||
| 11 | endmenu | 20 | endmenu |
diff --git a/arch/arm/mach-realview/Makefile b/arch/arm/mach-realview/Makefile index 8d37ea1605fd..36e76ba937fc 100644 --- a/arch/arm/mach-realview/Makefile +++ b/arch/arm/mach-realview/Makefile | |||
| @@ -4,3 +4,6 @@ | |||
| 4 | 4 | ||
| 5 | obj-y := core.o clock.o | 5 | obj-y := core.o clock.o |
| 6 | obj-$(CONFIG_MACH_REALVIEW_EB) += realview_eb.o | 6 | obj-$(CONFIG_MACH_REALVIEW_EB) += realview_eb.o |
| 7 | obj-$(CONFIG_SMP) += platsmp.o headsmp.o | ||
| 8 | obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o | ||
| 9 | obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o | ||
diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c index 482eb512ebe8..e2c6fa23d3cd 100644 --- a/arch/arm/mach-realview/core.c +++ b/arch/arm/mach-realview/core.c | |||
| @@ -550,6 +550,11 @@ static irqreturn_t realview_timer_interrupt(int irq, void *dev_id, struct pt_reg | |||
| 550 | 550 | ||
| 551 | timer_tick(regs); | 551 | timer_tick(regs); |
| 552 | 552 | ||
| 553 | #if defined(CONFIG_SMP) && !defined(CONFIG_LOCAL_TIMERS) | ||
| 554 | smp_send_timer(); | ||
| 555 | update_process_times(user_mode(regs)); | ||
| 556 | #endif | ||
| 557 | |||
| 553 | write_sequnlock(&xtime_lock); | 558 | write_sequnlock(&xtime_lock); |
| 554 | 559 | ||
| 555 | return IRQ_HANDLED; | 560 | return IRQ_HANDLED; |
diff --git a/arch/arm/mach-realview/core.h b/arch/arm/mach-realview/core.h index 575599db74db..d83e8bad2038 100644 --- a/arch/arm/mach-realview/core.h +++ b/arch/arm/mach-realview/core.h | |||
| @@ -23,6 +23,7 @@ | |||
| 23 | #define __ASM_ARCH_REALVIEW_H | 23 | #define __ASM_ARCH_REALVIEW_H |
| 24 | 24 | ||
| 25 | #include <asm/hardware/amba.h> | 25 | #include <asm/hardware/amba.h> |
| 26 | #include <asm/leds.h> | ||
| 26 | #include <asm/io.h> | 27 | #include <asm/io.h> |
| 27 | 28 | ||
| 28 | #define __io_address(n) __io(IO_ADDRESS(n)) | 29 | #define __io_address(n) __io(IO_ADDRESS(n)) |
diff --git a/arch/arm/mach-realview/headsmp.S b/arch/arm/mach-realview/headsmp.S new file mode 100644 index 000000000000..4075473cf68a --- /dev/null +++ b/arch/arm/mach-realview/headsmp.S | |||
| @@ -0,0 +1,39 @@ | |||
| 1 | /* | ||
| 2 | * linux/arch/arm/mach-realview/headsmp.S | ||
| 3 | * | ||
| 4 | * Copyright (c) 2003 ARM Limited | ||
| 5 | * All Rights Reserved | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or modify | ||
| 8 | * it under the terms of the GNU General Public License version 2 as | ||
| 9 | * published by the Free Software Foundation. | ||
| 10 | */ | ||
| 11 | #include <linux/linkage.h> | ||
| 12 | #include <linux/init.h> | ||
| 13 | |||
| 14 | __INIT | ||
| 15 | |||
| 16 | /* | ||
| 17 | * Realview specific entry point for secondary CPUs. This provides | ||
| 18 | * a "holding pen" into which all secondary cores are held until we're | ||
| 19 | * ready for them to initialise. | ||
| 20 | */ | ||
| 21 | ENTRY(realview_secondary_startup) | ||
| 22 | mrc p15, 0, r0, c0, c0, 5 | ||
| 23 | and r0, r0, #15 | ||
| 24 | adr r4, 1f | ||
| 25 | ldmia r4, {r5, r6} | ||
| 26 | sub r4, r4, r5 | ||
| 27 | add r6, r6, r4 | ||
| 28 | pen: ldr r7, [r6] | ||
| 29 | cmp r7, r0 | ||
| 30 | bne pen | ||
| 31 | |||
| 32 | /* | ||
| 33 | * we've been released from the holding pen: secondary_stack | ||
| 34 | * should now contain the SVC stack for this core | ||
| 35 | */ | ||
| 36 | b secondary_startup | ||
| 37 | |||
| 38 | 1: .long . | ||
| 39 | .long pen_release | ||
diff --git a/arch/arm/mach-realview/hotplug.c b/arch/arm/mach-realview/hotplug.c new file mode 100644 index 000000000000..09748cbcd10e --- /dev/null +++ b/arch/arm/mach-realview/hotplug.c | |||
| @@ -0,0 +1,138 @@ | |||
| 1 | /* | ||
| 2 | * linux/arch/arm/mach-realview/hotplug.c | ||
| 3 | * | ||
| 4 | * Copyright (C) 2002 ARM Ltd. | ||
| 5 | * All Rights Reserved | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or modify | ||
| 8 | * it under the terms of the GNU General Public License version 2 as | ||
| 9 | * published by the Free Software Foundation. | ||
| 10 | */ | ||
| 11 | #include <linux/kernel.h> | ||
| 12 | #include <linux/errno.h> | ||
| 13 | #include <linux/smp.h> | ||
| 14 | #include <linux/completion.h> | ||
| 15 | |||
| 16 | extern volatile int pen_release; | ||
| 17 | |||
| 18 | static DECLARE_COMPLETION(cpu_killed); | ||
| 19 | |||
| 20 | static inline void cpu_enter_lowpower(void) | ||
| 21 | { | ||
| 22 | unsigned int v; | ||
| 23 | |||
| 24 | asm volatile( "mcr p15, 0, %1, c7, c14, 0\n" | ||
| 25 | " mcr p15, 0, %1, c7, c5, 0\n" | ||
| 26 | " mcr p15, 0, %1, c7, c10, 4\n" | ||
| 27 | /* | ||
| 28 | * Turn off coherency | ||
| 29 | */ | ||
| 30 | " mrc p15, 0, %0, c1, c0, 1\n" | ||
| 31 | " bic %0, %0, #0x20\n" | ||
| 32 | " mcr p15, 0, %0, c1, c0, 1\n" | ||
| 33 | " mrc p15, 0, %0, c1, c0, 0\n" | ||
| 34 | " bic %0, %0, #0x04\n" | ||
| 35 | " mcr p15, 0, %0, c1, c0, 0\n" | ||
| 36 | : "=&r" (v) | ||
| 37 | : "r" (0) | ||
| 38 | : "cc"); | ||
| 39 | } | ||
| 40 | |||
| 41 | static inline void cpu_leave_lowpower(void) | ||
| 42 | { | ||
| 43 | unsigned int v; | ||
| 44 | |||
| 45 | asm volatile( "mrc p15, 0, %0, c1, c0, 0\n" | ||
| 46 | " orr %0, %0, #0x04\n" | ||
| 47 | " mcr p15, 0, %0, c1, c0, 0\n" | ||
| 48 | " mrc p15, 0, %0, c1, c0, 1\n" | ||
| 49 | " orr %0, %0, #0x20\n" | ||
| 50 | " mcr p15, 0, %0, c1, c0, 1\n" | ||
| 51 | : "=&r" (v) | ||
| 52 | : | ||
| 53 | : "cc"); | ||
| 54 | } | ||
| 55 | |||
| 56 | static inline void platform_do_lowpower(unsigned int cpu) | ||
| 57 | { | ||
| 58 | /* | ||
| 59 | * there is no power-control hardware on this platform, so all | ||
| 60 | * we can do is put the core into WFI; this is safe as the calling | ||
| 61 | * code will have already disabled interrupts | ||
| 62 | */ | ||
| 63 | for (;;) { | ||
| 64 | /* | ||
| 65 | * here's the WFI | ||
| 66 | */ | ||
| 67 | asm(".word 0xe320f003\n" | ||
| 68 | : | ||
| 69 | : | ||
| 70 | : "memory", "cc"); | ||
| 71 | |||
| 72 | if (pen_release == cpu) { | ||
| 73 | /* | ||
| 74 | * OK, proper wakeup, we're done | ||
| 75 | */ | ||
| 76 | break; | ||
| 77 | } | ||
| 78 | |||
| 79 | /* | ||
| 80 | * getting here, means that we have come out of WFI without | ||
| 81 | * having been woken up - this shouldn't happen | ||
| 82 | * | ||
| 83 | * The trouble is, letting people know about this is not really | ||
| 84 | * possible, since we are currently running incoherently, and | ||
| 85 | * therefore cannot safely call printk() or anything else | ||
| 86 | */ | ||
| 87 | #ifdef DEBUG | ||
| 88 | printk("CPU%u: spurious wakeup call\n", cpu); | ||
| 89 | #endif | ||
| 90 | } | ||
| 91 | } | ||
| 92 | |||
| 93 | int platform_cpu_kill(unsigned int cpu) | ||
| 94 | { | ||
| 95 | return wait_for_completion_timeout(&cpu_killed, 5000); | ||
| 96 | } | ||
| 97 | |||
| 98 | /* | ||
| 99 | * platform-specific code to shutdown a CPU | ||
| 100 | * | ||
| 101 | * Called with IRQs disabled | ||
| 102 | */ | ||
| 103 | void platform_cpu_die(unsigned int cpu) | ||
| 104 | { | ||
| 105 | #ifdef DEBUG | ||
| 106 | unsigned int this_cpu = hard_smp_processor_id(); | ||
| 107 | |||
| 108 | if (cpu != this_cpu) { | ||
| 109 | printk(KERN_CRIT "Eek! platform_cpu_die running on %u, should be %u\n", | ||
| 110 | this_cpu, cpu); | ||
| 111 | BUG(); | ||
| 112 | } | ||
| 113 | #endif | ||
| 114 | |||
| 115 | printk(KERN_NOTICE "CPU%u: shutdown\n", cpu); | ||
| 116 | complete(&cpu_killed); | ||
| 117 | |||
| 118 | /* | ||
| 119 | * we're ready for shutdown now, so do it | ||
| 120 | */ | ||
| 121 | cpu_enter_lowpower(); | ||
| 122 | platform_do_lowpower(cpu); | ||
| 123 | |||
| 124 | /* | ||
| 125 | * bring this CPU back into the world of cache | ||
| 126 | * coherency, and then restore interrupts | ||
| 127 | */ | ||
| 128 | cpu_leave_lowpower(); | ||
| 129 | } | ||
| 130 | |||
| 131 | int mach_cpu_disable(unsigned int cpu) | ||
| 132 | { | ||
| 133 | /* | ||
| 134 | * we don't allow CPU 0 to be shutdown (it is still too special | ||
| 135 | * e.g. clock tick interrupts) | ||
| 136 | */ | ||
| 137 | return cpu == 0 ? -EPERM : 0; | ||
| 138 | } | ||
diff --git a/arch/arm/mach-realview/localtimer.c b/arch/arm/mach-realview/localtimer.c new file mode 100644 index 000000000000..5e917e37d095 --- /dev/null +++ b/arch/arm/mach-realview/localtimer.c | |||
| @@ -0,0 +1,130 @@ | |||
| 1 | /* | ||
| 2 | * linux/arch/arm/mach-realview/localtimer.c | ||
| 3 | * | ||
| 4 | * Copyright (C) 2002 ARM Ltd. | ||
| 5 | * All Rights Reserved | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or modify | ||
| 8 | * it under the terms of the GNU General Public License version 2 as | ||
| 9 | * published by the Free Software Foundation. | ||
| 10 | */ | ||
| 11 | #include <linux/init.h> | ||
| 12 | #include <linux/kernel.h> | ||
| 13 | #include <linux/delay.h> | ||
| 14 | #include <linux/device.h> | ||
| 15 | #include <linux/smp.h> | ||
| 16 | |||
| 17 | #include <asm/mach/time.h> | ||
| 18 | #include <asm/hardware/arm_twd.h> | ||
| 19 | #include <asm/hardware/gic.h> | ||
| 20 | #include <asm/hardware.h> | ||
| 21 | #include <asm/io.h> | ||
| 22 | #include <asm/irq.h> | ||
| 23 | |||
| 24 | #include "core.h" | ||
| 25 | |||
| 26 | #define TWD_BASE(cpu) (__io_address(REALVIEW_TWD_BASE) + \ | ||
| 27 | ((cpu) * REALVIEW_TWD_SIZE)) | ||
| 28 | |||
| 29 | static unsigned long mpcore_timer_rate; | ||
| 30 | |||
| 31 | /* | ||
| 32 | * local_timer_ack: checks for a local timer interrupt. | ||
| 33 | * | ||
| 34 | * If a local timer interrupt has occured, acknowledge and return 1. | ||
| 35 | * Otherwise, return 0. | ||
| 36 | */ | ||
| 37 | int local_timer_ack(void) | ||
| 38 | { | ||
| 39 | void __iomem *base = TWD_BASE(smp_processor_id()); | ||
| 40 | |||
| 41 | if (__raw_readl(base + TWD_TIMER_INTSTAT)) { | ||
| 42 | __raw_writel(1, base + TWD_TIMER_INTSTAT); | ||
| 43 | return 1; | ||
| 44 | } | ||
| 45 | |||
| 46 | return 0; | ||
| 47 | } | ||
| 48 | |||
| 49 | void __cpuinit local_timer_setup(unsigned int cpu) | ||
| 50 | { | ||
| 51 | void __iomem *base = TWD_BASE(cpu); | ||
| 52 | unsigned int load, offset; | ||
| 53 | u64 waitjiffies; | ||
| 54 | unsigned int count; | ||
| 55 | |||
| 56 | /* | ||
| 57 | * If this is the first time round, we need to work out how fast | ||
| 58 | * the timer ticks | ||
| 59 | */ | ||
| 60 | if (mpcore_timer_rate == 0) { | ||
| 61 | printk("Calibrating local timer... "); | ||
| 62 | |||
| 63 | /* Wait for a tick to start */ | ||
| 64 | waitjiffies = get_jiffies_64() + 1; | ||
| 65 | |||
| 66 | while (get_jiffies_64() < waitjiffies) | ||
| 67 | udelay(10); | ||
| 68 | |||
| 69 | /* OK, now the tick has started, let's get the timer going */ | ||
| 70 | waitjiffies += 5; | ||
| 71 | |||
| 72 | /* enable, no interrupt or reload */ | ||
| 73 | __raw_writel(0x1, base + TWD_TIMER_CONTROL); | ||
| 74 | |||
| 75 | /* maximum value */ | ||
| 76 | __raw_writel(0xFFFFFFFFU, base + TWD_TIMER_COUNTER); | ||
| 77 | |||
| 78 | while (get_jiffies_64() < waitjiffies) | ||
| 79 | udelay(10); | ||
| 80 | |||
| 81 | count = __raw_readl(base + TWD_TIMER_COUNTER); | ||
| 82 | |||
| 83 | mpcore_timer_rate = (0xFFFFFFFFU - count) * (HZ / 5); | ||
| 84 | |||
| 85 | printk("%lu.%02luMHz.\n", mpcore_timer_rate / 1000000, | ||
| 86 | (mpcore_timer_rate / 100000) % 100); | ||
| 87 | } | ||
| 88 | |||
| 89 | load = mpcore_timer_rate / HZ; | ||
| 90 | |||
| 91 | __raw_writel(load, base + TWD_TIMER_LOAD); | ||
| 92 | __raw_writel(0x7, base + TWD_TIMER_CONTROL); | ||
| 93 | |||
| 94 | /* | ||
| 95 | * Now maneuver our local tick into the right part of the jiffy. | ||
| 96 | * Start by working out where within the tick our local timer | ||
| 97 | * interrupt should go. | ||
| 98 | */ | ||
| 99 | offset = ((mpcore_timer_rate / HZ) / (NR_CPUS + 1)) * (cpu + 1); | ||
| 100 | |||
| 101 | /* | ||
| 102 | * gettimeoffset() will return a number of us since the last tick. | ||
| 103 | * Convert this number of us to a local timer tick count. | ||
| 104 | * Be careful of integer overflow whilst keeping maximum precision. | ||
| 105 | * | ||
| 106 | * with HZ=100 and 1MHz (fpga) ~ 1GHz processor: | ||
| 107 | * load = 1 ~ 10,000 | ||
| 108 | * mpcore_timer_rate/10000 = 100 ~ 100,000 | ||
| 109 | * | ||
| 110 | * so the multiply value will be less than 10^9 always. | ||
| 111 | */ | ||
| 112 | load = (system_timer->offset() * (mpcore_timer_rate / 10000)) / 100; | ||
| 113 | |||
| 114 | /* Add on our offset to get the load value */ | ||
| 115 | load = (load + offset) % (mpcore_timer_rate / HZ); | ||
| 116 | |||
| 117 | __raw_writel(load, base + TWD_TIMER_COUNTER); | ||
| 118 | |||
| 119 | /* Make sure our local interrupt controller has this enabled */ | ||
| 120 | __raw_writel(1 << IRQ_LOCALTIMER, | ||
| 121 | __io_address(REALVIEW_GIC_DIST_BASE) + GIC_DIST_ENABLE_SET); | ||
| 122 | } | ||
| 123 | |||
| 124 | /* | ||
| 125 | * take a local timer down | ||
| 126 | */ | ||
| 127 | void __cpuexit local_timer_stop(unsigned int cpu) | ||
| 128 | { | ||
| 129 | __raw_writel(0, TWD_BASE(cpu) + TWD_TIMER_CONTROL); | ||
| 130 | } | ||
diff --git a/arch/arm/mach-realview/platsmp.c b/arch/arm/mach-realview/platsmp.c new file mode 100644 index 000000000000..0c7d4ac9a7b3 --- /dev/null +++ b/arch/arm/mach-realview/platsmp.c | |||
| @@ -0,0 +1,200 @@ | |||
| 1 | /* | ||
| 2 | * linux/arch/arm/mach-realview/platsmp.c | ||
| 3 | * | ||
| 4 | * Copyright (C) 2002 ARM Ltd. | ||
| 5 | * All Rights Reserved | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or modify | ||
| 8 | * it under the terms of the GNU General Public License version 2 as | ||
| 9 | * published by the Free Software Foundation. | ||
| 10 | */ | ||
| 11 | #include <linux/init.h> | ||
| 12 | #include <linux/errno.h> | ||
| 13 | #include <linux/delay.h> | ||
| 14 | #include <linux/device.h> | ||
| 15 | #include <linux/smp.h> | ||
| 16 | |||
| 17 | #include <asm/cacheflush.h> | ||
| 18 | #include <asm/hardware/arm_scu.h> | ||
| 19 | #include <asm/hardware.h> | ||
| 20 | |||
| 21 | #include "core.h" | ||
| 22 | |||
| 23 | extern void realview_secondary_startup(void); | ||
| 24 | |||
| 25 | /* | ||
| 26 | * control for which core is the next to come out of the secondary | ||
| 27 | * boot "holding pen" | ||
| 28 | */ | ||
| 29 | volatile int __cpuinitdata pen_release = -1; | ||
| 30 | |||
| 31 | static unsigned int __init get_core_count(void) | ||
| 32 | { | ||
| 33 | unsigned int ncores; | ||
| 34 | |||
| 35 | ncores = __raw_readl(__io_address(REALVIEW_MPCORE_SCU_BASE) + SCU_CONFIG); | ||
| 36 | |||
| 37 | return (ncores & 0x03) + 1; | ||
| 38 | } | ||
| 39 | |||
| 40 | static DEFINE_SPINLOCK(boot_lock); | ||
| 41 | |||
| 42 | void __cpuinit platform_secondary_init(unsigned int cpu) | ||
| 43 | { | ||
| 44 | /* | ||
| 45 | * the primary core may have used a "cross call" soft interrupt | ||
| 46 | * to get this processor out of WFI in the BootMonitor - make | ||
| 47 | * sure that we are no longer being sent this soft interrupt | ||
| 48 | */ | ||
| 49 | smp_cross_call_done(cpumask_of_cpu(cpu)); | ||
| 50 | |||
| 51 | /* | ||
| 52 | * if any interrupts are already enabled for the primary | ||
| 53 | * core (e.g. timer irq), then they will not have been enabled | ||
| 54 | * for us: do so | ||
| 55 | */ | ||
| 56 | gic_cpu_init(__io_address(REALVIEW_GIC_CPU_BASE)); | ||
| 57 | |||
| 58 | /* | ||
| 59 | * let the primary processor know we're out of the | ||
| 60 | * pen, then head off into the C entry point | ||
| 61 | */ | ||
| 62 | pen_release = -1; | ||
| 63 | |||
| 64 | /* | ||
| 65 | * Synchronise with the boot thread. | ||
| 66 | */ | ||
| 67 | spin_lock(&boot_lock); | ||
| 68 | spin_unlock(&boot_lock); | ||
| 69 | } | ||
| 70 | |||
| 71 | int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) | ||
| 72 | { | ||
| 73 | unsigned long timeout; | ||
| 74 | |||
| 75 | /* | ||
| 76 | * set synchronisation state between this boot processor | ||
| 77 | * and the secondary one | ||
| 78 | */ | ||
| 79 | spin_lock(&boot_lock); | ||
| 80 | |||
| 81 | /* | ||
| 82 | * The secondary processor is waiting to be released from | ||
| 83 | * the holding pen - release it, then wait for it to flag | ||
| 84 | * that it has been released by resetting pen_release. | ||
| 85 | * | ||
| 86 | * Note that "pen_release" is the hardware CPU ID, whereas | ||
| 87 | * "cpu" is Linux's internal ID. | ||
| 88 | */ | ||
| 89 | pen_release = cpu; | ||
| 90 | flush_cache_all(); | ||
| 91 | |||
| 92 | /* | ||
| 93 | * XXX | ||
| 94 | * | ||
| 95 | * This is a later addition to the booting protocol: the | ||
| 96 | * bootMonitor now puts secondary cores into WFI, so | ||
| 97 | * poke_milo() no longer gets the cores moving; we need | ||
| 98 | * to send a soft interrupt to wake the secondary core. | ||
| 99 | * Use smp_cross_call() for this, since there's little | ||
| 100 | * point duplicating the code here | ||
| 101 | */ | ||
| 102 | smp_cross_call(cpumask_of_cpu(cpu)); | ||
| 103 | |||
| 104 | timeout = jiffies + (1 * HZ); | ||
| 105 | while (time_before(jiffies, timeout)) { | ||
| 106 | if (pen_release == -1) | ||
| 107 | break; | ||
| 108 | |||
| 109 | udelay(10); | ||
| 110 | } | ||
| 111 | |||
| 112 | /* | ||
| 113 | * now the secondary core is starting up let it run its | ||
| 114 | * calibrations, then wait for it to finish | ||
| 115 | */ | ||
| 116 | spin_unlock(&boot_lock); | ||
| 117 | |||
| 118 | return pen_release != -1 ? -ENOSYS : 0; | ||
| 119 | } | ||
| 120 | |||
| 121 | static void __init poke_milo(void) | ||
| 122 | { | ||
| 123 | extern void secondary_startup(void); | ||
| 124 | |||
| 125 | /* nobody is to be released from the pen yet */ | ||
| 126 | pen_release = -1; | ||
| 127 | |||
| 128 | /* | ||
| 129 | * write the address of secondary startup into the system-wide | ||
| 130 | * flags register, then clear the bottom two bits, which is what | ||
| 131 | * BootMonitor is waiting for | ||
| 132 | */ | ||
| 133 | #if 1 | ||
| 134 | #define REALVIEW_SYS_FLAGSS_OFFSET 0x30 | ||
| 135 | __raw_writel(virt_to_phys(realview_secondary_startup), | ||
| 136 | __io_address(REALVIEW_SYS_BASE) + | ||
| 137 | REALVIEW_SYS_FLAGSS_OFFSET); | ||
| 138 | #define REALVIEW_SYS_FLAGSC_OFFSET 0x34 | ||
| 139 | __raw_writel(3, | ||
| 140 | __io_address(REALVIEW_SYS_BASE) + | ||
| 141 | REALVIEW_SYS_FLAGSC_OFFSET); | ||
| 142 | #endif | ||
| 143 | |||
| 144 | mb(); | ||
| 145 | } | ||
| 146 | |||
| 147 | void __init smp_prepare_cpus(unsigned int max_cpus) | ||
| 148 | { | ||
| 149 | unsigned int ncores = get_core_count(); | ||
| 150 | unsigned int cpu = smp_processor_id(); | ||
| 151 | int i; | ||
| 152 | |||
| 153 | /* sanity check */ | ||
| 154 | if (ncores == 0) { | ||
| 155 | printk(KERN_ERR | ||
| 156 | "Realview: strange CM count of 0? Default to 1\n"); | ||
| 157 | |||
| 158 | ncores = 1; | ||
| 159 | } | ||
| 160 | |||
| 161 | if (ncores > NR_CPUS) { | ||
| 162 | printk(KERN_WARNING | ||
| 163 | "Realview: no. of cores (%d) greater than configured " | ||
| 164 | "maximum of %d - clipping\n", | ||
| 165 | ncores, NR_CPUS); | ||
| 166 | ncores = NR_CPUS; | ||
| 167 | } | ||
| 168 | |||
| 169 | smp_store_cpu_info(cpu); | ||
| 170 | |||
| 171 | /* | ||
| 172 | * are we trying to boot more cores than exist? | ||
| 173 | */ | ||
| 174 | if (max_cpus > ncores) | ||
| 175 | max_cpus = ncores; | ||
| 176 | |||
| 177 | /* | ||
| 178 | * Enable the local timer for primary CPU | ||
| 179 | */ | ||
| 180 | local_timer_setup(cpu); | ||
| 181 | |||
| 182 | /* | ||
| 183 | * Initialise the possible/present maps. | ||
| 184 | * cpu_possible_map describes the set of CPUs which may be present | ||
| 185 | * cpu_present_map describes the set of CPUs populated | ||
| 186 | */ | ||
| 187 | for (i = 0; i < max_cpus; i++) { | ||
| 188 | cpu_set(i, cpu_possible_map); | ||
| 189 | cpu_set(i, cpu_present_map); | ||
| 190 | } | ||
| 191 | |||
| 192 | /* | ||
| 193 | * Do we need any more CPUs? If so, then let them know where | ||
| 194 | * to start. Note that, on modern versions of MILO, the "poke" | ||
| 195 | * doesn't actually do anything until each individual core is | ||
| 196 | * sent a soft interrupt to get it out of WFI | ||
| 197 | */ | ||
| 198 | if (max_cpus > 1) | ||
| 199 | poke_milo(); | ||
| 200 | } | ||
diff --git a/arch/arm/mach-realview/realview_eb.c b/arch/arm/mach-realview/realview_eb.c index 267bb07e39b7..7dc32503fdf2 100644 --- a/arch/arm/mach-realview/realview_eb.c +++ b/arch/arm/mach-realview/realview_eb.c | |||
| @@ -136,6 +136,11 @@ static struct amba_device *amba_devs[] __initdata = { | |||
| 136 | 136 | ||
| 137 | static void __init gic_init_irq(void) | 137 | static void __init gic_init_irq(void) |
| 138 | { | 138 | { |
| 139 | #ifdef CONFIG_REALVIEW_MPCORE | ||
| 140 | writel(0x0000a05f, __io_address(REALVIEW_SYS_LOCK)); | ||
| 141 | writel(0x008003c0, __io_address(REALVIEW_SYS_BASE) + 0xd8); | ||
| 142 | writel(0x00000000, __io_address(REALVIEW_SYS_LOCK)); | ||
| 143 | #endif | ||
| 139 | gic_dist_init(__io_address(REALVIEW_GIC_DIST_BASE)); | 144 | gic_dist_init(__io_address(REALVIEW_GIC_DIST_BASE)); |
| 140 | gic_cpu_init(__io_address(REALVIEW_GIC_CPU_BASE)); | 145 | gic_cpu_init(__io_address(REALVIEW_GIC_CPU_BASE)); |
| 141 | } | 146 | } |
diff --git a/arch/arm/mach-s3c2410/Kconfig b/arch/arm/mach-s3c2410/Kconfig index c796bcdd6158..0b9d7ca49ec1 100644 --- a/arch/arm/mach-s3c2410/Kconfig +++ b/arch/arm/mach-s3c2410/Kconfig | |||
| @@ -121,6 +121,14 @@ config S3C2410_BOOT_WATCHDOG | |||
| 121 | system resets depends on the value of PCLK. The timeout on an | 121 | system resets depends on the value of PCLK. The timeout on an |
| 122 | 200MHz s3c2410 should be about 30 seconds. | 122 | 200MHz s3c2410 should be about 30 seconds. |
| 123 | 123 | ||
| 124 | config S3C2410_BOOT_ERROR_RESET | ||
| 125 | bool "S3C2410 Reboot on decompression error" | ||
| 126 | depends on ARCH_S3C2410 | ||
| 127 | help | ||
| 128 | Say y here to use the watchdog to reset the system if the | ||
| 129 | kernel decompressor detects an error during decompression. | ||
| 130 | |||
| 131 | |||
| 124 | comment "S3C2410 Setup" | 132 | comment "S3C2410 Setup" |
| 125 | 133 | ||
| 126 | config S3C2410_DMA | 134 | config S3C2410_DMA |
diff --git a/arch/arm/mach-s3c2410/mach-anubis.c b/arch/arm/mach-s3c2410/mach-anubis.c index 8390b685c2b6..0f81fc0c2f7f 100644 --- a/arch/arm/mach-s3c2410/mach-anubis.c +++ b/arch/arm/mach-s3c2410/mach-anubis.c | |||
| @@ -56,8 +56,16 @@ | |||
| 56 | static struct map_desc anubis_iodesc[] __initdata = { | 56 | static struct map_desc anubis_iodesc[] __initdata = { |
| 57 | /* ISA IO areas */ | 57 | /* ISA IO areas */ |
| 58 | 58 | ||
| 59 | { (u32)S3C24XX_VA_ISA_BYTE, 0x0, SZ_16M, MT_DEVICE }, | 59 | { |
| 60 | { (u32)S3C24XX_VA_ISA_WORD, 0x0, SZ_16M, MT_DEVICE }, | 60 | .virtual = (u32)S3C24XX_VA_ISA_BYTE, |
| 61 | .pfn = __phys_to_pfn(0x0), | ||
| 62 | .length = SZ_4M, | ||
| 63 | .type = MT_DEVICE | ||
| 64 | }, { | ||
| 65 | .virtual = (u32)S3C24XX_VA_ISA_WORD, | ||
| 66 | .pfn = __phys_to_pfn(0x0), | ||
| 67 | .length = SZ_4M, MT_DEVICE | ||
| 68 | }, | ||
| 61 | 69 | ||
| 62 | /* we could possibly compress the next set down into a set of smaller tables | 70 | /* we could possibly compress the next set down into a set of smaller tables |
| 63 | * pagetables, but that would mean using an L2 section, and it still means | 71 | * pagetables, but that would mean using an L2 section, and it still means |
| @@ -66,16 +74,41 @@ static struct map_desc anubis_iodesc[] __initdata = { | |||
| 66 | 74 | ||
| 67 | /* CPLD control registers */ | 75 | /* CPLD control registers */ |
| 68 | 76 | ||
| 69 | { (u32)ANUBIS_VA_CTRL1, ANUBIS_PA_CTRL1, SZ_4K, MT_DEVICE }, | 77 | { |
| 70 | { (u32)ANUBIS_VA_CTRL2, ANUBIS_PA_CTRL2, SZ_4K, MT_DEVICE }, | 78 | .virtual = (u32)ANUBIS_VA_CTRL1, |
| 79 | .pfn = __phys_to_pfn(ANUBIS_PA_CTRL1), | ||
| 80 | .length = SZ_4K, | ||
| 81 | .type = MT_DEVICE | ||
| 82 | }, { | ||
| 83 | .virtual = (u32)ANUBIS_VA_CTRL2, | ||
| 84 | .pfn = __phys_to_pfn(ANUBIS_PA_CTRL2), | ||
| 85 | .length = SZ_4K, | ||
| 86 | .type =MT_DEVICE | ||
| 87 | }, | ||
| 71 | 88 | ||
| 72 | /* IDE drives */ | 89 | /* IDE drives */ |
| 73 | 90 | ||
| 74 | { (u32)ANUBIS_IDEPRI, S3C2410_CS3, SZ_1M, MT_DEVICE }, | 91 | { |
| 75 | { (u32)ANUBIS_IDEPRIAUX, S3C2410_CS3+(1<<26), SZ_1M, MT_DEVICE }, | 92 | .virtual = (u32)ANUBIS_IDEPRI, |
| 76 | 93 | .pfn = __phys_to_pfn(S3C2410_CS3), | |
| 77 | { (u32)ANUBIS_IDESEC, S3C2410_CS4, SZ_1M, MT_DEVICE }, | 94 | .length = SZ_1M, |
| 78 | { (u32)ANUBIS_IDESECAUX, S3C2410_CS4+(1<<26), SZ_1M, MT_DEVICE }, | 95 | .type = MT_DEVICE |
| 96 | }, { | ||
| 97 | .virtual = (u32)ANUBIS_IDEPRIAUX, | ||
| 98 | .pfn = __phys_to_pfn(S3C2410_CS3+(1<<26)), | ||
| 99 | .length = SZ_1M, | ||
| 100 | .type = MT_DEVICE | ||
| 101 | }, { | ||
| 102 | .virtual = (u32)ANUBIS_IDESEC, | ||
| 103 | .pfn = __phys_to_pfn(S3C2410_CS4), | ||
| 104 | .length = SZ_1M, | ||
| 105 | .type = MT_DEVICE | ||
| 106 | }, { | ||
| 107 | .virtual = (u32)ANUBIS_IDESECAUX, | ||
| 108 | .pfn = __phys_to_pfn(S3C2410_CS4+(1<<26)), | ||
| 109 | .length = SZ_1M, | ||
| 110 | .type = MT_DEVICE | ||
| 111 | }, | ||
| 79 | }; | 112 | }; |
| 80 | 113 | ||
| 81 | #define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK | 114 | #define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK |
diff --git a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c index 0b71c896bbd1..1be2567a7486 100644 --- a/arch/arm/mach-s3c2410/mach-bast.c +++ b/arch/arm/mach-s3c2410/mach-bast.c | |||
| @@ -89,32 +89,63 @@ | |||
| 89 | 89 | ||
| 90 | /* macros to modify the physical addresses for io space */ | 90 | /* macros to modify the physical addresses for io space */ |
| 91 | 91 | ||
| 92 | #define PA_CS2(item) ((item) + S3C2410_CS2) | 92 | #define PA_CS2(item) (__phys_to_pfn((item) + S3C2410_CS2)) |
| 93 | #define PA_CS3(item) ((item) + S3C2410_CS3) | 93 | #define PA_CS3(item) (__phys_to_pfn((item) + S3C2410_CS3)) |
| 94 | #define PA_CS4(item) ((item) + S3C2410_CS4) | 94 | #define PA_CS4(item) (__phys_to_pfn((item) + S3C2410_CS4)) |
| 95 | #define PA_CS5(item) ((item) + S3C2410_CS5) | 95 | #define PA_CS5(item) (__phys_to_pfn((item) + S3C2410_CS5)) |
| 96 | 96 | ||
| 97 | static struct map_desc bast_iodesc[] __initdata = { | 97 | static struct map_desc bast_iodesc[] __initdata = { |
| 98 | /* ISA IO areas */ | 98 | /* ISA IO areas */ |
| 99 | 99 | { | |
| 100 | { (u32)S3C24XX_VA_ISA_BYTE, PA_CS2(BAST_PA_ISAIO), SZ_16M, MT_DEVICE }, | 100 | .virtual = (u32)S3C24XX_VA_ISA_BYTE, |
| 101 | { (u32)S3C24XX_VA_ISA_WORD, PA_CS3(BAST_PA_ISAIO), SZ_16M, MT_DEVICE }, | 101 | .pfn = PA_CS2(BAST_PA_ISAIO), |
| 102 | 102 | .length = SZ_16M, | |
| 103 | /* we could possibly compress the next set down into a set of smaller tables | 103 | .type = MT_DEVICE, |
| 104 | * pagetables, but that would mean using an L2 section, and it still means | 104 | }, { |
| 105 | * we cannot actually feed the same register to an LDR due to 16K spacing | 105 | .virtual = (u32)S3C24XX_VA_ISA_WORD, |
| 106 | */ | 106 | .pfn = PA_CS3(BAST_PA_ISAIO), |
| 107 | 107 | .length = SZ_16M, | |
| 108 | .type = MT_DEVICE, | ||
| 109 | }, | ||
| 108 | /* bast CPLD control registers, and external interrupt controls */ | 110 | /* bast CPLD control registers, and external interrupt controls */ |
| 109 | { (u32)BAST_VA_CTRL1, BAST_PA_CTRL1, SZ_1M, MT_DEVICE }, | 111 | { |
| 110 | { (u32)BAST_VA_CTRL2, BAST_PA_CTRL2, SZ_1M, MT_DEVICE }, | 112 | .virtual = (u32)BAST_VA_CTRL1, |
| 111 | { (u32)BAST_VA_CTRL3, BAST_PA_CTRL3, SZ_1M, MT_DEVICE }, | 113 | .pfn = __phys_to_pfn(BAST_PA_CTRL1), |
| 112 | { (u32)BAST_VA_CTRL4, BAST_PA_CTRL4, SZ_1M, MT_DEVICE }, | 114 | .length = SZ_1M, |
| 113 | 115 | .type = MT_DEVICE, | |
| 116 | }, { | ||
| 117 | .virtual = (u32)BAST_VA_CTRL2, | ||
| 118 | .pfn = __phys_to_pfn(BAST_PA_CTRL2), | ||
| 119 | .length = SZ_1M, | ||
| 120 | .type = MT_DEVICE, | ||
| 121 | }, { | ||
| 122 | .virtual = (u32)BAST_VA_CTRL3, | ||
| 123 | .pfn = __phys_to_pfn(BAST_PA_CTRL3), | ||
| 124 | .length = SZ_1M, | ||
| 125 | .type = MT_DEVICE, | ||
| 126 | }, { | ||
| 127 | .virtual = (u32)BAST_VA_CTRL4, | ||
| 128 | .pfn = __phys_to_pfn(BAST_PA_CTRL4), | ||
| 129 | .length = SZ_1M, | ||
| 130 | .type = MT_DEVICE, | ||
| 131 | }, | ||
| 114 | /* PC104 IRQ mux */ | 132 | /* PC104 IRQ mux */ |
| 115 | { (u32)BAST_VA_PC104_IRQREQ, BAST_PA_PC104_IRQREQ, SZ_1M, MT_DEVICE }, | 133 | { |
| 116 | { (u32)BAST_VA_PC104_IRQRAW, BAST_PA_PC104_IRQRAW, SZ_1M, MT_DEVICE }, | 134 | .virtual = (u32)BAST_VA_PC104_IRQREQ, |
| 117 | { (u32)BAST_VA_PC104_IRQMASK, BAST_PA_PC104_IRQMASK, SZ_1M, MT_DEVICE }, | 135 | .pfn = __phys_to_pfn(BAST_PA_PC104_IRQREQ), |
| 136 | .length = SZ_1M, | ||
| 137 | .type = MT_DEVICE, | ||
| 138 | }, { | ||
| 139 | .virtual = (u32)BAST_VA_PC104_IRQRAW, | ||
| 140 | .pfn = __phys_to_pfn(BAST_PA_PC104_IRQRAW), | ||
| 141 | .length = SZ_1M, | ||
| 142 | .type = MT_DEVICE, | ||
| 143 | }, { | ||
| 144 | .virtual = (u32)BAST_VA_PC104_IRQMASK, | ||
| 145 | .pfn = __phys_to_pfn(BAST_PA_PC104_IRQMASK), | ||
| 146 | .length = SZ_1M, | ||
| 147 | .type = MT_DEVICE, | ||
| 148 | }, | ||
| 118 | 149 | ||
| 119 | /* peripheral space... one for each of fast/slow/byte/16bit */ | 150 | /* peripheral space... one for each of fast/slow/byte/16bit */ |
| 120 | /* note, ide is only decoded in word space, even though some registers | 151 | /* note, ide is only decoded in word space, even though some registers |
diff --git a/arch/arm/mach-s3c2410/mach-rx3715.c b/arch/arm/mach-s3c2410/mach-rx3715.c index 24d69019a843..f8d86d1e16b6 100644 --- a/arch/arm/mach-s3c2410/mach-rx3715.c +++ b/arch/arm/mach-s3c2410/mach-rx3715.c | |||
| @@ -56,8 +56,17 @@ | |||
| 56 | static struct map_desc rx3715_iodesc[] __initdata = { | 56 | static struct map_desc rx3715_iodesc[] __initdata = { |
| 57 | /* dump ISA space somewhere unused */ | 57 | /* dump ISA space somewhere unused */ |
| 58 | 58 | ||
| 59 | { (u32)S3C24XX_VA_ISA_WORD, S3C2410_CS3, SZ_16M, MT_DEVICE }, | 59 | { |
| 60 | { (u32)S3C24XX_VA_ISA_BYTE, S3C2410_CS3, SZ_16M, MT_DEVICE }, | 60 | .virtual = (u32)S3C24XX_VA_ISA_WORD, |
| 61 | .pfn = __phys_to_pfn(S3C2410_CS3), | ||
| 62 | .length = SZ_1M, | ||
| 63 | .type = MT_DEVICE, | ||
| 64 | }, { | ||
| 65 | .virtual = (u32)S3C24XX_VA_ISA_BYTE, | ||
| 66 | .pfn = __phys_to_pfn(S3C2410_CS3), | ||
| 67 | .length = SZ_1M, | ||
| 68 | .type = MT_DEVICE, | ||
| 69 | }, | ||
| 61 | }; | 70 | }; |
| 62 | 71 | ||
| 63 | 72 | ||
diff --git a/arch/arm/mach-s3c2410/mach-smdk2440.c b/arch/arm/mach-s3c2410/mach-smdk2440.c index d666c621ad06..4e31118533e6 100644 --- a/arch/arm/mach-s3c2410/mach-smdk2440.c +++ b/arch/arm/mach-s3c2410/mach-smdk2440.c | |||
| @@ -58,8 +58,27 @@ | |||
| 58 | static struct map_desc smdk2440_iodesc[] __initdata = { | 58 | static struct map_desc smdk2440_iodesc[] __initdata = { |
| 59 | /* ISA IO Space map (memory space selected by A24) */ | 59 | /* ISA IO Space map (memory space selected by A24) */ |
| 60 | 60 | ||
| 61 | { (u32)S3C24XX_VA_ISA_WORD, S3C2410_CS2, SZ_16M, MT_DEVICE }, | 61 | { |
| 62 | { (u32)S3C24XX_VA_ISA_BYTE, S3C2410_CS2, SZ_16M, MT_DEVICE }, | 62 | .virtual = (u32)S3C24XX_VA_ISA_WORD, |
| 63 | .pfn = __phys_to_pfn(S3C2410_CS2), | ||
| 64 | .length = 0x10000, | ||
| 65 | .type = MT_DEVICE, | ||
| 66 | }, { | ||
| 67 | .virtual = (u32)S3C24XX_VA_ISA_WORD + 0x10000, | ||
| 68 | .pfn = __phys_to_pfn(S3C2410_CS2 + (1<<24)), | ||
| 69 | .length = SZ_4M, | ||
| 70 | .type = MT_DEVICE, | ||
| 71 | }, { | ||
| 72 | .virtual = (u32)S3C24XX_VA_ISA_BYTE, | ||
| 73 | .pfn = __phys_to_pfn(S3C2410_CS2), | ||
| 74 | .length = 0x10000, | ||
| 75 | .type = MT_DEVICE, | ||
| 76 | }, { | ||
| 77 | .virtual = (u32)S3C24XX_VA_ISA_BYTE + 0x10000, | ||
| 78 | .pfn = __phys_to_pfn(S3C2410_CS2 + (1<<24)), | ||
| 79 | .length = SZ_4M, | ||
| 80 | .type = MT_DEVICE, | ||
| 81 | } | ||
| 63 | }; | 82 | }; |
| 64 | 83 | ||
| 65 | #define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK | 84 | #define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK |
diff --git a/arch/arm/mach-s3c2410/mach-vr1000.c b/arch/arm/mach-s3c2410/mach-vr1000.c index 46b259673c18..ae7e099bf6c8 100644 --- a/arch/arm/mach-s3c2410/mach-vr1000.c +++ b/arch/arm/mach-s3c2410/mach-vr1000.c | |||
| @@ -74,27 +74,47 @@ | |||
| 74 | 74 | ||
| 75 | /* macros to modify the physical addresses for io space */ | 75 | /* macros to modify the physical addresses for io space */ |
| 76 | 76 | ||
| 77 | #define PA_CS2(item) ((item) + S3C2410_CS2) | 77 | #define PA_CS2(item) (__phys_to_pfn((item) + S3C2410_CS2)) |
| 78 | #define PA_CS3(item) ((item) + S3C2410_CS3) | 78 | #define PA_CS3(item) (__phys_to_pfn((item) + S3C2410_CS3)) |
| 79 | #define PA_CS4(item) ((item) + S3C2410_CS4) | 79 | #define PA_CS4(item) (__phys_to_pfn((item) + S3C2410_CS4)) |
| 80 | #define PA_CS5(item) ((item) + S3C2410_CS5) | 80 | #define PA_CS5(item) (__phys_to_pfn((item) + S3C2410_CS5)) |
| 81 | 81 | ||
| 82 | static struct map_desc vr1000_iodesc[] __initdata = { | 82 | static struct map_desc vr1000_iodesc[] __initdata = { |
| 83 | /* ISA IO areas */ | 83 | /* ISA IO areas */ |
| 84 | 84 | { | |
| 85 | { (u32)S3C24XX_VA_ISA_BYTE, PA_CS2(BAST_PA_ISAIO), SZ_16M, MT_DEVICE }, | 85 | .virtual = (u32)S3C24XX_VA_ISA_BYTE, |
| 86 | { (u32)S3C24XX_VA_ISA_WORD, PA_CS3(BAST_PA_ISAIO), SZ_16M, MT_DEVICE }, | 86 | .pfn = PA_CS2(BAST_PA_ISAIO), |
| 87 | 87 | .length = SZ_16M, | |
| 88 | /* we could possibly compress the next set down into a set of smaller tables | 88 | .type = MT_DEVICE, |
| 89 | * pagetables, but that would mean using an L2 section, and it still means | 89 | }, { |
| 90 | * we cannot actually feed the same register to an LDR due to 16K spacing | 90 | .virtual = (u32)S3C24XX_VA_ISA_WORD, |
| 91 | */ | 91 | .pfn = PA_CS3(BAST_PA_ISAIO), |
| 92 | 92 | .length = SZ_16M, | |
| 93 | /* bast CPLD control registers, and external interrupt controls */ | 93 | .type = MT_DEVICE, |
| 94 | { (u32)VR1000_VA_CTRL1, VR1000_PA_CTRL1, SZ_1M, MT_DEVICE }, | 94 | }, |
| 95 | { (u32)VR1000_VA_CTRL2, VR1000_PA_CTRL2, SZ_1M, MT_DEVICE }, | 95 | |
| 96 | { (u32)VR1000_VA_CTRL3, VR1000_PA_CTRL3, SZ_1M, MT_DEVICE }, | 96 | /* CPLD control registers, and external interrupt controls */ |
| 97 | { (u32)VR1000_VA_CTRL4, VR1000_PA_CTRL4, SZ_1M, MT_DEVICE }, | 97 | { |
| 98 | .virtual = (u32)VR1000_VA_CTRL1, | ||
| 99 | .pfn = __phys_to_pfn(VR1000_PA_CTRL1), | ||
| 100 | .length = SZ_1M, | ||
| 101 | .type = MT_DEVICE, | ||
| 102 | }, { | ||
| 103 | .virtual = (u32)VR1000_VA_CTRL2, | ||
| 104 | .pfn = __phys_to_pfn(VR1000_PA_CTRL2), | ||
| 105 | .length = SZ_1M, | ||
| 106 | .type = MT_DEVICE, | ||
| 107 | }, { | ||
| 108 | .virtual = (u32)VR1000_VA_CTRL3, | ||
| 109 | .pfn = __phys_to_pfn(VR1000_PA_CTRL3), | ||
| 110 | .length = SZ_1M, | ||
| 111 | .type = MT_DEVICE, | ||
| 112 | }, { | ||
| 113 | .virtual = (u32)VR1000_VA_CTRL4, | ||
| 114 | .pfn = __phys_to_pfn(VR1000_PA_CTRL4), | ||
| 115 | .length = SZ_1M, | ||
| 116 | .type = MT_DEVICE, | ||
| 117 | }, | ||
| 98 | 118 | ||
| 99 | /* peripheral space... one for each of fast/slow/byte/16bit */ | 119 | /* peripheral space... one for each of fast/slow/byte/16bit */ |
| 100 | /* note, ide is only decoded in word space, even though some registers | 120 | /* note, ide is only decoded in word space, even though some registers |
diff --git a/arch/arm/mach-sa1100/time.c b/arch/arm/mach-sa1100/time.c index 47e0420623fc..e4b435e634e4 100644 --- a/arch/arm/mach-sa1100/time.c +++ b/arch/arm/mach-sa1100/time.c | |||
| @@ -124,11 +124,13 @@ static void __init sa1100_timer_init(void) | |||
| 124 | tv.tv_sec = sa1100_get_rtc_time(); | 124 | tv.tv_sec = sa1100_get_rtc_time(); |
| 125 | do_settimeofday(&tv); | 125 | do_settimeofday(&tv); |
| 126 | 126 | ||
| 127 | OSMR0 = 0; /* set initial match at 0 */ | 127 | OIER = 0; /* disable any timer interrupts */ |
| 128 | OSCR = LATCH*2; /* push OSCR out of the way */ | ||
| 129 | OSMR0 = LATCH; /* set initial match */ | ||
| 128 | OSSR = 0xf; /* clear status on all timers */ | 130 | OSSR = 0xf; /* clear status on all timers */ |
| 129 | setup_irq(IRQ_OST0, &sa1100_timer_irq); | 131 | setup_irq(IRQ_OST0, &sa1100_timer_irq); |
| 130 | OIER |= OIER_E0; /* enable match on timer 0 to cause interrupts */ | 132 | OIER = OIER_E0; /* enable match on timer 0 to cause interrupts */ |
| 131 | OSCR = 0; /* initialize free-running timer, force first match */ | 133 | OSCR = 0; /* initialize free-running timer */ |
| 132 | } | 134 | } |
| 133 | 135 | ||
| 134 | #ifdef CONFIG_NO_IDLE_HZ | 136 | #ifdef CONFIG_NO_IDLE_HZ |
diff --git a/arch/arm/mm/mm-armv.c b/arch/arm/mm/mm-armv.c index fb5b40289de2..9e50127be635 100644 --- a/arch/arm/mm/mm-armv.c +++ b/arch/arm/mm/mm-armv.c | |||
| @@ -354,7 +354,7 @@ void __init build_mem_type_table(void) | |||
| 354 | { | 354 | { |
| 355 | struct cachepolicy *cp; | 355 | struct cachepolicy *cp; |
| 356 | unsigned int cr = get_cr(); | 356 | unsigned int cr = get_cr(); |
| 357 | unsigned int user_pgprot; | 357 | unsigned int user_pgprot, kern_pgprot; |
| 358 | int cpu_arch = cpu_architecture(); | 358 | int cpu_arch = cpu_architecture(); |
| 359 | int i; | 359 | int i; |
| 360 | 360 | ||
| @@ -381,7 +381,7 @@ void __init build_mem_type_table(void) | |||
| 381 | } | 381 | } |
| 382 | 382 | ||
| 383 | cp = &cache_policies[cachepolicy]; | 383 | cp = &cache_policies[cachepolicy]; |
| 384 | user_pgprot = cp->pte; | 384 | kern_pgprot = user_pgprot = cp->pte; |
| 385 | 385 | ||
| 386 | /* | 386 | /* |
| 387 | * ARMv6 and above have extended page tables. | 387 | * ARMv6 and above have extended page tables. |
| @@ -393,6 +393,7 @@ void __init build_mem_type_table(void) | |||
| 393 | */ | 393 | */ |
| 394 | mem_types[MT_MEMORY].prot_sect &= ~PMD_BIT4; | 394 | mem_types[MT_MEMORY].prot_sect &= ~PMD_BIT4; |
| 395 | mem_types[MT_ROM].prot_sect &= ~PMD_BIT4; | 395 | mem_types[MT_ROM].prot_sect &= ~PMD_BIT4; |
| 396 | |||
| 396 | /* | 397 | /* |
| 397 | * Mark cache clean areas and XIP ROM read only | 398 | * Mark cache clean areas and XIP ROM read only |
| 398 | * from SVC mode and no access from userspace. | 399 | * from SVC mode and no access from userspace. |
| @@ -412,32 +413,47 @@ void __init build_mem_type_table(void) | |||
| 412 | * (iow, non-global) | 413 | * (iow, non-global) |
| 413 | */ | 414 | */ |
| 414 | user_pgprot |= L_PTE_ASID; | 415 | user_pgprot |= L_PTE_ASID; |
| 416 | |||
| 417 | #ifdef CONFIG_SMP | ||
| 418 | /* | ||
| 419 | * Mark memory with the "shared" attribute for SMP systems | ||
| 420 | */ | ||
| 421 | user_pgprot |= L_PTE_SHARED; | ||
| 422 | kern_pgprot |= L_PTE_SHARED; | ||
| 423 | mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S; | ||
| 424 | #endif | ||
| 415 | } | 425 | } |
| 416 | 426 | ||
| 427 | for (i = 0; i < 16; i++) { | ||
| 428 | unsigned long v = pgprot_val(protection_map[i]); | ||
| 429 | v = (v & ~(L_PTE_BUFFERABLE|L_PTE_CACHEABLE)) | user_pgprot; | ||
| 430 | protection_map[i] = __pgprot(v); | ||
| 431 | } | ||
| 432 | |||
| 433 | mem_types[MT_LOW_VECTORS].prot_pte |= kern_pgprot; | ||
| 434 | mem_types[MT_HIGH_VECTORS].prot_pte |= kern_pgprot; | ||
| 435 | |||
| 417 | if (cpu_arch >= CPU_ARCH_ARMv5) { | 436 | if (cpu_arch >= CPU_ARCH_ARMv5) { |
| 418 | mem_types[MT_LOW_VECTORS].prot_pte |= cp->pte & PTE_CACHEABLE; | 437 | #ifndef CONFIG_SMP |
| 419 | mem_types[MT_HIGH_VECTORS].prot_pte |= cp->pte & PTE_CACHEABLE; | 438 | /* |
| 439 | * Only use write-through for non-SMP systems | ||
| 440 | */ | ||
| 441 | mem_types[MT_LOW_VECTORS].prot_pte &= ~L_PTE_BUFFERABLE; | ||
| 442 | mem_types[MT_HIGH_VECTORS].prot_pte &= ~L_PTE_BUFFERABLE; | ||
| 443 | #endif | ||
| 420 | } else { | 444 | } else { |
| 421 | mem_types[MT_LOW_VECTORS].prot_pte |= cp->pte; | ||
| 422 | mem_types[MT_HIGH_VECTORS].prot_pte |= cp->pte; | ||
| 423 | mem_types[MT_MINICLEAN].prot_sect &= ~PMD_SECT_TEX(1); | 445 | mem_types[MT_MINICLEAN].prot_sect &= ~PMD_SECT_TEX(1); |
| 424 | } | 446 | } |
| 425 | 447 | ||
| 448 | pgprot_kernel = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | | ||
| 449 | L_PTE_DIRTY | L_PTE_WRITE | | ||
| 450 | L_PTE_EXEC | kern_pgprot); | ||
| 451 | |||
| 426 | mem_types[MT_LOW_VECTORS].prot_l1 |= ecc_mask; | 452 | mem_types[MT_LOW_VECTORS].prot_l1 |= ecc_mask; |
| 427 | mem_types[MT_HIGH_VECTORS].prot_l1 |= ecc_mask; | 453 | mem_types[MT_HIGH_VECTORS].prot_l1 |= ecc_mask; |
| 428 | mem_types[MT_MEMORY].prot_sect |= ecc_mask | cp->pmd; | 454 | mem_types[MT_MEMORY].prot_sect |= ecc_mask | cp->pmd; |
| 429 | mem_types[MT_ROM].prot_sect |= cp->pmd; | 455 | mem_types[MT_ROM].prot_sect |= cp->pmd; |
| 430 | 456 | ||
| 431 | for (i = 0; i < 16; i++) { | ||
| 432 | unsigned long v = pgprot_val(protection_map[i]); | ||
| 433 | v = (v & ~(PTE_BUFFERABLE|PTE_CACHEABLE)) | user_pgprot; | ||
| 434 | protection_map[i] = __pgprot(v); | ||
| 435 | } | ||
| 436 | |||
| 437 | pgprot_kernel = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | | ||
| 438 | L_PTE_DIRTY | L_PTE_WRITE | | ||
| 439 | L_PTE_EXEC | cp->pte); | ||
| 440 | |||
| 441 | switch (cp->pmd) { | 457 | switch (cp->pmd) { |
| 442 | case PMD_SECT_WT: | 458 | case PMD_SECT_WT: |
| 443 | mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_WT; | 459 | mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_WT; |
diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S index 9bb5fff406fb..92f3ca31b7b9 100644 --- a/arch/arm/mm/proc-v6.S +++ b/arch/arm/mm/proc-v6.S | |||
| @@ -12,6 +12,7 @@ | |||
| 12 | #include <linux/linkage.h> | 12 | #include <linux/linkage.h> |
| 13 | #include <asm/assembler.h> | 13 | #include <asm/assembler.h> |
| 14 | #include <asm/asm-offsets.h> | 14 | #include <asm/asm-offsets.h> |
| 15 | #include <asm/hardware/arm_scu.h> | ||
| 15 | #include <asm/procinfo.h> | 16 | #include <asm/procinfo.h> |
| 16 | #include <asm/pgtable.h> | 17 | #include <asm/pgtable.h> |
| 17 | 18 | ||
| @@ -112,6 +113,9 @@ ENTRY(cpu_v6_dcache_clean_area) | |||
| 112 | ENTRY(cpu_v6_switch_mm) | 113 | ENTRY(cpu_v6_switch_mm) |
| 113 | mov r2, #0 | 114 | mov r2, #0 |
| 114 | ldr r1, [r1, #MM_CONTEXT_ID] @ get mm->context.id | 115 | ldr r1, [r1, #MM_CONTEXT_ID] @ get mm->context.id |
| 116 | #ifdef CONFIG_SMP | ||
| 117 | orr r0, r0, #2 @ set shared pgtable | ||
| 118 | #endif | ||
| 115 | mcr p15, 0, r2, c7, c5, 6 @ flush BTAC/BTB | 119 | mcr p15, 0, r2, c7, c5, 6 @ flush BTAC/BTB |
| 116 | mcr p15, 0, r2, c7, c10, 4 @ drain write buffer | 120 | mcr p15, 0, r2, c7, c10, 4 @ drain write buffer |
| 117 | mcr p15, 0, r0, c2, c0, 0 @ set TTB 0 | 121 | mcr p15, 0, r0, c2, c0, 0 @ set TTB 0 |
| @@ -140,7 +144,7 @@ ENTRY(cpu_v6_switch_mm) | |||
| 140 | ENTRY(cpu_v6_set_pte) | 144 | ENTRY(cpu_v6_set_pte) |
| 141 | str r1, [r0], #-2048 @ linux version | 145 | str r1, [r0], #-2048 @ linux version |
| 142 | 146 | ||
| 143 | bic r2, r1, #0x000007f0 | 147 | bic r2, r1, #0x000003f0 |
| 144 | bic r2, r2, #0x00000003 | 148 | bic r2, r2, #0x00000003 |
| 145 | orr r2, r2, #PTE_EXT_AP0 | 2 | 149 | orr r2, r2, #PTE_EXT_AP0 | 2 |
| 146 | 150 | ||
| @@ -191,6 +195,23 @@ cpu_v6_name: | |||
| 191 | * - cache type register is implemented | 195 | * - cache type register is implemented |
| 192 | */ | 196 | */ |
| 193 | __v6_setup: | 197 | __v6_setup: |
| 198 | #ifdef CONFIG_SMP | ||
| 199 | /* Set up the SCU on core 0 only */ | ||
| 200 | mrc p15, 0, r0, c0, c0, 5 @ CPU core number | ||
| 201 | ands r0, r0, #15 | ||
| 202 | moveq r0, #0x10000000 @ SCU_BASE | ||
| 203 | orreq r0, r0, #0x00100000 | ||
| 204 | ldreq r5, [r0, #SCU_CTRL] | ||
| 205 | orreq r5, r5, #1 | ||
| 206 | streq r5, [r0, #SCU_CTRL] | ||
| 207 | |||
| 208 | #ifndef CONFIG_CPU_DCACHE_DISABLE | ||
| 209 | mrc p15, 0, r0, c1, c0, 1 @ Enable SMP/nAMP mode | ||
| 210 | orr r0, r0, #0x20 | ||
| 211 | mcr p15, 0, r0, c1, c0, 1 | ||
| 212 | #endif | ||
| 213 | #endif | ||
| 214 | |||
| 194 | mov r0, #0 | 215 | mov r0, #0 |
| 195 | mcr p15, 0, r0, c7, c14, 0 @ clean+invalidate D cache | 216 | mcr p15, 0, r0, c7, c14, 0 @ clean+invalidate D cache |
| 196 | mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache | 217 | mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache |
| @@ -198,6 +219,9 @@ __v6_setup: | |||
| 198 | mcr p15, 0, r0, c7, c10, 4 @ drain write buffer | 219 | mcr p15, 0, r0, c7, c10, 4 @ drain write buffer |
| 199 | mcr p15, 0, r0, c8, c7, 0 @ invalidate I + D TLBs | 220 | mcr p15, 0, r0, c8, c7, 0 @ invalidate I + D TLBs |
| 200 | mcr p15, 0, r0, c2, c0, 2 @ TTB control register | 221 | mcr p15, 0, r0, c2, c0, 2 @ TTB control register |
| 222 | #ifdef CONFIG_SMP | ||
| 223 | orr r4, r4, #2 @ set shared pgtable | ||
| 224 | #endif | ||
| 201 | mcr p15, 0, r4, c2, c0, 1 @ load TTB1 | 225 | mcr p15, 0, r4, c2, c0, 1 @ load TTB1 |
| 202 | #ifdef CONFIG_VFP | 226 | #ifdef CONFIG_VFP |
| 203 | mrc p15, 0, r0, c1, c0, 2 | 227 | mrc p15, 0, r0, c1, c0, 2 |
diff --git a/arch/arm/nwfpe/fpa11.h b/arch/arm/nwfpe/fpa11.h index 9677ae8448e8..da4c616b6c49 100644 --- a/arch/arm/nwfpe/fpa11.h +++ b/arch/arm/nwfpe/fpa11.h | |||
| @@ -60,7 +60,7 @@ typedef union tagFPREG { | |||
| 60 | #ifdef CONFIG_FPE_NWFPE_XP | 60 | #ifdef CONFIG_FPE_NWFPE_XP |
| 61 | floatx80 fExtended; | 61 | floatx80 fExtended; |
| 62 | #else | 62 | #else |
| 63 | int padding[3]; | 63 | u32 padding[3]; |
| 64 | #endif | 64 | #endif |
| 65 | } FPREG; | 65 | } FPREG; |
| 66 | 66 | ||
diff --git a/arch/arm/nwfpe/fpa11_cpdt.c b/arch/arm/nwfpe/fpa11_cpdt.c index b0db5cbcc3b1..32859fa8dcfc 100644 --- a/arch/arm/nwfpe/fpa11_cpdt.c +++ b/arch/arm/nwfpe/fpa11_cpdt.c | |||
| @@ -59,8 +59,13 @@ static inline void loadExtended(const unsigned int Fn, const unsigned int __user | |||
| 59 | p = (unsigned int *) &fpa11->fpreg[Fn].fExtended; | 59 | p = (unsigned int *) &fpa11->fpreg[Fn].fExtended; |
| 60 | fpa11->fType[Fn] = typeExtended; | 60 | fpa11->fType[Fn] = typeExtended; |
| 61 | get_user(p[0], &pMem[0]); /* sign & exponent */ | 61 | get_user(p[0], &pMem[0]); /* sign & exponent */ |
| 62 | #ifdef __ARMEB__ | ||
| 63 | get_user(p[1], &pMem[1]); /* ms bits */ | ||
| 64 | get_user(p[2], &pMem[2]); /* ls bits */ | ||
| 65 | #else | ||
| 62 | get_user(p[1], &pMem[2]); /* ls bits */ | 66 | get_user(p[1], &pMem[2]); /* ls bits */ |
| 63 | get_user(p[2], &pMem[1]); /* ms bits */ | 67 | get_user(p[2], &pMem[1]); /* ms bits */ |
| 68 | #endif | ||
| 64 | } | 69 | } |
| 65 | #endif | 70 | #endif |
| 66 | 71 | ||
| @@ -177,8 +182,13 @@ static inline void storeExtended(const unsigned int Fn, unsigned int __user *pMe | |||
| 177 | } | 182 | } |
| 178 | 183 | ||
| 179 | put_user(val.i[0], &pMem[0]); /* sign & exp */ | 184 | put_user(val.i[0], &pMem[0]); /* sign & exp */ |
| 185 | #ifdef __ARMEB__ | ||
| 186 | put_user(val.i[1], &pMem[1]); /* msw */ | ||
| 187 | put_user(val.i[2], &pMem[2]); | ||
| 188 | #else | ||
| 180 | put_user(val.i[1], &pMem[2]); | 189 | put_user(val.i[1], &pMem[2]); |
| 181 | put_user(val.i[2], &pMem[1]); /* msw */ | 190 | put_user(val.i[2], &pMem[1]); /* msw */ |
| 191 | #endif | ||
| 182 | } | 192 | } |
| 183 | #endif | 193 | #endif |
| 184 | 194 | ||
diff --git a/arch/arm/nwfpe/fpopcode.c b/arch/arm/nwfpe/fpopcode.c index 4c9f5703148c..67ff2ab08ea0 100644 --- a/arch/arm/nwfpe/fpopcode.c +++ b/arch/arm/nwfpe/fpopcode.c | |||
| @@ -29,14 +29,14 @@ | |||
| 29 | 29 | ||
| 30 | #ifdef CONFIG_FPE_NWFPE_XP | 30 | #ifdef CONFIG_FPE_NWFPE_XP |
| 31 | const floatx80 floatx80Constant[] = { | 31 | const floatx80 floatx80Constant[] = { |
| 32 | {0x0000, 0x0000000000000000ULL}, /* extended 0.0 */ | 32 | { .high = 0x0000, .low = 0x0000000000000000ULL},/* extended 0.0 */ |
| 33 | {0x3fff, 0x8000000000000000ULL}, /* extended 1.0 */ | 33 | { .high = 0x3fff, .low = 0x8000000000000000ULL},/* extended 1.0 */ |
| 34 | {0x4000, 0x8000000000000000ULL}, /* extended 2.0 */ | 34 | { .high = 0x4000, .low = 0x8000000000000000ULL},/* extended 2.0 */ |
| 35 | {0x4000, 0xc000000000000000ULL}, /* extended 3.0 */ | 35 | { .high = 0x4000, .low = 0xc000000000000000ULL},/* extended 3.0 */ |
| 36 | {0x4001, 0x8000000000000000ULL}, /* extended 4.0 */ | 36 | { .high = 0x4001, .low = 0x8000000000000000ULL},/* extended 4.0 */ |
| 37 | {0x4001, 0xa000000000000000ULL}, /* extended 5.0 */ | 37 | { .high = 0x4001, .low = 0xa000000000000000ULL},/* extended 5.0 */ |
| 38 | {0x3ffe, 0x8000000000000000ULL}, /* extended 0.5 */ | 38 | { .high = 0x3ffe, .low = 0x8000000000000000ULL},/* extended 0.5 */ |
| 39 | {0x4002, 0xa000000000000000ULL} /* extended 10.0 */ | 39 | { .high = 0x4002, .low = 0xa000000000000000ULL},/* extended 10.0 */ |
| 40 | }; | 40 | }; |
| 41 | #endif | 41 | #endif |
| 42 | 42 | ||
diff --git a/arch/arm/nwfpe/softfloat-specialize b/arch/arm/nwfpe/softfloat-specialize index acf409144763..d4a4c8e06635 100644 --- a/arch/arm/nwfpe/softfloat-specialize +++ b/arch/arm/nwfpe/softfloat-specialize | |||
| @@ -332,6 +332,7 @@ static floatx80 commonNaNToFloatx80( commonNaNT a ) | |||
| 332 | 332 | ||
| 333 | z.low = LIT64( 0xC000000000000000 ) | ( a.high>>1 ); | 333 | z.low = LIT64( 0xC000000000000000 ) | ( a.high>>1 ); |
| 334 | z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF; | 334 | z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF; |
| 335 | z.__padding = 0; | ||
| 335 | return z; | 336 | return z; |
| 336 | 337 | ||
| 337 | } | 338 | } |
diff --git a/arch/arm/nwfpe/softfloat.c b/arch/arm/nwfpe/softfloat.c index f9f049132a17..0f9656e482ba 100644 --- a/arch/arm/nwfpe/softfloat.c +++ b/arch/arm/nwfpe/softfloat.c | |||
| @@ -531,6 +531,7 @@ INLINE floatx80 packFloatx80( flag zSign, int32 zExp, bits64 zSig ) | |||
| 531 | 531 | ||
| 532 | z.low = zSig; | 532 | z.low = zSig; |
| 533 | z.high = ( ( (bits16) zSign )<<15 ) + zExp; | 533 | z.high = ( ( (bits16) zSign )<<15 ) + zExp; |
| 534 | z.__padding = 0; | ||
| 534 | return z; | 535 | return z; |
| 535 | 536 | ||
| 536 | } | 537 | } |
| @@ -2831,6 +2832,7 @@ static floatx80 subFloatx80Sigs( struct roundingData *roundData, floatx80 a, flo | |||
| 2831 | roundData->exception |= float_flag_invalid; | 2832 | roundData->exception |= float_flag_invalid; |
| 2832 | z.low = floatx80_default_nan_low; | 2833 | z.low = floatx80_default_nan_low; |
| 2833 | z.high = floatx80_default_nan_high; | 2834 | z.high = floatx80_default_nan_high; |
| 2835 | z.__padding = 0; | ||
| 2834 | return z; | 2836 | return z; |
| 2835 | } | 2837 | } |
| 2836 | if ( aExp == 0 ) { | 2838 | if ( aExp == 0 ) { |
| @@ -2950,6 +2952,7 @@ floatx80 floatx80_mul( struct roundingData *roundData, floatx80 a, floatx80 b ) | |||
| 2950 | roundData->exception |= float_flag_invalid; | 2952 | roundData->exception |= float_flag_invalid; |
| 2951 | z.low = floatx80_default_nan_low; | 2953 | z.low = floatx80_default_nan_low; |
| 2952 | z.high = floatx80_default_nan_high; | 2954 | z.high = floatx80_default_nan_high; |
| 2955 | z.__padding = 0; | ||
| 2953 | return z; | 2956 | return z; |
| 2954 | } | 2957 | } |
| 2955 | return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); | 2958 | return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); |
| @@ -3015,6 +3018,7 @@ floatx80 floatx80_div( struct roundingData *roundData, floatx80 a, floatx80 b ) | |||
| 3015 | roundData->exception |= float_flag_invalid; | 3018 | roundData->exception |= float_flag_invalid; |
| 3016 | z.low = floatx80_default_nan_low; | 3019 | z.low = floatx80_default_nan_low; |
| 3017 | z.high = floatx80_default_nan_high; | 3020 | z.high = floatx80_default_nan_high; |
| 3021 | z.__padding = 0; | ||
| 3018 | return z; | 3022 | return z; |
| 3019 | } | 3023 | } |
| 3020 | roundData->exception |= float_flag_divbyzero; | 3024 | roundData->exception |= float_flag_divbyzero; |
| @@ -3093,6 +3097,7 @@ floatx80 floatx80_rem( struct roundingData *roundData, floatx80 a, floatx80 b ) | |||
| 3093 | roundData->exception |= float_flag_invalid; | 3097 | roundData->exception |= float_flag_invalid; |
| 3094 | z.low = floatx80_default_nan_low; | 3098 | z.low = floatx80_default_nan_low; |
| 3095 | z.high = floatx80_default_nan_high; | 3099 | z.high = floatx80_default_nan_high; |
| 3100 | z.__padding = 0; | ||
| 3096 | return z; | 3101 | return z; |
| 3097 | } | 3102 | } |
| 3098 | normalizeFloatx80Subnormal( bSig, &bExp, &bSig ); | 3103 | normalizeFloatx80Subnormal( bSig, &bExp, &bSig ); |
| @@ -3184,6 +3189,7 @@ floatx80 floatx80_sqrt( struct roundingData *roundData, floatx80 a ) | |||
| 3184 | roundData->exception |= float_flag_invalid; | 3189 | roundData->exception |= float_flag_invalid; |
| 3185 | z.low = floatx80_default_nan_low; | 3190 | z.low = floatx80_default_nan_low; |
| 3186 | z.high = floatx80_default_nan_high; | 3191 | z.high = floatx80_default_nan_high; |
| 3192 | z.__padding = 0; | ||
| 3187 | return z; | 3193 | return z; |
| 3188 | } | 3194 | } |
| 3189 | if ( aExp == 0 ) { | 3195 | if ( aExp == 0 ) { |
diff --git a/arch/arm/nwfpe/softfloat.h b/arch/arm/nwfpe/softfloat.h index 14151700b6b2..978c699673c6 100644 --- a/arch/arm/nwfpe/softfloat.h +++ b/arch/arm/nwfpe/softfloat.h | |||
| @@ -51,11 +51,17 @@ input or output the `floatx80' type will be defined. | |||
| 51 | Software IEC/IEEE floating-point types. | 51 | Software IEC/IEEE floating-point types. |
| 52 | ------------------------------------------------------------------------------- | 52 | ------------------------------------------------------------------------------- |
| 53 | */ | 53 | */ |
| 54 | typedef unsigned long int float32; | 54 | typedef u32 float32; |
| 55 | typedef unsigned long long float64; | 55 | typedef u64 float64; |
| 56 | typedef struct { | 56 | typedef struct { |
| 57 | unsigned short high; | 57 | #ifdef __ARMEB__ |
| 58 | unsigned long long low; | 58 | u16 __padding; |
| 59 | u16 high; | ||
| 60 | #else | ||
| 61 | u16 high; | ||
| 62 | u16 __padding; | ||
| 63 | #endif | ||
| 64 | u64 low; | ||
| 59 | } floatx80; | 65 | } floatx80; |
| 60 | 66 | ||
| 61 | /* | 67 | /* |
diff --git a/arch/arm/plat-omap/ocpi.c b/arch/arm/plat-omap/ocpi.c index 1fb16f9edfd5..2ede2ee8cae4 100644 --- a/arch/arm/plat-omap/ocpi.c +++ b/arch/arm/plat-omap/ocpi.c | |||
| @@ -25,7 +25,6 @@ | |||
| 25 | 25 | ||
| 26 | #include <linux/config.h> | 26 | #include <linux/config.h> |
| 27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
| 28 | #include <linux/version.h> | ||
| 29 | #include <linux/types.h> | 28 | #include <linux/types.h> |
| 30 | #include <linux/errno.h> | 29 | #include <linux/errno.h> |
| 31 | #include <linux/kernel.h> | 30 | #include <linux/kernel.h> |
