diff options
Diffstat (limited to 'arch')
173 files changed, 5801 insertions, 1201 deletions
diff --git a/arch/Kconfig b/arch/Kconfig index 4877a8c8ee16..fe48fc7a3eba 100644 --- a/arch/Kconfig +++ b/arch/Kconfig | |||
@@ -32,8 +32,9 @@ config HAVE_OPROFILE | |||
32 | 32 | ||
33 | config KPROBES | 33 | config KPROBES |
34 | bool "Kprobes" | 34 | bool "Kprobes" |
35 | depends on KALLSYMS && MODULES | 35 | depends on MODULES |
36 | depends on HAVE_KPROBES | 36 | depends on HAVE_KPROBES |
37 | select KALLSYMS | ||
37 | help | 38 | help |
38 | Kprobes allows you to trap at almost any kernel address and | 39 | Kprobes allows you to trap at almost any kernel address and |
39 | execute a callback function. register_kprobe() establishes | 40 | execute a callback function. register_kprobe() establishes |
@@ -45,7 +46,6 @@ config OPTPROBES | |||
45 | def_bool y | 46 | def_bool y |
46 | depends on KPROBES && HAVE_OPTPROBES | 47 | depends on KPROBES && HAVE_OPTPROBES |
47 | depends on !PREEMPT | 48 | depends on !PREEMPT |
48 | select KALLSYMS_ALL | ||
49 | 49 | ||
50 | config HAVE_EFFICIENT_UNALIGNED_ACCESS | 50 | config HAVE_EFFICIENT_UNALIGNED_ACCESS |
51 | bool | 51 | bool |
diff --git a/arch/alpha/include/asm/cacheflush.h b/arch/alpha/include/asm/cacheflush.h index 01d71e1c8a9e..012f1243b1c1 100644 --- a/arch/alpha/include/asm/cacheflush.h +++ b/arch/alpha/include/asm/cacheflush.h | |||
@@ -43,6 +43,8 @@ extern void smp_imb(void); | |||
43 | /* ??? Ought to use this in arch/alpha/kernel/signal.c too. */ | 43 | /* ??? Ought to use this in arch/alpha/kernel/signal.c too. */ |
44 | 44 | ||
45 | #ifndef CONFIG_SMP | 45 | #ifndef CONFIG_SMP |
46 | #include <linux/sched.h> | ||
47 | |||
46 | extern void __load_new_mm_context(struct mm_struct *); | 48 | extern void __load_new_mm_context(struct mm_struct *); |
47 | static inline void | 49 | static inline void |
48 | flush_icache_user_range(struct vm_area_struct *vma, struct page *page, | 50 | flush_icache_user_range(struct vm_area_struct *vma, struct page *page, |
diff --git a/arch/alpha/include/asm/unistd.h b/arch/alpha/include/asm/unistd.h index 804e5311c841..058937bf5a77 100644 --- a/arch/alpha/include/asm/unistd.h +++ b/arch/alpha/include/asm/unistd.h | |||
@@ -449,10 +449,13 @@ | |||
449 | #define __NR_pwritev 491 | 449 | #define __NR_pwritev 491 |
450 | #define __NR_rt_tgsigqueueinfo 492 | 450 | #define __NR_rt_tgsigqueueinfo 492 |
451 | #define __NR_perf_event_open 493 | 451 | #define __NR_perf_event_open 493 |
452 | #define __NR_fanotify_init 494 | ||
453 | #define __NR_fanotify_mark 495 | ||
454 | #define __NR_prlimit64 496 | ||
452 | 455 | ||
453 | #ifdef __KERNEL__ | 456 | #ifdef __KERNEL__ |
454 | 457 | ||
455 | #define NR_SYSCALLS 494 | 458 | #define NR_SYSCALLS 497 |
456 | 459 | ||
457 | #define __ARCH_WANT_IPC_PARSE_VERSION | 460 | #define __ARCH_WANT_IPC_PARSE_VERSION |
458 | #define __ARCH_WANT_OLD_READDIR | 461 | #define __ARCH_WANT_OLD_READDIR |
@@ -463,6 +466,7 @@ | |||
463 | #define __ARCH_WANT_SYS_OLD_GETRLIMIT | 466 | #define __ARCH_WANT_SYS_OLD_GETRLIMIT |
464 | #define __ARCH_WANT_SYS_OLDUMOUNT | 467 | #define __ARCH_WANT_SYS_OLDUMOUNT |
465 | #define __ARCH_WANT_SYS_SIGPENDING | 468 | #define __ARCH_WANT_SYS_SIGPENDING |
469 | #define __ARCH_WANT_SYS_RT_SIGSUSPEND | ||
466 | 470 | ||
467 | /* "Conditional" syscalls. What we want is | 471 | /* "Conditional" syscalls. What we want is |
468 | 472 | ||
diff --git a/arch/alpha/kernel/entry.S b/arch/alpha/kernel/entry.S index b45d913a51c3..6d159cee5f2f 100644 --- a/arch/alpha/kernel/entry.S +++ b/arch/alpha/kernel/entry.S | |||
@@ -73,8 +73,6 @@ | |||
73 | ldq $20, HAE_REG($19); \ | 73 | ldq $20, HAE_REG($19); \ |
74 | stq $21, HAE_CACHE($19); \ | 74 | stq $21, HAE_CACHE($19); \ |
75 | stq $21, 0($20); \ | 75 | stq $21, 0($20); \ |
76 | ldq $0, 0($sp); \ | ||
77 | ldq $1, 8($sp); \ | ||
78 | 99:; \ | 76 | 99:; \ |
79 | ldq $19, 72($sp); \ | 77 | ldq $19, 72($sp); \ |
80 | ldq $20, 80($sp); \ | 78 | ldq $20, 80($sp); \ |
@@ -316,19 +314,24 @@ ret_from_sys_call: | |||
316 | cmovne $26, 0, $19 /* $19 = 0 => non-restartable */ | 314 | cmovne $26, 0, $19 /* $19 = 0 => non-restartable */ |
317 | ldq $0, SP_OFF($sp) | 315 | ldq $0, SP_OFF($sp) |
318 | and $0, 8, $0 | 316 | and $0, 8, $0 |
319 | beq $0, restore_all | 317 | beq $0, ret_to_kernel |
320 | ret_from_reschedule: | 318 | ret_to_user: |
321 | /* Make sure need_resched and sigpending don't change between | 319 | /* Make sure need_resched and sigpending don't change between |
322 | sampling and the rti. */ | 320 | sampling and the rti. */ |
323 | lda $16, 7 | 321 | lda $16, 7 |
324 | call_pal PAL_swpipl | 322 | call_pal PAL_swpipl |
325 | ldl $5, TI_FLAGS($8) | 323 | ldl $5, TI_FLAGS($8) |
326 | and $5, _TIF_WORK_MASK, $2 | 324 | and $5, _TIF_WORK_MASK, $2 |
327 | bne $5, work_pending | 325 | bne $2, work_pending |
328 | restore_all: | 326 | restore_all: |
329 | RESTORE_ALL | 327 | RESTORE_ALL |
330 | call_pal PAL_rti | 328 | call_pal PAL_rti |
331 | 329 | ||
330 | ret_to_kernel: | ||
331 | lda $16, 7 | ||
332 | call_pal PAL_swpipl | ||
333 | br restore_all | ||
334 | |||
332 | .align 3 | 335 | .align 3 |
333 | $syscall_error: | 336 | $syscall_error: |
334 | /* | 337 | /* |
@@ -363,7 +366,7 @@ $ret_success: | |||
363 | * $8: current. | 366 | * $8: current. |
364 | * $19: The old syscall number, or zero if this is not a return | 367 | * $19: The old syscall number, or zero if this is not a return |
365 | * from a syscall that errored and is possibly restartable. | 368 | * from a syscall that errored and is possibly restartable. |
366 | * $20: Error indication. | 369 | * $20: The old a3 value |
367 | */ | 370 | */ |
368 | 371 | ||
369 | .align 4 | 372 | .align 4 |
@@ -392,12 +395,18 @@ $work_resched: | |||
392 | 395 | ||
393 | $work_notifysig: | 396 | $work_notifysig: |
394 | mov $sp, $16 | 397 | mov $sp, $16 |
395 | br $1, do_switch_stack | 398 | bsr $1, do_switch_stack |
396 | mov $sp, $17 | 399 | mov $sp, $17 |
397 | mov $5, $18 | 400 | mov $5, $18 |
401 | mov $19, $9 /* save old syscall number */ | ||
402 | mov $20, $10 /* save old a3 */ | ||
403 | and $5, _TIF_SIGPENDING, $2 | ||
404 | cmovne $2, 0, $9 /* we don't want double syscall restarts */ | ||
398 | jsr $26, do_notify_resume | 405 | jsr $26, do_notify_resume |
406 | mov $9, $19 | ||
407 | mov $10, $20 | ||
399 | bsr $1, undo_switch_stack | 408 | bsr $1, undo_switch_stack |
400 | br restore_all | 409 | br ret_to_user |
401 | .end work_pending | 410 | .end work_pending |
402 | 411 | ||
403 | /* | 412 | /* |
@@ -430,6 +439,7 @@ strace: | |||
430 | beq $1, 1f | 439 | beq $1, 1f |
431 | ldq $27, 0($2) | 440 | ldq $27, 0($2) |
432 | 1: jsr $26, ($27), sys_gettimeofday | 441 | 1: jsr $26, ($27), sys_gettimeofday |
442 | ret_from_straced: | ||
433 | ldgp $gp, 0($26) | 443 | ldgp $gp, 0($26) |
434 | 444 | ||
435 | /* check return.. */ | 445 | /* check return.. */ |
@@ -650,7 +660,7 @@ kernel_thread: | |||
650 | /* We don't actually care for a3 success widgetry in the kernel. | 660 | /* We don't actually care for a3 success widgetry in the kernel. |
651 | Not for positive errno values. */ | 661 | Not for positive errno values. */ |
652 | stq $0, 0($sp) /* $0 */ | 662 | stq $0, 0($sp) /* $0 */ |
653 | br restore_all | 663 | br ret_to_kernel |
654 | .end kernel_thread | 664 | .end kernel_thread |
655 | 665 | ||
656 | /* | 666 | /* |
@@ -757,11 +767,15 @@ sys_vfork: | |||
757 | .ent sys_sigreturn | 767 | .ent sys_sigreturn |
758 | sys_sigreturn: | 768 | sys_sigreturn: |
759 | .prologue 0 | 769 | .prologue 0 |
770 | lda $9, ret_from_straced | ||
771 | cmpult $26, $9, $9 | ||
760 | mov $sp, $17 | 772 | mov $sp, $17 |
761 | lda $18, -SWITCH_STACK_SIZE($sp) | 773 | lda $18, -SWITCH_STACK_SIZE($sp) |
762 | lda $sp, -SWITCH_STACK_SIZE($sp) | 774 | lda $sp, -SWITCH_STACK_SIZE($sp) |
763 | jsr $26, do_sigreturn | 775 | jsr $26, do_sigreturn |
764 | br $1, undo_switch_stack | 776 | bne $9, 1f |
777 | jsr $26, syscall_trace | ||
778 | 1: br $1, undo_switch_stack | ||
765 | br ret_from_sys_call | 779 | br ret_from_sys_call |
766 | .end sys_sigreturn | 780 | .end sys_sigreturn |
767 | 781 | ||
@@ -770,47 +784,19 @@ sys_sigreturn: | |||
770 | .ent sys_rt_sigreturn | 784 | .ent sys_rt_sigreturn |
771 | sys_rt_sigreturn: | 785 | sys_rt_sigreturn: |
772 | .prologue 0 | 786 | .prologue 0 |
787 | lda $9, ret_from_straced | ||
788 | cmpult $26, $9, $9 | ||
773 | mov $sp, $17 | 789 | mov $sp, $17 |
774 | lda $18, -SWITCH_STACK_SIZE($sp) | 790 | lda $18, -SWITCH_STACK_SIZE($sp) |
775 | lda $sp, -SWITCH_STACK_SIZE($sp) | 791 | lda $sp, -SWITCH_STACK_SIZE($sp) |
776 | jsr $26, do_rt_sigreturn | 792 | jsr $26, do_rt_sigreturn |
777 | br $1, undo_switch_stack | 793 | bne $9, 1f |
794 | jsr $26, syscall_trace | ||
795 | 1: br $1, undo_switch_stack | ||
778 | br ret_from_sys_call | 796 | br ret_from_sys_call |
779 | .end sys_rt_sigreturn | 797 | .end sys_rt_sigreturn |
780 | 798 | ||
781 | .align 4 | 799 | .align 4 |
782 | .globl sys_sigsuspend | ||
783 | .ent sys_sigsuspend | ||
784 | sys_sigsuspend: | ||
785 | .prologue 0 | ||
786 | mov $sp, $17 | ||
787 | br $1, do_switch_stack | ||
788 | mov $sp, $18 | ||
789 | subq $sp, 16, $sp | ||
790 | stq $26, 0($sp) | ||
791 | jsr $26, do_sigsuspend | ||
792 | ldq $26, 0($sp) | ||
793 | lda $sp, SWITCH_STACK_SIZE+16($sp) | ||
794 | ret | ||
795 | .end sys_sigsuspend | ||
796 | |||
797 | .align 4 | ||
798 | .globl sys_rt_sigsuspend | ||
799 | .ent sys_rt_sigsuspend | ||
800 | sys_rt_sigsuspend: | ||
801 | .prologue 0 | ||
802 | mov $sp, $18 | ||
803 | br $1, do_switch_stack | ||
804 | mov $sp, $19 | ||
805 | subq $sp, 16, $sp | ||
806 | stq $26, 0($sp) | ||
807 | jsr $26, do_rt_sigsuspend | ||
808 | ldq $26, 0($sp) | ||
809 | lda $sp, SWITCH_STACK_SIZE+16($sp) | ||
810 | ret | ||
811 | .end sys_rt_sigsuspend | ||
812 | |||
813 | .align 4 | ||
814 | .globl sys_sethae | 800 | .globl sys_sethae |
815 | .ent sys_sethae | 801 | .ent sys_sethae |
816 | sys_sethae: | 802 | sys_sethae: |
@@ -929,15 +915,6 @@ sys_execve: | |||
929 | .end sys_execve | 915 | .end sys_execve |
930 | 916 | ||
931 | .align 4 | 917 | .align 4 |
932 | .globl osf_sigprocmask | ||
933 | .ent osf_sigprocmask | ||
934 | osf_sigprocmask: | ||
935 | .prologue 0 | ||
936 | mov $sp, $18 | ||
937 | jmp $31, sys_osf_sigprocmask | ||
938 | .end osf_sigprocmask | ||
939 | |||
940 | .align 4 | ||
941 | .globl alpha_ni_syscall | 918 | .globl alpha_ni_syscall |
942 | .ent alpha_ni_syscall | 919 | .ent alpha_ni_syscall |
943 | alpha_ni_syscall: | 920 | alpha_ni_syscall: |
diff --git a/arch/alpha/kernel/err_ev6.c b/arch/alpha/kernel/err_ev6.c index 8ca6345bf131..253cf1a87481 100644 --- a/arch/alpha/kernel/err_ev6.c +++ b/arch/alpha/kernel/err_ev6.c | |||
@@ -90,11 +90,13 @@ static int | |||
90 | ev6_parse_cbox(u64 c_addr, u64 c1_syn, u64 c2_syn, | 90 | ev6_parse_cbox(u64 c_addr, u64 c1_syn, u64 c2_syn, |
91 | u64 c_stat, u64 c_sts, int print) | 91 | u64 c_stat, u64 c_sts, int print) |
92 | { | 92 | { |
93 | char *sourcename[] = { "UNKNOWN", "UNKNOWN", "UNKNOWN", | 93 | static const char * const sourcename[] = { |
94 | "MEMORY", "BCACHE", "DCACHE", | 94 | "UNKNOWN", "UNKNOWN", "UNKNOWN", |
95 | "BCACHE PROBE", "BCACHE PROBE" }; | 95 | "MEMORY", "BCACHE", "DCACHE", |
96 | char *streamname[] = { "D", "I" }; | 96 | "BCACHE PROBE", "BCACHE PROBE" |
97 | char *bitsname[] = { "SINGLE", "DOUBLE" }; | 97 | }; |
98 | static const char * const streamname[] = { "D", "I" }; | ||
99 | static const char * const bitsname[] = { "SINGLE", "DOUBLE" }; | ||
98 | int status = MCHK_DISPOSITION_REPORT; | 100 | int status = MCHK_DISPOSITION_REPORT; |
99 | int source = -1, stream = -1, bits = -1; | 101 | int source = -1, stream = -1, bits = -1; |
100 | 102 | ||
diff --git a/arch/alpha/kernel/err_marvel.c b/arch/alpha/kernel/err_marvel.c index 5c905aaaeccd..648ae88aeb8a 100644 --- a/arch/alpha/kernel/err_marvel.c +++ b/arch/alpha/kernel/err_marvel.c | |||
@@ -589,22 +589,23 @@ marvel_print_pox_spl_cmplt(u64 spl_cmplt) | |||
589 | static void | 589 | static void |
590 | marvel_print_pox_trans_sum(u64 trans_sum) | 590 | marvel_print_pox_trans_sum(u64 trans_sum) |
591 | { | 591 | { |
592 | char *pcix_cmd[] = { "Interrupt Acknowledge", | 592 | static const char * const pcix_cmd[] = { |
593 | "Special Cycle", | 593 | "Interrupt Acknowledge", |
594 | "I/O Read", | 594 | "Special Cycle", |
595 | "I/O Write", | 595 | "I/O Read", |
596 | "Reserved", | 596 | "I/O Write", |
597 | "Reserved / Device ID Message", | 597 | "Reserved", |
598 | "Memory Read", | 598 | "Reserved / Device ID Message", |
599 | "Memory Write", | 599 | "Memory Read", |
600 | "Reserved / Alias to Memory Read Block", | 600 | "Memory Write", |
601 | "Reserved / Alias to Memory Write Block", | 601 | "Reserved / Alias to Memory Read Block", |
602 | "Configuration Read", | 602 | "Reserved / Alias to Memory Write Block", |
603 | "Configuration Write", | 603 | "Configuration Read", |
604 | "Memory Read Multiple / Split Completion", | 604 | "Configuration Write", |
605 | "Dual Address Cycle", | 605 | "Memory Read Multiple / Split Completion", |
606 | "Memory Read Line / Memory Read Block", | 606 | "Dual Address Cycle", |
607 | "Memory Write and Invalidate / Memory Write Block" | 607 | "Memory Read Line / Memory Read Block", |
608 | "Memory Write and Invalidate / Memory Write Block" | ||
608 | }; | 609 | }; |
609 | 610 | ||
610 | #define IO7__POX_TRANSUM__PCI_ADDR__S (0) | 611 | #define IO7__POX_TRANSUM__PCI_ADDR__S (0) |
diff --git a/arch/alpha/kernel/err_titan.c b/arch/alpha/kernel/err_titan.c index f7ed97ce0dfd..c3b3781a03de 100644 --- a/arch/alpha/kernel/err_titan.c +++ b/arch/alpha/kernel/err_titan.c | |||
@@ -75,8 +75,12 @@ titan_parse_p_serror(int which, u64 serror, int print) | |||
75 | int status = MCHK_DISPOSITION_REPORT; | 75 | int status = MCHK_DISPOSITION_REPORT; |
76 | 76 | ||
77 | #ifdef CONFIG_VERBOSE_MCHECK | 77 | #ifdef CONFIG_VERBOSE_MCHECK |
78 | char *serror_src[] = {"GPCI", "APCI", "AGP HP", "AGP LP"}; | 78 | static const char * const serror_src[] = { |
79 | char *serror_cmd[] = {"DMA Read", "DMA RMW", "SGTE Read", "Reserved"}; | 79 | "GPCI", "APCI", "AGP HP", "AGP LP" |
80 | }; | ||
81 | static const char * const serror_cmd[] = { | ||
82 | "DMA Read", "DMA RMW", "SGTE Read", "Reserved" | ||
83 | }; | ||
80 | #endif /* CONFIG_VERBOSE_MCHECK */ | 84 | #endif /* CONFIG_VERBOSE_MCHECK */ |
81 | 85 | ||
82 | #define TITAN__PCHIP_SERROR__LOST_UECC (1UL << 0) | 86 | #define TITAN__PCHIP_SERROR__LOST_UECC (1UL << 0) |
@@ -140,14 +144,15 @@ titan_parse_p_perror(int which, int port, u64 perror, int print) | |||
140 | int status = MCHK_DISPOSITION_REPORT; | 144 | int status = MCHK_DISPOSITION_REPORT; |
141 | 145 | ||
142 | #ifdef CONFIG_VERBOSE_MCHECK | 146 | #ifdef CONFIG_VERBOSE_MCHECK |
143 | char *perror_cmd[] = { "Interrupt Acknowledge", "Special Cycle", | 147 | static const char * const perror_cmd[] = { |
144 | "I/O Read", "I/O Write", | 148 | "Interrupt Acknowledge", "Special Cycle", |
145 | "Reserved", "Reserved", | 149 | "I/O Read", "I/O Write", |
146 | "Memory Read", "Memory Write", | 150 | "Reserved", "Reserved", |
147 | "Reserved", "Reserved", | 151 | "Memory Read", "Memory Write", |
148 | "Configuration Read", "Configuration Write", | 152 | "Reserved", "Reserved", |
149 | "Memory Read Multiple", "Dual Address Cycle", | 153 | "Configuration Read", "Configuration Write", |
150 | "Memory Read Line","Memory Write and Invalidate" | 154 | "Memory Read Multiple", "Dual Address Cycle", |
155 | "Memory Read Line", "Memory Write and Invalidate" | ||
151 | }; | 156 | }; |
152 | #endif /* CONFIG_VERBOSE_MCHECK */ | 157 | #endif /* CONFIG_VERBOSE_MCHECK */ |
153 | 158 | ||
@@ -273,11 +278,11 @@ titan_parse_p_agperror(int which, u64 agperror, int print) | |||
273 | int cmd, len; | 278 | int cmd, len; |
274 | unsigned long addr; | 279 | unsigned long addr; |
275 | 280 | ||
276 | char *agperror_cmd[] = { "Read (low-priority)", "Read (high-priority)", | 281 | static const char * const agperror_cmd[] = { |
277 | "Write (low-priority)", | 282 | "Read (low-priority)", "Read (high-priority)", |
278 | "Write (high-priority)", | 283 | "Write (low-priority)", "Write (high-priority)", |
279 | "Reserved", "Reserved", | 284 | "Reserved", "Reserved", |
280 | "Flush", "Fence" | 285 | "Flush", "Fence" |
281 | }; | 286 | }; |
282 | #endif /* CONFIG_VERBOSE_MCHECK */ | 287 | #endif /* CONFIG_VERBOSE_MCHECK */ |
283 | 288 | ||
diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c index 5d1e6d6ce684..547e8b84b2f7 100644 --- a/arch/alpha/kernel/osf_sys.c +++ b/arch/alpha/kernel/osf_sys.c | |||
@@ -15,7 +15,6 @@ | |||
15 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
16 | #include <linux/mm.h> | 16 | #include <linux/mm.h> |
17 | #include <linux/smp.h> | 17 | #include <linux/smp.h> |
18 | #include <linux/smp_lock.h> | ||
19 | #include <linux/stddef.h> | 18 | #include <linux/stddef.h> |
20 | #include <linux/syscalls.h> | 19 | #include <linux/syscalls.h> |
21 | #include <linux/unistd.h> | 20 | #include <linux/unistd.h> |
@@ -69,7 +68,6 @@ SYSCALL_DEFINE4(osf_set_program_attributes, unsigned long, text_start, | |||
69 | { | 68 | { |
70 | struct mm_struct *mm; | 69 | struct mm_struct *mm; |
71 | 70 | ||
72 | lock_kernel(); | ||
73 | mm = current->mm; | 71 | mm = current->mm; |
74 | mm->end_code = bss_start + bss_len; | 72 | mm->end_code = bss_start + bss_len; |
75 | mm->start_brk = bss_start + bss_len; | 73 | mm->start_brk = bss_start + bss_len; |
@@ -78,7 +76,6 @@ SYSCALL_DEFINE4(osf_set_program_attributes, unsigned long, text_start, | |||
78 | printk("set_program_attributes(%lx %lx %lx %lx)\n", | 76 | printk("set_program_attributes(%lx %lx %lx %lx)\n", |
79 | text_start, text_len, bss_start, bss_len); | 77 | text_start, text_len, bss_start, bss_len); |
80 | #endif | 78 | #endif |
81 | unlock_kernel(); | ||
82 | return 0; | 79 | return 0; |
83 | } | 80 | } |
84 | 81 | ||
@@ -517,7 +514,6 @@ SYSCALL_DEFINE2(osf_proplist_syscall, enum pl_code, code, | |||
517 | long error; | 514 | long error; |
518 | int __user *min_buf_size_ptr; | 515 | int __user *min_buf_size_ptr; |
519 | 516 | ||
520 | lock_kernel(); | ||
521 | switch (code) { | 517 | switch (code) { |
522 | case PL_SET: | 518 | case PL_SET: |
523 | if (get_user(error, &args->set.nbytes)) | 519 | if (get_user(error, &args->set.nbytes)) |
@@ -547,7 +543,6 @@ SYSCALL_DEFINE2(osf_proplist_syscall, enum pl_code, code, | |||
547 | error = -EOPNOTSUPP; | 543 | error = -EOPNOTSUPP; |
548 | break; | 544 | break; |
549 | }; | 545 | }; |
550 | unlock_kernel(); | ||
551 | return error; | 546 | return error; |
552 | } | 547 | } |
553 | 548 | ||
@@ -594,7 +589,7 @@ SYSCALL_DEFINE2(osf_sigstack, struct sigstack __user *, uss, | |||
594 | 589 | ||
595 | SYSCALL_DEFINE3(osf_sysinfo, int, command, char __user *, buf, long, count) | 590 | SYSCALL_DEFINE3(osf_sysinfo, int, command, char __user *, buf, long, count) |
596 | { | 591 | { |
597 | char *sysinfo_table[] = { | 592 | const char *sysinfo_table[] = { |
598 | utsname()->sysname, | 593 | utsname()->sysname, |
599 | utsname()->nodename, | 594 | utsname()->nodename, |
600 | utsname()->release, | 595 | utsname()->release, |
@@ -606,7 +601,7 @@ SYSCALL_DEFINE3(osf_sysinfo, int, command, char __user *, buf, long, count) | |||
606 | "dummy", /* secure RPC domain */ | 601 | "dummy", /* secure RPC domain */ |
607 | }; | 602 | }; |
608 | unsigned long offset; | 603 | unsigned long offset; |
609 | char *res; | 604 | const char *res; |
610 | long len, err = -EINVAL; | 605 | long len, err = -EINVAL; |
611 | 606 | ||
612 | offset = command-1; | 607 | offset = command-1; |
diff --git a/arch/alpha/kernel/pci-sysfs.c b/arch/alpha/kernel/pci-sysfs.c index 738fc824e2ea..b899e95f79fd 100644 --- a/arch/alpha/kernel/pci-sysfs.c +++ b/arch/alpha/kernel/pci-sysfs.c | |||
@@ -66,7 +66,7 @@ static int pci_mmap_resource(struct kobject *kobj, | |||
66 | { | 66 | { |
67 | struct pci_dev *pdev = to_pci_dev(container_of(kobj, | 67 | struct pci_dev *pdev = to_pci_dev(container_of(kobj, |
68 | struct device, kobj)); | 68 | struct device, kobj)); |
69 | struct resource *res = (struct resource *)attr->private; | 69 | struct resource *res = attr->private; |
70 | enum pci_mmap_state mmap_type; | 70 | enum pci_mmap_state mmap_type; |
71 | struct pci_bus_region bar; | 71 | struct pci_bus_region bar; |
72 | int i; | 72 | int i; |
diff --git a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c index 842dba308eab..3ec35066f1dc 100644 --- a/arch/alpha/kernel/process.c +++ b/arch/alpha/kernel/process.c | |||
@@ -356,7 +356,7 @@ dump_elf_thread(elf_greg_t *dest, struct pt_regs *pt, struct thread_info *ti) | |||
356 | dest[27] = pt->r27; | 356 | dest[27] = pt->r27; |
357 | dest[28] = pt->r28; | 357 | dest[28] = pt->r28; |
358 | dest[29] = pt->gp; | 358 | dest[29] = pt->gp; |
359 | dest[30] = rdusp(); | 359 | dest[30] = ti == current_thread_info() ? rdusp() : ti->pcb.usp; |
360 | dest[31] = pt->pc; | 360 | dest[31] = pt->pc; |
361 | 361 | ||
362 | /* Once upon a time this was the PS value. Which is stupid | 362 | /* Once upon a time this was the PS value. Which is stupid |
diff --git a/arch/alpha/kernel/signal.c b/arch/alpha/kernel/signal.c index 0932dbb1ef8e..d290845aef59 100644 --- a/arch/alpha/kernel/signal.c +++ b/arch/alpha/kernel/signal.c | |||
@@ -41,46 +41,20 @@ static void do_signal(struct pt_regs *, struct switch_stack *, | |||
41 | /* | 41 | /* |
42 | * The OSF/1 sigprocmask calling sequence is different from the | 42 | * The OSF/1 sigprocmask calling sequence is different from the |
43 | * C sigprocmask() sequence.. | 43 | * C sigprocmask() sequence.. |
44 | * | ||
45 | * how: | ||
46 | * 1 - SIG_BLOCK | ||
47 | * 2 - SIG_UNBLOCK | ||
48 | * 3 - SIG_SETMASK | ||
49 | * | ||
50 | * We change the range to -1 .. 1 in order to let gcc easily | ||
51 | * use the conditional move instructions. | ||
52 | * | ||
53 | * Note that we don't need to acquire the kernel lock for SMP | ||
54 | * operation, as all of this is local to this thread. | ||
55 | */ | 44 | */ |
56 | SYSCALL_DEFINE3(osf_sigprocmask, int, how, unsigned long, newmask, | 45 | SYSCALL_DEFINE2(osf_sigprocmask, int, how, unsigned long, newmask) |
57 | struct pt_regs *, regs) | ||
58 | { | 46 | { |
59 | unsigned long oldmask = -EINVAL; | 47 | sigset_t oldmask; |
60 | 48 | sigset_t mask; | |
61 | if ((unsigned long)how-1 <= 2) { | 49 | unsigned long res; |
62 | long sign = how-2; /* -1 .. 1 */ | 50 | |
63 | unsigned long block, unblock; | 51 | siginitset(&mask, newmask & ~_BLOCKABLE); |
64 | 52 | res = sigprocmask(how, &mask, &oldmask); | |
65 | newmask &= _BLOCKABLE; | 53 | if (!res) { |
66 | spin_lock_irq(¤t->sighand->siglock); | 54 | force_successful_syscall_return(); |
67 | oldmask = current->blocked.sig[0]; | 55 | res = oldmask.sig[0]; |
68 | |||
69 | unblock = oldmask & ~newmask; | ||
70 | block = oldmask | newmask; | ||
71 | if (!sign) | ||
72 | block = unblock; | ||
73 | if (sign <= 0) | ||
74 | newmask = block; | ||
75 | if (_NSIG_WORDS > 1 && sign > 0) | ||
76 | sigemptyset(¤t->blocked); | ||
77 | current->blocked.sig[0] = newmask; | ||
78 | recalc_sigpending(); | ||
79 | spin_unlock_irq(¤t->sighand->siglock); | ||
80 | |||
81 | regs->r0 = 0; /* special no error return */ | ||
82 | } | 56 | } |
83 | return oldmask; | 57 | return res; |
84 | } | 58 | } |
85 | 59 | ||
86 | SYSCALL_DEFINE3(osf_sigaction, int, sig, | 60 | SYSCALL_DEFINE3(osf_sigaction, int, sig, |
@@ -94,9 +68,9 @@ SYSCALL_DEFINE3(osf_sigaction, int, sig, | |||
94 | old_sigset_t mask; | 68 | old_sigset_t mask; |
95 | if (!access_ok(VERIFY_READ, act, sizeof(*act)) || | 69 | if (!access_ok(VERIFY_READ, act, sizeof(*act)) || |
96 | __get_user(new_ka.sa.sa_handler, &act->sa_handler) || | 70 | __get_user(new_ka.sa.sa_handler, &act->sa_handler) || |
97 | __get_user(new_ka.sa.sa_flags, &act->sa_flags)) | 71 | __get_user(new_ka.sa.sa_flags, &act->sa_flags) || |
72 | __get_user(mask, &act->sa_mask)) | ||
98 | return -EFAULT; | 73 | return -EFAULT; |
99 | __get_user(mask, &act->sa_mask); | ||
100 | siginitset(&new_ka.sa.sa_mask, mask); | 74 | siginitset(&new_ka.sa.sa_mask, mask); |
101 | new_ka.ka_restorer = NULL; | 75 | new_ka.ka_restorer = NULL; |
102 | } | 76 | } |
@@ -106,9 +80,9 @@ SYSCALL_DEFINE3(osf_sigaction, int, sig, | |||
106 | if (!ret && oact) { | 80 | if (!ret && oact) { |
107 | if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || | 81 | if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || |
108 | __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || | 82 | __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || |
109 | __put_user(old_ka.sa.sa_flags, &oact->sa_flags)) | 83 | __put_user(old_ka.sa.sa_flags, &oact->sa_flags) || |
84 | __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask)) | ||
110 | return -EFAULT; | 85 | return -EFAULT; |
111 | __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask); | ||
112 | } | 86 | } |
113 | 87 | ||
114 | return ret; | 88 | return ret; |
@@ -144,8 +118,7 @@ SYSCALL_DEFINE5(rt_sigaction, int, sig, const struct sigaction __user *, act, | |||
144 | /* | 118 | /* |
145 | * Atomically swap in the new signal mask, and wait for a signal. | 119 | * Atomically swap in the new signal mask, and wait for a signal. |
146 | */ | 120 | */ |
147 | asmlinkage int | 121 | SYSCALL_DEFINE1(sigsuspend, old_sigset_t, mask) |
148 | do_sigsuspend(old_sigset_t mask, struct pt_regs *regs, struct switch_stack *sw) | ||
149 | { | 122 | { |
150 | mask &= _BLOCKABLE; | 123 | mask &= _BLOCKABLE; |
151 | spin_lock_irq(¤t->sighand->siglock); | 124 | spin_lock_irq(¤t->sighand->siglock); |
@@ -154,41 +127,6 @@ do_sigsuspend(old_sigset_t mask, struct pt_regs *regs, struct switch_stack *sw) | |||
154 | recalc_sigpending(); | 127 | recalc_sigpending(); |
155 | spin_unlock_irq(¤t->sighand->siglock); | 128 | spin_unlock_irq(¤t->sighand->siglock); |
156 | 129 | ||
157 | /* Indicate EINTR on return from any possible signal handler, | ||
158 | which will not come back through here, but via sigreturn. */ | ||
159 | regs->r0 = EINTR; | ||
160 | regs->r19 = 1; | ||
161 | |||
162 | current->state = TASK_INTERRUPTIBLE; | ||
163 | schedule(); | ||
164 | set_thread_flag(TIF_RESTORE_SIGMASK); | ||
165 | return -ERESTARTNOHAND; | ||
166 | } | ||
167 | |||
168 | asmlinkage int | ||
169 | do_rt_sigsuspend(sigset_t __user *uset, size_t sigsetsize, | ||
170 | struct pt_regs *regs, struct switch_stack *sw) | ||
171 | { | ||
172 | sigset_t set; | ||
173 | |||
174 | /* XXX: Don't preclude handling different sized sigset_t's. */ | ||
175 | if (sigsetsize != sizeof(sigset_t)) | ||
176 | return -EINVAL; | ||
177 | if (copy_from_user(&set, uset, sizeof(set))) | ||
178 | return -EFAULT; | ||
179 | |||
180 | sigdelsetmask(&set, ~_BLOCKABLE); | ||
181 | spin_lock_irq(¤t->sighand->siglock); | ||
182 | current->saved_sigmask = current->blocked; | ||
183 | current->blocked = set; | ||
184 | recalc_sigpending(); | ||
185 | spin_unlock_irq(¤t->sighand->siglock); | ||
186 | |||
187 | /* Indicate EINTR on return from any possible signal handler, | ||
188 | which will not come back through here, but via sigreturn. */ | ||
189 | regs->r0 = EINTR; | ||
190 | regs->r19 = 1; | ||
191 | |||
192 | current->state = TASK_INTERRUPTIBLE; | 130 | current->state = TASK_INTERRUPTIBLE; |
193 | schedule(); | 131 | schedule(); |
194 | set_thread_flag(TIF_RESTORE_SIGMASK); | 132 | set_thread_flag(TIF_RESTORE_SIGMASK); |
@@ -239,6 +177,8 @@ restore_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, | |||
239 | unsigned long usp; | 177 | unsigned long usp; |
240 | long i, err = __get_user(regs->pc, &sc->sc_pc); | 178 | long i, err = __get_user(regs->pc, &sc->sc_pc); |
241 | 179 | ||
180 | current_thread_info()->restart_block.fn = do_no_restart_syscall; | ||
181 | |||
242 | sw->r26 = (unsigned long) ret_from_sys_call; | 182 | sw->r26 = (unsigned long) ret_from_sys_call; |
243 | 183 | ||
244 | err |= __get_user(regs->r0, sc->sc_regs+0); | 184 | err |= __get_user(regs->r0, sc->sc_regs+0); |
@@ -591,7 +531,6 @@ syscall_restart(unsigned long r0, unsigned long r19, | |||
591 | regs->pc -= 4; | 531 | regs->pc -= 4; |
592 | break; | 532 | break; |
593 | case ERESTART_RESTARTBLOCK: | 533 | case ERESTART_RESTARTBLOCK: |
594 | current_thread_info()->restart_block.fn = do_no_restart_syscall; | ||
595 | regs->r0 = EINTR; | 534 | regs->r0 = EINTR; |
596 | break; | 535 | break; |
597 | } | 536 | } |
diff --git a/arch/alpha/kernel/srm_env.c b/arch/alpha/kernel/srm_env.c index 4afc1a1e2e5a..f0df3fbd8402 100644 --- a/arch/alpha/kernel/srm_env.c +++ b/arch/alpha/kernel/srm_env.c | |||
@@ -87,7 +87,7 @@ static int srm_env_proc_show(struct seq_file *m, void *v) | |||
87 | srm_env_t *entry; | 87 | srm_env_t *entry; |
88 | char *page; | 88 | char *page; |
89 | 89 | ||
90 | entry = (srm_env_t *)m->private; | 90 | entry = m->private; |
91 | page = (char *)__get_free_page(GFP_USER); | 91 | page = (char *)__get_free_page(GFP_USER); |
92 | if (!page) | 92 | if (!page) |
93 | return -ENOMEM; | 93 | return -ENOMEM; |
diff --git a/arch/alpha/kernel/systbls.S b/arch/alpha/kernel/systbls.S index 09acb786e72b..a6a1de9db16f 100644 --- a/arch/alpha/kernel/systbls.S +++ b/arch/alpha/kernel/systbls.S | |||
@@ -58,7 +58,7 @@ sys_call_table: | |||
58 | .quad sys_open /* 45 */ | 58 | .quad sys_open /* 45 */ |
59 | .quad alpha_ni_syscall | 59 | .quad alpha_ni_syscall |
60 | .quad sys_getxgid | 60 | .quad sys_getxgid |
61 | .quad osf_sigprocmask | 61 | .quad sys_osf_sigprocmask |
62 | .quad alpha_ni_syscall | 62 | .quad alpha_ni_syscall |
63 | .quad alpha_ni_syscall /* 50 */ | 63 | .quad alpha_ni_syscall /* 50 */ |
64 | .quad sys_acct | 64 | .quad sys_acct |
@@ -512,6 +512,9 @@ sys_call_table: | |||
512 | .quad sys_pwritev | 512 | .quad sys_pwritev |
513 | .quad sys_rt_tgsigqueueinfo | 513 | .quad sys_rt_tgsigqueueinfo |
514 | .quad sys_perf_event_open | 514 | .quad sys_perf_event_open |
515 | .quad sys_fanotify_init | ||
516 | .quad sys_fanotify_mark /* 495 */ | ||
517 | .quad sys_prlimit64 | ||
515 | 518 | ||
516 | .size sys_call_table, . - sys_call_table | 519 | .size sys_call_table, . - sys_call_table |
517 | .type sys_call_table, @object | 520 | .type sys_call_table, @object |
diff --git a/arch/alpha/kernel/time.c b/arch/alpha/kernel/time.c index eacceb26d9c8..396af1799ea4 100644 --- a/arch/alpha/kernel/time.c +++ b/arch/alpha/kernel/time.c | |||
@@ -191,16 +191,16 @@ irqreturn_t timer_interrupt(int irq, void *dev) | |||
191 | 191 | ||
192 | write_sequnlock(&xtime_lock); | 192 | write_sequnlock(&xtime_lock); |
193 | 193 | ||
194 | #ifndef CONFIG_SMP | ||
195 | while (nticks--) | ||
196 | update_process_times(user_mode(get_irq_regs())); | ||
197 | #endif | ||
198 | |||
199 | if (test_perf_event_pending()) { | 194 | if (test_perf_event_pending()) { |
200 | clear_perf_event_pending(); | 195 | clear_perf_event_pending(); |
201 | perf_event_do_pending(); | 196 | perf_event_do_pending(); |
202 | } | 197 | } |
203 | 198 | ||
199 | #ifndef CONFIG_SMP | ||
200 | while (nticks--) | ||
201 | update_process_times(user_mode(get_irq_regs())); | ||
202 | #endif | ||
203 | |||
204 | return IRQ_HANDLED; | 204 | return IRQ_HANDLED; |
205 | } | 205 | } |
206 | 206 | ||
diff --git a/arch/alpha/kernel/traps.c b/arch/alpha/kernel/traps.c index b14f015008ad..0414e021a91c 100644 --- a/arch/alpha/kernel/traps.c +++ b/arch/alpha/kernel/traps.c | |||
@@ -13,7 +13,6 @@ | |||
13 | #include <linux/sched.h> | 13 | #include <linux/sched.h> |
14 | #include <linux/tty.h> | 14 | #include <linux/tty.h> |
15 | #include <linux/delay.h> | 15 | #include <linux/delay.h> |
16 | #include <linux/smp_lock.h> | ||
17 | #include <linux/module.h> | 16 | #include <linux/module.h> |
18 | #include <linux/init.h> | 17 | #include <linux/init.h> |
19 | #include <linux/kallsyms.h> | 18 | #include <linux/kallsyms.h> |
@@ -623,7 +622,6 @@ do_entUna(void * va, unsigned long opcode, unsigned long reg, | |||
623 | return; | 622 | return; |
624 | } | 623 | } |
625 | 624 | ||
626 | lock_kernel(); | ||
627 | printk("Bad unaligned kernel access at %016lx: %p %lx %lu\n", | 625 | printk("Bad unaligned kernel access at %016lx: %p %lx %lu\n", |
628 | pc, va, opcode, reg); | 626 | pc, va, opcode, reg); |
629 | do_exit(SIGSEGV); | 627 | do_exit(SIGSEGV); |
@@ -646,7 +644,6 @@ got_exception: | |||
646 | * Yikes! No one to forward the exception to. | 644 | * Yikes! No one to forward the exception to. |
647 | * Since the registers are in a weird format, dump them ourselves. | 645 | * Since the registers are in a weird format, dump them ourselves. |
648 | */ | 646 | */ |
649 | lock_kernel(); | ||
650 | 647 | ||
651 | printk("%s(%d): unhandled unaligned exception\n", | 648 | printk("%s(%d): unhandled unaligned exception\n", |
652 | current->comm, task_pid_nr(current)); | 649 | current->comm, task_pid_nr(current)); |
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 553b7cf17bfb..b404e5eec0c1 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
@@ -19,6 +19,8 @@ config ARM | |||
19 | select HAVE_KPROBES if (!XIP_KERNEL) | 19 | select HAVE_KPROBES if (!XIP_KERNEL) |
20 | select HAVE_KRETPROBES if (HAVE_KPROBES) | 20 | select HAVE_KRETPROBES if (HAVE_KPROBES) |
21 | select HAVE_FUNCTION_TRACER if (!XIP_KERNEL) | 21 | select HAVE_FUNCTION_TRACER if (!XIP_KERNEL) |
22 | select HAVE_FTRACE_MCOUNT_RECORD if (!XIP_KERNEL) | ||
23 | select HAVE_DYNAMIC_FTRACE if (!XIP_KERNEL) | ||
22 | select HAVE_GENERIC_DMA_COHERENT | 24 | select HAVE_GENERIC_DMA_COHERENT |
23 | select HAVE_KERNEL_GZIP | 25 | select HAVE_KERNEL_GZIP |
24 | select HAVE_KERNEL_LZO | 26 | select HAVE_KERNEL_LZO |
@@ -26,6 +28,7 @@ config ARM | |||
26 | select HAVE_PERF_EVENTS | 28 | select HAVE_PERF_EVENTS |
27 | select PERF_USE_VMALLOC | 29 | select PERF_USE_VMALLOC |
28 | select HAVE_REGS_AND_STACK_ACCESS_API | 30 | select HAVE_REGS_AND_STACK_ACCESS_API |
31 | select HAVE_HW_BREAKPOINT if (PERF_EVENTS && (CPU_V6 || CPU_V7)) | ||
29 | help | 32 | help |
30 | The ARM series is a line of low-power-consumption RISC chip designs | 33 | The ARM series is a line of low-power-consumption RISC chip designs |
31 | licensed by ARM Ltd and targeted at embedded applications and | 34 | licensed by ARM Ltd and targeted at embedded applications and |
@@ -145,6 +148,9 @@ config ARCH_HAS_CPUFREQ | |||
145 | and that the relevant menu configurations are displayed for | 148 | and that the relevant menu configurations are displayed for |
146 | it. | 149 | it. |
147 | 150 | ||
151 | config ARCH_HAS_CPU_IDLE_WAIT | ||
152 | def_bool y | ||
153 | |||
148 | config GENERIC_HWEIGHT | 154 | config GENERIC_HWEIGHT |
149 | bool | 155 | bool |
150 | default y | 156 | default y |
@@ -271,7 +277,6 @@ config ARCH_AT91 | |||
271 | bool "Atmel AT91" | 277 | bool "Atmel AT91" |
272 | select ARCH_REQUIRE_GPIOLIB | 278 | select ARCH_REQUIRE_GPIOLIB |
273 | select HAVE_CLK | 279 | select HAVE_CLK |
274 | select ARCH_USES_GETTIMEOFFSET | ||
275 | help | 280 | help |
276 | This enables support for systems based on the Atmel AT91RM9200, | 281 | This enables support for systems based on the Atmel AT91RM9200, |
277 | AT91SAM9 and AT91CAP9 processors. | 282 | AT91SAM9 and AT91CAP9 processors. |
@@ -1003,7 +1008,7 @@ endif | |||
1003 | 1008 | ||
1004 | config ARM_ERRATA_411920 | 1009 | config ARM_ERRATA_411920 |
1005 | bool "ARM errata: Invalidation of the Instruction Cache operation can fail" | 1010 | bool "ARM errata: Invalidation of the Instruction Cache operation can fail" |
1006 | depends on CPU_V6 && !SMP | 1011 | depends on CPU_V6 |
1007 | help | 1012 | help |
1008 | Invalidation of the Instruction Cache operation can | 1013 | Invalidation of the Instruction Cache operation can |
1009 | fail. This erratum is present in 1136 (before r1p4), 1156 and 1176. | 1014 | fail. This erratum is present in 1136 (before r1p4), 1156 and 1176. |
@@ -1051,6 +1056,32 @@ config ARM_ERRATA_460075 | |||
1051 | ACTLR register. Note that setting specific bits in the ACTLR register | 1056 | ACTLR register. Note that setting specific bits in the ACTLR register |
1052 | may not be available in non-secure mode. | 1057 | may not be available in non-secure mode. |
1053 | 1058 | ||
1059 | config ARM_ERRATA_742230 | ||
1060 | bool "ARM errata: DMB operation may be faulty" | ||
1061 | depends on CPU_V7 && SMP | ||
1062 | help | ||
1063 | This option enables the workaround for the 742230 Cortex-A9 | ||
1064 | (r1p0..r2p2) erratum. Under rare circumstances, a DMB instruction | ||
1065 | between two write operations may not ensure the correct visibility | ||
1066 | ordering of the two writes. This workaround sets a specific bit in | ||
1067 | the diagnostic register of the Cortex-A9 which causes the DMB | ||
1068 | instruction to behave as a DSB, ensuring the correct behaviour of | ||
1069 | the two writes. | ||
1070 | |||
1071 | config ARM_ERRATA_742231 | ||
1072 | bool "ARM errata: Incorrect hazard handling in the SCU may lead to data corruption" | ||
1073 | depends on CPU_V7 && SMP | ||
1074 | help | ||
1075 | This option enables the workaround for the 742231 Cortex-A9 | ||
1076 | (r2p0..r2p2) erratum. Under certain conditions, specific to the | ||
1077 | Cortex-A9 MPCore micro-architecture, two CPUs working in SMP mode, | ||
1078 | accessing some data located in the same cache line, may get corrupted | ||
1079 | data due to bad handling of the address hazard when the line gets | ||
1080 | replaced from one of the CPUs at the same time as another CPU is | ||
1081 | accessing it. This workaround sets specific bits in the diagnostic | ||
1082 | register of the Cortex-A9 which reduces the linefill issuing | ||
1083 | capabilities of the processor. | ||
1084 | |||
1054 | config PL310_ERRATA_588369 | 1085 | config PL310_ERRATA_588369 |
1055 | bool "Clean & Invalidate maintenance operations do not invalidate clean lines" | 1086 | bool "Clean & Invalidate maintenance operations do not invalidate clean lines" |
1056 | depends on CACHE_L2X0 && ARCH_OMAP4 | 1087 | depends on CACHE_L2X0 && ARCH_OMAP4 |
@@ -1142,13 +1173,13 @@ source "kernel/time/Kconfig" | |||
1142 | 1173 | ||
1143 | config SMP | 1174 | config SMP |
1144 | bool "Symmetric Multi-Processing (EXPERIMENTAL)" | 1175 | bool "Symmetric Multi-Processing (EXPERIMENTAL)" |
1145 | depends on EXPERIMENTAL && (REALVIEW_EB_ARM11MP || REALVIEW_EB_A9MP ||\ | 1176 | depends on EXPERIMENTAL |
1146 | MACH_REALVIEW_PB11MP || MACH_REALVIEW_PBX || ARCH_OMAP4 ||\ | ||
1147 | ARCH_S5PV310 || ARCH_TEGRA || ARCH_U8500 || ARCH_VEXPRESS_CA9X4) | ||
1148 | depends on GENERIC_CLOCKEVENTS | 1177 | depends on GENERIC_CLOCKEVENTS |
1178 | depends on REALVIEW_EB_ARM11MP || REALVIEW_EB_A9MP || \ | ||
1179 | MACH_REALVIEW_PB11MP || MACH_REALVIEW_PBX || ARCH_OMAP4 ||\ | ||
1180 | ARCH_S5PV310 || ARCH_TEGRA || ARCH_U8500 || ARCH_VEXPRESS_CA9X4 | ||
1149 | select USE_GENERIC_SMP_HELPERS | 1181 | select USE_GENERIC_SMP_HELPERS |
1150 | select HAVE_ARM_SCU if ARCH_REALVIEW || ARCH_OMAP4 || ARCH_S5PV310 ||\ | 1182 | select HAVE_ARM_SCU |
1151 | ARCH_TEGRA || ARCH_U8500 || ARCH_VEXPRESS_CA9X4 | ||
1152 | help | 1183 | help |
1153 | This enables support for systems with more than one CPU. If you have | 1184 | This enables support for systems with more than one CPU. If you have |
1154 | a system with only one CPU, like most personal computers, say N. If | 1185 | a system with only one CPU, like most personal computers, say N. If |
@@ -1166,6 +1197,19 @@ config SMP | |||
1166 | 1197 | ||
1167 | If you don't know what to do here, say N. | 1198 | If you don't know what to do here, say N. |
1168 | 1199 | ||
1200 | config SMP_ON_UP | ||
1201 | bool "Allow booting SMP kernel on uniprocessor systems (EXPERIMENTAL)" | ||
1202 | depends on EXPERIMENTAL | ||
1203 | depends on SMP && !XIP && !THUMB2_KERNEL | ||
1204 | default y | ||
1205 | help | ||
1206 | SMP kernels contain instructions which fail on non-SMP processors. | ||
1207 | Enabling this option allows the kernel to modify itself to make | ||
1208 | these instructions safe. Disabling it allows about 1K of space | ||
1209 | savings. | ||
1210 | |||
1211 | If you don't know what to do here, say Y. | ||
1212 | |||
1169 | config HAVE_ARM_SCU | 1213 | config HAVE_ARM_SCU |
1170 | bool | 1214 | bool |
1171 | depends on SMP | 1215 | depends on SMP |
@@ -1216,12 +1260,9 @@ config HOTPLUG_CPU | |||
1216 | 1260 | ||
1217 | config LOCAL_TIMERS | 1261 | config LOCAL_TIMERS |
1218 | bool "Use local timer interrupts" | 1262 | bool "Use local timer interrupts" |
1219 | depends on SMP && (REALVIEW_EB_ARM11MP || MACH_REALVIEW_PB11MP || \ | 1263 | depends on SMP |
1220 | REALVIEW_EB_A9MP || MACH_REALVIEW_PBX || ARCH_OMAP4 || \ | ||
1221 | ARCH_S5PV310 || ARCH_TEGRA || ARCH_U8500 || ARCH_VEXPRESS_CA9X4) | ||
1222 | default y | 1264 | default y |
1223 | select HAVE_ARM_TWD if ARCH_REALVIEW || ARCH_OMAP4 || ARCH_S5PV310 || \ | 1265 | select HAVE_ARM_TWD |
1224 | ARCH_TEGRA || ARCH_U8500 || ARCH_VEXPRESS | ||
1225 | help | 1266 | help |
1226 | Enable support for local timers on SMP platforms, rather then the | 1267 | Enable support for local timers on SMP platforms, rather then the |
1227 | legacy IPI broadcast method. Local timers allows the system | 1268 | legacy IPI broadcast method. Local timers allows the system |
diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug index 91344af75f39..4dbce538fec4 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug | |||
@@ -27,6 +27,11 @@ config ARM_UNWIND | |||
27 | the performance is not affected. Currently, this feature | 27 | the performance is not affected. Currently, this feature |
28 | only works with EABI compilers. If unsure say Y. | 28 | only works with EABI compilers. If unsure say Y. |
29 | 29 | ||
30 | config OLD_MCOUNT | ||
31 | bool | ||
32 | depends on FUNCTION_TRACER && FRAME_POINTER | ||
33 | default y | ||
34 | |||
30 | config DEBUG_USER | 35 | config DEBUG_USER |
31 | bool "Verbose user fault messages" | 36 | bool "Verbose user fault messages" |
32 | help | 37 | help |
diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile index b23f6bc46cfa..65a7c1c588a9 100644 --- a/arch/arm/boot/compressed/Makefile +++ b/arch/arm/boot/compressed/Makefile | |||
@@ -116,5 +116,5 @@ CFLAGS_font.o := -Dstatic= | |||
116 | $(obj)/font.c: $(FONTC) | 116 | $(obj)/font.c: $(FONTC) |
117 | $(call cmd,shipped) | 117 | $(call cmd,shipped) |
118 | 118 | ||
119 | $(obj)/vmlinux.lds: $(obj)/vmlinux.lds.in arch/arm/boot/Makefile .config | 119 | $(obj)/vmlinux.lds: $(obj)/vmlinux.lds.in arch/arm/boot/Makefile $(KCONFIG_CONFIG) |
120 | @sed "$(SEDFLAGS)" < $< > $@ | 120 | @sed "$(SEDFLAGS)" < $< > $@ |
diff --git a/arch/arm/common/it8152.c b/arch/arm/common/it8152.c index 7974baacafce..1bec96e85196 100644 --- a/arch/arm/common/it8152.c +++ b/arch/arm/common/it8152.c | |||
@@ -271,6 +271,14 @@ int dma_needs_bounce(struct device *dev, dma_addr_t dma_addr, size_t size) | |||
271 | ((dma_addr + size - PHYS_OFFSET) >= SZ_64M); | 271 | ((dma_addr + size - PHYS_OFFSET) >= SZ_64M); |
272 | } | 272 | } |
273 | 273 | ||
274 | int dma_set_coherent_mask(struct device *dev, u64 mask) | ||
275 | { | ||
276 | if (mask >= PHYS_OFFSET + SZ_64M - 1) | ||
277 | return 0; | ||
278 | |||
279 | return -EIO; | ||
280 | } | ||
281 | |||
274 | int __init it8152_pci_setup(int nr, struct pci_sys_data *sys) | 282 | int __init it8152_pci_setup(int nr, struct pci_sys_data *sys) |
275 | { | 283 | { |
276 | it8152_io.start = IT8152_IO_BASE + 0x12000; | 284 | it8152_io.start = IT8152_IO_BASE + 0x12000; |
diff --git a/arch/arm/common/pl330.c b/arch/arm/common/pl330.c index 5ebbab6242a7..8f0f86db3602 100644 --- a/arch/arm/common/pl330.c +++ b/arch/arm/common/pl330.c | |||
@@ -146,8 +146,7 @@ | |||
146 | #define DESIGNER 0x41 | 146 | #define DESIGNER 0x41 |
147 | #define REVISION 0x0 | 147 | #define REVISION 0x0 |
148 | #define INTEG_CFG 0x0 | 148 | #define INTEG_CFG 0x0 |
149 | #define PERIPH_ID_VAL ((PART << 0) | (DESIGNER << 12) \ | 149 | #define PERIPH_ID_VAL ((PART << 0) | (DESIGNER << 12)) |
150 | | (REVISION << 20) | (INTEG_CFG << 24)) | ||
151 | 150 | ||
152 | #define PCELL_ID_VAL 0xb105f00d | 151 | #define PCELL_ID_VAL 0xb105f00d |
153 | 152 | ||
@@ -1859,10 +1858,10 @@ int pl330_add(struct pl330_info *pi) | |||
1859 | regs = pi->base; | 1858 | regs = pi->base; |
1860 | 1859 | ||
1861 | /* Check if we can handle this DMAC */ | 1860 | /* Check if we can handle this DMAC */ |
1862 | if (get_id(pi, PERIPH_ID) != PERIPH_ID_VAL | 1861 | if ((get_id(pi, PERIPH_ID) & 0xfffff) != PERIPH_ID_VAL |
1863 | || get_id(pi, PCELL_ID) != PCELL_ID_VAL) { | 1862 | || get_id(pi, PCELL_ID) != PCELL_ID_VAL) { |
1864 | dev_err(pi->dev, "PERIPH_ID 0x%x, PCELL_ID 0x%x !\n", | 1863 | dev_err(pi->dev, "PERIPH_ID 0x%x, PCELL_ID 0x%x !\n", |
1865 | readl(regs + PERIPH_ID), readl(regs + PCELL_ID)); | 1864 | get_id(pi, PERIPH_ID), get_id(pi, PCELL_ID)); |
1866 | return -EINVAL; | 1865 | return -EINVAL; |
1867 | } | 1866 | } |
1868 | 1867 | ||
diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c index 517d50ddbeb3..c0258a8c103b 100644 --- a/arch/arm/common/sa1111.c +++ b/arch/arm/common/sa1111.c | |||
@@ -678,7 +678,7 @@ out: | |||
678 | * %-EBUSY physical address already marked in-use. | 678 | * %-EBUSY physical address already marked in-use. |
679 | * %0 successful. | 679 | * %0 successful. |
680 | */ | 680 | */ |
681 | static int | 681 | static int __devinit |
682 | __sa1111_probe(struct device *me, struct resource *mem, int irq) | 682 | __sa1111_probe(struct device *me, struct resource *mem, int irq) |
683 | { | 683 | { |
684 | struct sa1111 *sachip; | 684 | struct sa1111 *sachip; |
diff --git a/arch/arm/configs/realview-smp_defconfig b/arch/arm/configs/realview-smp_defconfig index 9312ef9f9bf4..5ca7a61f7c01 100644 --- a/arch/arm/configs/realview-smp_defconfig +++ b/arch/arm/configs/realview-smp_defconfig | |||
@@ -39,6 +39,7 @@ CONFIG_MTD_CFI=y | |||
39 | CONFIG_MTD_CFI_INTELEXT=y | 39 | CONFIG_MTD_CFI_INTELEXT=y |
40 | CONFIG_MTD_CFI_AMDSTD=y | 40 | CONFIG_MTD_CFI_AMDSTD=y |
41 | CONFIG_MTD_ARM_INTEGRATOR=y | 41 | CONFIG_MTD_ARM_INTEGRATOR=y |
42 | CONFIG_ARM_CHARLCD=y | ||
42 | CONFIG_NETDEVICES=y | 43 | CONFIG_NETDEVICES=y |
43 | CONFIG_SMSC_PHY=y | 44 | CONFIG_SMSC_PHY=y |
44 | CONFIG_NET_ETHERNET=y | 45 | CONFIG_NET_ETHERNET=y |
@@ -52,10 +53,13 @@ CONFIG_SERIAL_AMBA_PL011=y | |||
52 | CONFIG_SERIAL_AMBA_PL011_CONSOLE=y | 53 | CONFIG_SERIAL_AMBA_PL011_CONSOLE=y |
53 | CONFIG_LEGACY_PTY_COUNT=16 | 54 | CONFIG_LEGACY_PTY_COUNT=16 |
54 | # CONFIG_HW_RANDOM is not set | 55 | # CONFIG_HW_RANDOM is not set |
56 | CONFIG_I2C=y | ||
57 | CONFIG_I2C_VERSATILE=y | ||
58 | CONFIG_SPI=y | ||
59 | CONFIG_GPIOLIB=y | ||
55 | # CONFIG_HWMON is not set | 60 | # CONFIG_HWMON is not set |
56 | CONFIG_FB=y | 61 | CONFIG_FB=y |
57 | CONFIG_FB_ARMCLCD=y | 62 | CONFIG_FB_ARMCLCD=y |
58 | # CONFIG_VGA_CONSOLE is not set | ||
59 | CONFIG_FRAMEBUFFER_CONSOLE=y | 63 | CONFIG_FRAMEBUFFER_CONSOLE=y |
60 | CONFIG_LOGO=y | 64 | CONFIG_LOGO=y |
61 | # CONFIG_LOGO_LINUX_MONO is not set | 65 | # CONFIG_LOGO_LINUX_MONO is not set |
@@ -70,7 +74,13 @@ CONFIG_SND_ARMAACI=y | |||
70 | # CONFIG_USB_SUPPORT is not set | 74 | # CONFIG_USB_SUPPORT is not set |
71 | CONFIG_MMC=y | 75 | CONFIG_MMC=y |
72 | CONFIG_MMC_ARMMMCI=y | 76 | CONFIG_MMC_ARMMMCI=y |
73 | CONFIG_INOTIFY=y | 77 | CONFIG_NEW_LEDS=y |
78 | CONFIG_LEDS_CLASS=y | ||
79 | CONFIG_LEDS_TRIGGERS=y | ||
80 | CONFIG_LEDS_TRIGGER_HEARTBEAT=y | ||
81 | CONFIG_RTC_CLASS=y | ||
82 | CONFIG_RTC_DRV_DS1307=y | ||
83 | CONFIG_RTC_DRV_PL031=y | ||
74 | CONFIG_VFAT_FS=y | 84 | CONFIG_VFAT_FS=y |
75 | CONFIG_TMPFS=y | 85 | CONFIG_TMPFS=y |
76 | CONFIG_CRAMFS=y | 86 | CONFIG_CRAMFS=y |
@@ -80,6 +90,7 @@ CONFIG_ROOT_NFS=y | |||
80 | CONFIG_NLS_CODEPAGE_437=y | 90 | CONFIG_NLS_CODEPAGE_437=y |
81 | CONFIG_NLS_ISO8859_1=y | 91 | CONFIG_NLS_ISO8859_1=y |
82 | CONFIG_MAGIC_SYSRQ=y | 92 | CONFIG_MAGIC_SYSRQ=y |
93 | CONFIG_DEBUG_FS=y | ||
83 | CONFIG_DEBUG_KERNEL=y | 94 | CONFIG_DEBUG_KERNEL=y |
84 | # CONFIG_SCHED_DEBUG is not set | 95 | # CONFIG_SCHED_DEBUG is not set |
85 | # CONFIG_RCU_CPU_STALL_DETECTOR is not set | 96 | # CONFIG_RCU_CPU_STALL_DETECTOR is not set |
diff --git a/arch/arm/configs/realview_defconfig b/arch/arm/configs/realview_defconfig index fb75192ee7e5..fcaa60328051 100644 --- a/arch/arm/configs/realview_defconfig +++ b/arch/arm/configs/realview_defconfig | |||
@@ -38,6 +38,7 @@ CONFIG_MTD_CFI=y | |||
38 | CONFIG_MTD_CFI_INTELEXT=y | 38 | CONFIG_MTD_CFI_INTELEXT=y |
39 | CONFIG_MTD_CFI_AMDSTD=y | 39 | CONFIG_MTD_CFI_AMDSTD=y |
40 | CONFIG_MTD_ARM_INTEGRATOR=y | 40 | CONFIG_MTD_ARM_INTEGRATOR=y |
41 | CONFIG_ARM_CHARLCD=y | ||
41 | CONFIG_NETDEVICES=y | 42 | CONFIG_NETDEVICES=y |
42 | CONFIG_SMSC_PHY=y | 43 | CONFIG_SMSC_PHY=y |
43 | CONFIG_NET_ETHERNET=y | 44 | CONFIG_NET_ETHERNET=y |
@@ -51,10 +52,13 @@ CONFIG_SERIAL_AMBA_PL011=y | |||
51 | CONFIG_SERIAL_AMBA_PL011_CONSOLE=y | 52 | CONFIG_SERIAL_AMBA_PL011_CONSOLE=y |
52 | CONFIG_LEGACY_PTY_COUNT=16 | 53 | CONFIG_LEGACY_PTY_COUNT=16 |
53 | # CONFIG_HW_RANDOM is not set | 54 | # CONFIG_HW_RANDOM is not set |
55 | CONFIG_I2C=y | ||
56 | CONFIG_I2C_VERSATILE=y | ||
57 | CONFIG_SPI=y | ||
58 | CONFIG_GPIOLIB=y | ||
54 | # CONFIG_HWMON is not set | 59 | # CONFIG_HWMON is not set |
55 | CONFIG_FB=y | 60 | CONFIG_FB=y |
56 | CONFIG_FB_ARMCLCD=y | 61 | CONFIG_FB_ARMCLCD=y |
57 | # CONFIG_VGA_CONSOLE is not set | ||
58 | CONFIG_FRAMEBUFFER_CONSOLE=y | 62 | CONFIG_FRAMEBUFFER_CONSOLE=y |
59 | CONFIG_LOGO=y | 63 | CONFIG_LOGO=y |
60 | # CONFIG_LOGO_LINUX_MONO is not set | 64 | # CONFIG_LOGO_LINUX_MONO is not set |
@@ -69,7 +73,13 @@ CONFIG_SND_ARMAACI=y | |||
69 | # CONFIG_USB_SUPPORT is not set | 73 | # CONFIG_USB_SUPPORT is not set |
70 | CONFIG_MMC=y | 74 | CONFIG_MMC=y |
71 | CONFIG_MMC_ARMMMCI=y | 75 | CONFIG_MMC_ARMMMCI=y |
72 | CONFIG_INOTIFY=y | 76 | CONFIG_NEW_LEDS=y |
77 | CONFIG_LEDS_CLASS=y | ||
78 | CONFIG_LEDS_TRIGGERS=y | ||
79 | CONFIG_LEDS_TRIGGER_HEARTBEAT=y | ||
80 | CONFIG_RTC_CLASS=y | ||
81 | CONFIG_RTC_DRV_DS1307=y | ||
82 | CONFIG_RTC_DRV_PL031=y | ||
73 | CONFIG_VFAT_FS=y | 83 | CONFIG_VFAT_FS=y |
74 | CONFIG_TMPFS=y | 84 | CONFIG_TMPFS=y |
75 | CONFIG_CRAMFS=y | 85 | CONFIG_CRAMFS=y |
@@ -79,6 +89,7 @@ CONFIG_ROOT_NFS=y | |||
79 | CONFIG_NLS_CODEPAGE_437=y | 89 | CONFIG_NLS_CODEPAGE_437=y |
80 | CONFIG_NLS_ISO8859_1=y | 90 | CONFIG_NLS_ISO8859_1=y |
81 | CONFIG_MAGIC_SYSRQ=y | 91 | CONFIG_MAGIC_SYSRQ=y |
92 | CONFIG_DEBUG_FS=y | ||
82 | CONFIG_DEBUG_KERNEL=y | 93 | CONFIG_DEBUG_KERNEL=y |
83 | # CONFIG_SCHED_DEBUG is not set | 94 | # CONFIG_SCHED_DEBUG is not set |
84 | # CONFIG_RCU_CPU_STALL_DETECTOR is not set | 95 | # CONFIG_RCU_CPU_STALL_DETECTOR is not set |
diff --git a/arch/arm/configs/u300_defconfig b/arch/arm/configs/u300_defconfig index 46e5e0747269..c1c252cdca60 100644 --- a/arch/arm/configs/u300_defconfig +++ b/arch/arm/configs/u300_defconfig | |||
@@ -28,26 +28,9 @@ CONFIG_CPU_IDLE=y | |||
28 | CONFIG_FPE_NWFPE=y | 28 | CONFIG_FPE_NWFPE=y |
29 | CONFIG_PM=y | 29 | CONFIG_PM=y |
30 | # CONFIG_SUSPEND is not set | 30 | # CONFIG_SUSPEND is not set |
31 | CONFIG_NET=y | ||
32 | CONFIG_PACKET=y | ||
33 | CONFIG_UNIX=y | ||
34 | CONFIG_INET=y | ||
35 | # CONFIG_INET_XFRM_MODE_TRANSPORT is not set | ||
36 | # CONFIG_INET_XFRM_MODE_TUNNEL is not set | ||
37 | # CONFIG_INET_XFRM_MODE_BEET is not set | ||
38 | # CONFIG_INET_LRO is not set | ||
39 | # CONFIG_INET_DIAG is not set | ||
40 | # CONFIG_IPV6 is not set | ||
41 | # CONFIG_WIRELESS is not set | ||
42 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | 31 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" |
43 | # CONFIG_PREVENT_FIRMWARE_BUILD is not set | 32 | # CONFIG_PREVENT_FIRMWARE_BUILD is not set |
44 | CONFIG_MTD=y | 33 | # CONFIG_MISC_DEVICES is not set |
45 | CONFIG_MTD_PARTITIONS=y | ||
46 | CONFIG_MTD_CMDLINE_PARTS=y | ||
47 | CONFIG_MTD_CHAR=y | ||
48 | CONFIG_MTD_BLOCK=y | ||
49 | CONFIG_MTD_NAND=y | ||
50 | CONFIG_MTD_NAND_ECC_SMC=y | ||
51 | # CONFIG_INPUT_MOUSEDEV is not set | 34 | # CONFIG_INPUT_MOUSEDEV is not set |
52 | CONFIG_INPUT_EVDEV=y | 35 | CONFIG_INPUT_EVDEV=y |
53 | # CONFIG_KEYBOARD_ATKBD is not set | 36 | # CONFIG_KEYBOARD_ATKBD is not set |
@@ -58,7 +41,6 @@ CONFIG_SERIAL_AMBA_PL011_CONSOLE=y | |||
58 | CONFIG_LEGACY_PTY_COUNT=16 | 41 | CONFIG_LEGACY_PTY_COUNT=16 |
59 | # CONFIG_HW_RANDOM is not set | 42 | # CONFIG_HW_RANDOM is not set |
60 | CONFIG_I2C=y | 43 | CONFIG_I2C=y |
61 | CONFIG_POWER_SUPPLY=y | ||
62 | # CONFIG_HWMON is not set | 44 | # CONFIG_HWMON is not set |
63 | CONFIG_WATCHDOG=y | 45 | CONFIG_WATCHDOG=y |
64 | CONFIG_REGULATOR=y | 46 | CONFIG_REGULATOR=y |
@@ -66,24 +48,10 @@ CONFIG_FB=y | |||
66 | CONFIG_BACKLIGHT_LCD_SUPPORT=y | 48 | CONFIG_BACKLIGHT_LCD_SUPPORT=y |
67 | # CONFIG_LCD_CLASS_DEVICE is not set | 49 | # CONFIG_LCD_CLASS_DEVICE is not set |
68 | CONFIG_BACKLIGHT_CLASS_DEVICE=y | 50 | CONFIG_BACKLIGHT_CLASS_DEVICE=y |
69 | # CONFIG_VGA_CONSOLE is not set | ||
70 | CONFIG_SOUND=y | ||
71 | CONFIG_SND=y | ||
72 | # CONFIG_SND_SUPPORT_OLD_API is not set | ||
73 | # CONFIG_SND_VERBOSE_PROCFS is not set | ||
74 | # CONFIG_SND_DRIVERS is not set | ||
75 | # CONFIG_SND_ARM is not set | ||
76 | # CONFIG_SND_SPI is not set | ||
77 | CONFIG_SND_SOC=y | ||
78 | # CONFIG_HID_SUPPORT is not set | 51 | # CONFIG_HID_SUPPORT is not set |
79 | # CONFIG_USB_SUPPORT is not set | 52 | # CONFIG_USB_SUPPORT is not set |
80 | CONFIG_MMC=y | 53 | CONFIG_MMC=y |
81 | CONFIG_MMC_DEBUG=y | ||
82 | CONFIG_MMC_ARMMMCI=y | 54 | CONFIG_MMC_ARMMMCI=y |
83 | CONFIG_NEW_LEDS=y | ||
84 | CONFIG_LEDS_CLASS=y | ||
85 | CONFIG_LEDS_TRIGGERS=y | ||
86 | CONFIG_LEDS_TRIGGER_BACKLIGHT=y | ||
87 | CONFIG_RTC_CLASS=y | 55 | CONFIG_RTC_CLASS=y |
88 | # CONFIG_RTC_HCTOSYS is not set | 56 | # CONFIG_RTC_HCTOSYS is not set |
89 | CONFIG_RTC_DRV_COH901331=y | 57 | CONFIG_RTC_DRV_COH901331=y |
@@ -93,12 +61,11 @@ CONFIG_COH901318=y | |||
93 | CONFIG_FUSE_FS=y | 61 | CONFIG_FUSE_FS=y |
94 | CONFIG_VFAT_FS=y | 62 | CONFIG_VFAT_FS=y |
95 | CONFIG_TMPFS=y | 63 | CONFIG_TMPFS=y |
96 | # CONFIG_NETWORK_FILESYSTEMS is not set | ||
97 | CONFIG_NLS_CODEPAGE_437=y | 64 | CONFIG_NLS_CODEPAGE_437=y |
98 | CONFIG_NLS_ISO8859_1=y | 65 | CONFIG_NLS_ISO8859_1=y |
99 | CONFIG_PRINTK_TIME=y | 66 | CONFIG_PRINTK_TIME=y |
67 | CONFIG_DEBUG_FS=y | ||
100 | CONFIG_DEBUG_KERNEL=y | 68 | CONFIG_DEBUG_KERNEL=y |
101 | # CONFIG_DETECT_SOFTLOCKUP is not set | ||
102 | # CONFIG_SCHED_DEBUG is not set | 69 | # CONFIG_SCHED_DEBUG is not set |
103 | CONFIG_TIMER_STATS=y | 70 | CONFIG_TIMER_STATS=y |
104 | # CONFIG_DEBUG_PREEMPT is not set | 71 | # CONFIG_DEBUG_PREEMPT is not set |
diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h index 6e8f05c8a1c8..062b58c029ab 100644 --- a/arch/arm/include/asm/assembler.h +++ b/arch/arm/include/asm/assembler.h | |||
@@ -154,16 +154,39 @@ | |||
154 | .long 9999b,9001f; \ | 154 | .long 9999b,9001f; \ |
155 | .popsection | 155 | .popsection |
156 | 156 | ||
157 | #ifdef CONFIG_SMP | ||
158 | #define ALT_SMP(instr...) \ | ||
159 | 9998: instr | ||
160 | #define ALT_UP(instr...) \ | ||
161 | .pushsection ".alt.smp.init", "a" ;\ | ||
162 | .long 9998b ;\ | ||
163 | instr ;\ | ||
164 | .popsection | ||
165 | #define ALT_UP_B(label) \ | ||
166 | .equ up_b_offset, label - 9998b ;\ | ||
167 | .pushsection ".alt.smp.init", "a" ;\ | ||
168 | .long 9998b ;\ | ||
169 | b . + up_b_offset ;\ | ||
170 | .popsection | ||
171 | #else | ||
172 | #define ALT_SMP(instr...) | ||
173 | #define ALT_UP(instr...) instr | ||
174 | #define ALT_UP_B(label) b label | ||
175 | #endif | ||
176 | |||
157 | /* | 177 | /* |
158 | * SMP data memory barrier | 178 | * SMP data memory barrier |
159 | */ | 179 | */ |
160 | .macro smp_dmb | 180 | .macro smp_dmb |
161 | #ifdef CONFIG_SMP | 181 | #ifdef CONFIG_SMP |
162 | #if __LINUX_ARM_ARCH__ >= 7 | 182 | #if __LINUX_ARM_ARCH__ >= 7 |
163 | dmb | 183 | ALT_SMP(dmb) |
164 | #elif __LINUX_ARM_ARCH__ == 6 | 184 | #elif __LINUX_ARM_ARCH__ == 6 |
165 | mcr p15, 0, r0, c7, c10, 5 @ dmb | 185 | ALT_SMP(mcr p15, 0, r0, c7, c10, 5) @ dmb |
186 | #else | ||
187 | #error Incompatible SMP platform | ||
166 | #endif | 188 | #endif |
189 | ALT_UP(nop) | ||
167 | #endif | 190 | #endif |
168 | .endm | 191 | .endm |
169 | 192 | ||
diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h index 042e13994d38..3acd8fa25e34 100644 --- a/arch/arm/include/asm/cacheflush.h +++ b/arch/arm/include/asm/cacheflush.h | |||
@@ -156,6 +156,12 @@ | |||
156 | * Please note that the implementation of these, and the required | 156 | * Please note that the implementation of these, and the required |
157 | * effects are cache-type (VIVT/VIPT/PIPT) specific. | 157 | * effects are cache-type (VIVT/VIPT/PIPT) specific. |
158 | * | 158 | * |
159 | * flush_icache_all() | ||
160 | * | ||
161 | * Unconditionally clean and invalidate the entire icache. | ||
162 | * Currently only needed for cache-v6.S and cache-v7.S, see | ||
163 | * __flush_icache_all for the generic implementation. | ||
164 | * | ||
159 | * flush_kern_all() | 165 | * flush_kern_all() |
160 | * | 166 | * |
161 | * Unconditionally clean and invalidate the entire cache. | 167 | * Unconditionally clean and invalidate the entire cache. |
@@ -206,6 +212,7 @@ | |||
206 | */ | 212 | */ |
207 | 213 | ||
208 | struct cpu_cache_fns { | 214 | struct cpu_cache_fns { |
215 | void (*flush_icache_all)(void); | ||
209 | void (*flush_kern_all)(void); | 216 | void (*flush_kern_all)(void); |
210 | void (*flush_user_all)(void); | 217 | void (*flush_user_all)(void); |
211 | void (*flush_user_range)(unsigned long, unsigned long, unsigned int); | 218 | void (*flush_user_range)(unsigned long, unsigned long, unsigned int); |
@@ -227,6 +234,7 @@ struct cpu_cache_fns { | |||
227 | 234 | ||
228 | extern struct cpu_cache_fns cpu_cache; | 235 | extern struct cpu_cache_fns cpu_cache; |
229 | 236 | ||
237 | #define __cpuc_flush_icache_all cpu_cache.flush_icache_all | ||
230 | #define __cpuc_flush_kern_all cpu_cache.flush_kern_all | 238 | #define __cpuc_flush_kern_all cpu_cache.flush_kern_all |
231 | #define __cpuc_flush_user_all cpu_cache.flush_user_all | 239 | #define __cpuc_flush_user_all cpu_cache.flush_user_all |
232 | #define __cpuc_flush_user_range cpu_cache.flush_user_range | 240 | #define __cpuc_flush_user_range cpu_cache.flush_user_range |
@@ -246,6 +254,7 @@ extern struct cpu_cache_fns cpu_cache; | |||
246 | 254 | ||
247 | #else | 255 | #else |
248 | 256 | ||
257 | #define __cpuc_flush_icache_all __glue(_CACHE,_flush_icache_all) | ||
249 | #define __cpuc_flush_kern_all __glue(_CACHE,_flush_kern_cache_all) | 258 | #define __cpuc_flush_kern_all __glue(_CACHE,_flush_kern_cache_all) |
250 | #define __cpuc_flush_user_all __glue(_CACHE,_flush_user_cache_all) | 259 | #define __cpuc_flush_user_all __glue(_CACHE,_flush_user_cache_all) |
251 | #define __cpuc_flush_user_range __glue(_CACHE,_flush_user_cache_range) | 260 | #define __cpuc_flush_user_range __glue(_CACHE,_flush_user_cache_range) |
@@ -253,6 +262,7 @@ extern struct cpu_cache_fns cpu_cache; | |||
253 | #define __cpuc_coherent_user_range __glue(_CACHE,_coherent_user_range) | 262 | #define __cpuc_coherent_user_range __glue(_CACHE,_coherent_user_range) |
254 | #define __cpuc_flush_dcache_area __glue(_CACHE,_flush_kern_dcache_area) | 263 | #define __cpuc_flush_dcache_area __glue(_CACHE,_flush_kern_dcache_area) |
255 | 264 | ||
265 | extern void __cpuc_flush_icache_all(void); | ||
256 | extern void __cpuc_flush_kern_all(void); | 266 | extern void __cpuc_flush_kern_all(void); |
257 | extern void __cpuc_flush_user_all(void); | 267 | extern void __cpuc_flush_user_all(void); |
258 | extern void __cpuc_flush_user_range(unsigned long, unsigned long, unsigned int); | 268 | extern void __cpuc_flush_user_range(unsigned long, unsigned long, unsigned int); |
@@ -291,6 +301,37 @@ extern void copy_to_user_page(struct vm_area_struct *, struct page *, | |||
291 | /* | 301 | /* |
292 | * Convert calls to our calling convention. | 302 | * Convert calls to our calling convention. |
293 | */ | 303 | */ |
304 | |||
305 | /* Invalidate I-cache */ | ||
306 | #define __flush_icache_all_generic() \ | ||
307 | asm("mcr p15, 0, %0, c7, c5, 0" \ | ||
308 | : : "r" (0)); | ||
309 | |||
310 | /* Invalidate I-cache inner shareable */ | ||
311 | #define __flush_icache_all_v7_smp() \ | ||
312 | asm("mcr p15, 0, %0, c7, c1, 0" \ | ||
313 | : : "r" (0)); | ||
314 | |||
315 | /* | ||
316 | * Optimized __flush_icache_all for the common cases. Note that UP ARMv7 | ||
317 | * will fall through to use __flush_icache_all_generic. | ||
318 | */ | ||
319 | #if (defined(CONFIG_CPU_V7) && defined(CONFIG_CPU_V6)) || \ | ||
320 | defined(CONFIG_SMP_ON_UP) | ||
321 | #define __flush_icache_preferred __cpuc_flush_icache_all | ||
322 | #elif __LINUX_ARM_ARCH__ >= 7 && defined(CONFIG_SMP) | ||
323 | #define __flush_icache_preferred __flush_icache_all_v7_smp | ||
324 | #elif __LINUX_ARM_ARCH__ == 6 && defined(CONFIG_ARM_ERRATA_411920) | ||
325 | #define __flush_icache_preferred __cpuc_flush_icache_all | ||
326 | #else | ||
327 | #define __flush_icache_preferred __flush_icache_all_generic | ||
328 | #endif | ||
329 | |||
330 | static inline void __flush_icache_all(void) | ||
331 | { | ||
332 | __flush_icache_preferred(); | ||
333 | } | ||
334 | |||
294 | #define flush_cache_all() __cpuc_flush_kern_all() | 335 | #define flush_cache_all() __cpuc_flush_kern_all() |
295 | 336 | ||
296 | static inline void vivt_flush_cache_mm(struct mm_struct *mm) | 337 | static inline void vivt_flush_cache_mm(struct mm_struct *mm) |
@@ -366,21 +407,6 @@ extern void flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr | |||
366 | #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1 | 407 | #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1 |
367 | extern void flush_dcache_page(struct page *); | 408 | extern void flush_dcache_page(struct page *); |
368 | 409 | ||
369 | static inline void __flush_icache_all(void) | ||
370 | { | ||
371 | #ifdef CONFIG_ARM_ERRATA_411920 | ||
372 | extern void v6_icache_inval_all(void); | ||
373 | v6_icache_inval_all(); | ||
374 | #elif defined(CONFIG_SMP) && __LINUX_ARM_ARCH__ >= 7 | ||
375 | asm("mcr p15, 0, %0, c7, c1, 0 @ invalidate I-cache inner shareable\n" | ||
376 | : | ||
377 | : "r" (0)); | ||
378 | #else | ||
379 | asm("mcr p15, 0, %0, c7, c5, 0 @ invalidate I-cache\n" | ||
380 | : | ||
381 | : "r" (0)); | ||
382 | #endif | ||
383 | } | ||
384 | static inline void flush_kernel_vmap_range(void *addr, int size) | 410 | static inline void flush_kernel_vmap_range(void *addr, int size) |
385 | { | 411 | { |
386 | if ((cache_is_vivt() || cache_is_vipt_aliasing())) | 412 | if ((cache_is_vivt() || cache_is_vipt_aliasing())) |
diff --git a/arch/arm/include/asm/ftrace.h b/arch/arm/include/asm/ftrace.h index 103f7ee97313..f89515adac60 100644 --- a/arch/arm/include/asm/ftrace.h +++ b/arch/arm/include/asm/ftrace.h | |||
@@ -2,12 +2,30 @@ | |||
2 | #define _ASM_ARM_FTRACE | 2 | #define _ASM_ARM_FTRACE |
3 | 3 | ||
4 | #ifdef CONFIG_FUNCTION_TRACER | 4 | #ifdef CONFIG_FUNCTION_TRACER |
5 | #define MCOUNT_ADDR ((long)(mcount)) | 5 | #define MCOUNT_ADDR ((unsigned long)(__gnu_mcount_nc)) |
6 | #define MCOUNT_INSN_SIZE 4 /* sizeof mcount call */ | 6 | #define MCOUNT_INSN_SIZE 4 /* sizeof mcount call */ |
7 | 7 | ||
8 | #ifndef __ASSEMBLY__ | 8 | #ifndef __ASSEMBLY__ |
9 | extern void mcount(void); | 9 | extern void mcount(void); |
10 | extern void __gnu_mcount_nc(void); | 10 | extern void __gnu_mcount_nc(void); |
11 | |||
12 | #ifdef CONFIG_DYNAMIC_FTRACE | ||
13 | struct dyn_arch_ftrace { | ||
14 | #ifdef CONFIG_OLD_MCOUNT | ||
15 | bool old_mcount; | ||
16 | #endif | ||
17 | }; | ||
18 | |||
19 | static inline unsigned long ftrace_call_adjust(unsigned long addr) | ||
20 | { | ||
21 | /* With Thumb-2, the recorded addresses have the lsb set */ | ||
22 | return addr & ~1; | ||
23 | } | ||
24 | |||
25 | extern void ftrace_caller_old(void); | ||
26 | extern void ftrace_call_old(void); | ||
27 | #endif | ||
28 | |||
11 | #endif | 29 | #endif |
12 | 30 | ||
13 | #endif | 31 | #endif |
diff --git a/arch/arm/include/asm/hardware/coresight.h b/arch/arm/include/asm/hardware/coresight.h index 212e47828c79..7ecd793b8f5a 100644 --- a/arch/arm/include/asm/hardware/coresight.h +++ b/arch/arm/include/asm/hardware/coresight.h | |||
@@ -21,18 +21,6 @@ | |||
21 | #define TRACER_RUNNING BIT(TRACER_RUNNING_BIT) | 21 | #define TRACER_RUNNING BIT(TRACER_RUNNING_BIT) |
22 | #define TRACER_CYCLE_ACC BIT(TRACER_CYCLE_ACC_BIT) | 22 | #define TRACER_CYCLE_ACC BIT(TRACER_CYCLE_ACC_BIT) |
23 | 23 | ||
24 | struct tracectx { | ||
25 | unsigned int etb_bufsz; | ||
26 | void __iomem *etb_regs; | ||
27 | void __iomem *etm_regs; | ||
28 | unsigned long flags; | ||
29 | int ncmppairs; | ||
30 | int etm_portsz; | ||
31 | struct device *dev; | ||
32 | struct clk *emu_clk; | ||
33 | struct mutex mutex; | ||
34 | }; | ||
35 | |||
36 | #define TRACER_TIMEOUT 10000 | 24 | #define TRACER_TIMEOUT 10000 |
37 | 25 | ||
38 | #define etm_writel(t, v, x) \ | 26 | #define etm_writel(t, v, x) \ |
@@ -112,10 +100,10 @@ struct tracectx { | |||
112 | 100 | ||
113 | /* ETM status register, "ETM Architecture", 3.3.2 */ | 101 | /* ETM status register, "ETM Architecture", 3.3.2 */ |
114 | #define ETMR_STATUS (0x10) | 102 | #define ETMR_STATUS (0x10) |
115 | #define ETMST_OVERFLOW (1 << 0) | 103 | #define ETMST_OVERFLOW BIT(0) |
116 | #define ETMST_PROGBIT (1 << 1) | 104 | #define ETMST_PROGBIT BIT(1) |
117 | #define ETMST_STARTSTOP (1 << 2) | 105 | #define ETMST_STARTSTOP BIT(2) |
118 | #define ETMST_TRIGGER (1 << 3) | 106 | #define ETMST_TRIGGER BIT(3) |
119 | 107 | ||
120 | #define etm_progbit(t) (etm_readl((t), ETMR_STATUS) & ETMST_PROGBIT) | 108 | #define etm_progbit(t) (etm_readl((t), ETMR_STATUS) & ETMST_PROGBIT) |
121 | #define etm_started(t) (etm_readl((t), ETMR_STATUS) & ETMST_STARTSTOP) | 109 | #define etm_started(t) (etm_readl((t), ETMR_STATUS) & ETMST_STARTSTOP) |
@@ -123,7 +111,7 @@ struct tracectx { | |||
123 | 111 | ||
124 | #define ETMR_TRACEENCTRL2 0x1c | 112 | #define ETMR_TRACEENCTRL2 0x1c |
125 | #define ETMR_TRACEENCTRL 0x24 | 113 | #define ETMR_TRACEENCTRL 0x24 |
126 | #define ETMTE_INCLEXCL (1 << 24) | 114 | #define ETMTE_INCLEXCL BIT(24) |
127 | #define ETMR_TRACEENEVT 0x20 | 115 | #define ETMR_TRACEENEVT 0x20 |
128 | #define ETMCTRL_OPTS (ETMCTRL_DO_CPRT | \ | 116 | #define ETMCTRL_OPTS (ETMCTRL_DO_CPRT | \ |
129 | ETMCTRL_DATA_DO_ADDR | \ | 117 | ETMCTRL_DATA_DO_ADDR | \ |
@@ -146,12 +134,12 @@ struct tracectx { | |||
146 | #define ETBR_CTRL 0x20 | 134 | #define ETBR_CTRL 0x20 |
147 | #define ETBR_FORMATTERCTRL 0x304 | 135 | #define ETBR_FORMATTERCTRL 0x304 |
148 | #define ETBFF_ENFTC 1 | 136 | #define ETBFF_ENFTC 1 |
149 | #define ETBFF_ENFCONT (1 << 1) | 137 | #define ETBFF_ENFCONT BIT(1) |
150 | #define ETBFF_FONFLIN (1 << 4) | 138 | #define ETBFF_FONFLIN BIT(4) |
151 | #define ETBFF_MANUAL_FLUSH (1 << 6) | 139 | #define ETBFF_MANUAL_FLUSH BIT(6) |
152 | #define ETBFF_TRIGIN (1 << 8) | 140 | #define ETBFF_TRIGIN BIT(8) |
153 | #define ETBFF_TRIGEVT (1 << 9) | 141 | #define ETBFF_TRIGEVT BIT(9) |
154 | #define ETBFF_TRIGFL (1 << 10) | 142 | #define ETBFF_TRIGFL BIT(10) |
155 | 143 | ||
156 | #define etb_writel(t, v, x) \ | 144 | #define etb_writel(t, v, x) \ |
157 | (__raw_writel((v), (t)->etb_regs + (x))) | 145 | (__raw_writel((v), (t)->etb_regs + (x))) |
diff --git a/arch/arm/include/asm/hw_breakpoint.h b/arch/arm/include/asm/hw_breakpoint.h new file mode 100644 index 000000000000..4d8ae9d67abe --- /dev/null +++ b/arch/arm/include/asm/hw_breakpoint.h | |||
@@ -0,0 +1,133 @@ | |||
1 | #ifndef _ARM_HW_BREAKPOINT_H | ||
2 | #define _ARM_HW_BREAKPOINT_H | ||
3 | |||
4 | #ifdef __KERNEL__ | ||
5 | |||
6 | struct task_struct; | ||
7 | |||
8 | #ifdef CONFIG_HAVE_HW_BREAKPOINT | ||
9 | |||
10 | struct arch_hw_breakpoint_ctrl { | ||
11 | u32 __reserved : 9, | ||
12 | mismatch : 1, | ||
13 | : 9, | ||
14 | len : 8, | ||
15 | type : 2, | ||
16 | privilege : 2, | ||
17 | enabled : 1; | ||
18 | }; | ||
19 | |||
20 | struct arch_hw_breakpoint { | ||
21 | u32 address; | ||
22 | u32 trigger; | ||
23 | struct perf_event *suspended_wp; | ||
24 | struct arch_hw_breakpoint_ctrl ctrl; | ||
25 | }; | ||
26 | |||
27 | static inline u32 encode_ctrl_reg(struct arch_hw_breakpoint_ctrl ctrl) | ||
28 | { | ||
29 | return (ctrl.mismatch << 22) | (ctrl.len << 5) | (ctrl.type << 3) | | ||
30 | (ctrl.privilege << 1) | ctrl.enabled; | ||
31 | } | ||
32 | |||
33 | static inline void decode_ctrl_reg(u32 reg, | ||
34 | struct arch_hw_breakpoint_ctrl *ctrl) | ||
35 | { | ||
36 | ctrl->enabled = reg & 0x1; | ||
37 | reg >>= 1; | ||
38 | ctrl->privilege = reg & 0x3; | ||
39 | reg >>= 2; | ||
40 | ctrl->type = reg & 0x3; | ||
41 | reg >>= 2; | ||
42 | ctrl->len = reg & 0xff; | ||
43 | reg >>= 17; | ||
44 | ctrl->mismatch = reg & 0x1; | ||
45 | } | ||
46 | |||
47 | /* Debug architecture numbers. */ | ||
48 | #define ARM_DEBUG_ARCH_RESERVED 0 /* In case of ptrace ABI updates. */ | ||
49 | #define ARM_DEBUG_ARCH_V6 1 | ||
50 | #define ARM_DEBUG_ARCH_V6_1 2 | ||
51 | #define ARM_DEBUG_ARCH_V7_ECP14 3 | ||
52 | #define ARM_DEBUG_ARCH_V7_MM 4 | ||
53 | |||
54 | /* Breakpoint */ | ||
55 | #define ARM_BREAKPOINT_EXECUTE 0 | ||
56 | |||
57 | /* Watchpoints */ | ||
58 | #define ARM_BREAKPOINT_LOAD 1 | ||
59 | #define ARM_BREAKPOINT_STORE 2 | ||
60 | |||
61 | /* Privilege Levels */ | ||
62 | #define ARM_BREAKPOINT_PRIV 1 | ||
63 | #define ARM_BREAKPOINT_USER 2 | ||
64 | |||
65 | /* Lengths */ | ||
66 | #define ARM_BREAKPOINT_LEN_1 0x1 | ||
67 | #define ARM_BREAKPOINT_LEN_2 0x3 | ||
68 | #define ARM_BREAKPOINT_LEN_4 0xf | ||
69 | #define ARM_BREAKPOINT_LEN_8 0xff | ||
70 | |||
71 | /* Limits */ | ||
72 | #define ARM_MAX_BRP 16 | ||
73 | #define ARM_MAX_WRP 16 | ||
74 | #define ARM_MAX_HBP_SLOTS (ARM_MAX_BRP + ARM_MAX_WRP) | ||
75 | |||
76 | /* DSCR method of entry bits. */ | ||
77 | #define ARM_DSCR_MOE(x) ((x >> 2) & 0xf) | ||
78 | #define ARM_ENTRY_BREAKPOINT 0x1 | ||
79 | #define ARM_ENTRY_ASYNC_WATCHPOINT 0x2 | ||
80 | #define ARM_ENTRY_SYNC_WATCHPOINT 0xa | ||
81 | |||
82 | /* DSCR monitor/halting bits. */ | ||
83 | #define ARM_DSCR_HDBGEN (1 << 14) | ||
84 | #define ARM_DSCR_MDBGEN (1 << 15) | ||
85 | |||
86 | /* opcode2 numbers for the co-processor instructions. */ | ||
87 | #define ARM_OP2_BVR 4 | ||
88 | #define ARM_OP2_BCR 5 | ||
89 | #define ARM_OP2_WVR 6 | ||
90 | #define ARM_OP2_WCR 7 | ||
91 | |||
92 | /* Base register numbers for the debug registers. */ | ||
93 | #define ARM_BASE_BVR 64 | ||
94 | #define ARM_BASE_BCR 80 | ||
95 | #define ARM_BASE_WVR 96 | ||
96 | #define ARM_BASE_WCR 112 | ||
97 | |||
98 | /* Accessor macros for the debug registers. */ | ||
99 | #define ARM_DBG_READ(M, OP2, VAL) do {\ | ||
100 | asm volatile("mrc p14, 0, %0, c0," #M ", " #OP2 : "=r" (VAL));\ | ||
101 | } while (0) | ||
102 | |||
103 | #define ARM_DBG_WRITE(M, OP2, VAL) do {\ | ||
104 | asm volatile("mcr p14, 0, %0, c0," #M ", " #OP2 : : "r" (VAL));\ | ||
105 | } while (0) | ||
106 | |||
107 | struct notifier_block; | ||
108 | struct perf_event; | ||
109 | struct pmu; | ||
110 | |||
111 | extern struct pmu perf_ops_bp; | ||
112 | extern int arch_bp_generic_fields(struct arch_hw_breakpoint_ctrl ctrl, | ||
113 | int *gen_len, int *gen_type); | ||
114 | extern int arch_check_bp_in_kernelspace(struct perf_event *bp); | ||
115 | extern int arch_validate_hwbkpt_settings(struct perf_event *bp); | ||
116 | extern int hw_breakpoint_exceptions_notify(struct notifier_block *unused, | ||
117 | unsigned long val, void *data); | ||
118 | |||
119 | extern u8 arch_get_debug_arch(void); | ||
120 | extern u8 arch_get_max_wp_len(void); | ||
121 | extern void clear_ptrace_hw_breakpoint(struct task_struct *tsk); | ||
122 | |||
123 | int arch_install_hw_breakpoint(struct perf_event *bp); | ||
124 | void arch_uninstall_hw_breakpoint(struct perf_event *bp); | ||
125 | void hw_breakpoint_pmu_read(struct perf_event *bp); | ||
126 | int hw_breakpoint_slots(int type); | ||
127 | |||
128 | #else | ||
129 | static inline void clear_ptrace_hw_breakpoint(struct task_struct *tsk) {} | ||
130 | |||
131 | #endif /* CONFIG_HAVE_HW_BREAKPOINT */ | ||
132 | #endif /* __KERNEL__ */ | ||
133 | #endif /* _ARM_HW_BREAKPOINT_H */ | ||
diff --git a/arch/arm/include/asm/module.h b/arch/arm/include/asm/module.h index e4dfa69abb68..cbb0bc295d2b 100644 --- a/arch/arm/include/asm/module.h +++ b/arch/arm/include/asm/module.h | |||
@@ -7,20 +7,27 @@ | |||
7 | 7 | ||
8 | struct unwind_table; | 8 | struct unwind_table; |
9 | 9 | ||
10 | struct mod_arch_specific | ||
11 | { | ||
12 | #ifdef CONFIG_ARM_UNWIND | 10 | #ifdef CONFIG_ARM_UNWIND |
13 | Elf_Shdr *unw_sec_init; | 11 | struct arm_unwind_mapping { |
14 | Elf_Shdr *unw_sec_devinit; | 12 | Elf_Shdr *unw_sec; |
15 | Elf_Shdr *unw_sec_core; | 13 | Elf_Shdr *sec_text; |
16 | Elf_Shdr *sec_init_text; | 14 | struct unwind_table *unwind; |
17 | Elf_Shdr *sec_devinit_text; | 15 | }; |
18 | Elf_Shdr *sec_core_text; | 16 | enum { |
19 | struct unwind_table *unwind_init; | 17 | ARM_SEC_INIT, |
20 | struct unwind_table *unwind_devinit; | 18 | ARM_SEC_DEVINIT, |
21 | struct unwind_table *unwind_core; | 19 | ARM_SEC_CORE, |
22 | #endif | 20 | ARM_SEC_EXIT, |
21 | ARM_SEC_DEVEXIT, | ||
22 | ARM_SEC_MAX, | ||
23 | }; | ||
24 | struct mod_arch_specific { | ||
25 | struct arm_unwind_mapping map[ARM_SEC_MAX]; | ||
23 | }; | 26 | }; |
27 | #else | ||
28 | struct mod_arch_specific { | ||
29 | }; | ||
30 | #endif | ||
24 | 31 | ||
25 | /* | 32 | /* |
26 | * Include the ARM architecture version. | 33 | * Include the ARM architecture version. |
diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h index 42e694f1d58e..a9672e8406a3 100644 --- a/arch/arm/include/asm/pgtable.h +++ b/arch/arm/include/asm/pgtable.h | |||
@@ -337,6 +337,10 @@ static inline pte_t pte_mkspecial(pte_t pte) { return pte; } | |||
337 | #ifdef CONFIG_ARM_DMA_MEM_BUFFERABLE | 337 | #ifdef CONFIG_ARM_DMA_MEM_BUFFERABLE |
338 | #define pgprot_dmacoherent(prot) \ | 338 | #define pgprot_dmacoherent(prot) \ |
339 | __pgprot_modify(prot, L_PTE_MT_MASK|L_PTE_EXEC, L_PTE_MT_BUFFERABLE) | 339 | __pgprot_modify(prot, L_PTE_MT_MASK|L_PTE_EXEC, L_PTE_MT_BUFFERABLE) |
340 | #define __HAVE_PHYS_MEM_ACCESS_PROT | ||
341 | struct file; | ||
342 | extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn, | ||
343 | unsigned long size, pgprot_t vma_prot); | ||
340 | #else | 344 | #else |
341 | #define pgprot_dmacoherent(prot) \ | 345 | #define pgprot_dmacoherent(prot) \ |
342 | __pgprot_modify(prot, L_PTE_MT_MASK|L_PTE_EXEC, L_PTE_MT_UNCACHED) | 346 | __pgprot_modify(prot, L_PTE_MT_MASK|L_PTE_EXEC, L_PTE_MT_UNCACHED) |
diff --git a/arch/arm/include/asm/processor.h b/arch/arm/include/asm/processor.h index 7bed3daf83b8..67357baaeeeb 100644 --- a/arch/arm/include/asm/processor.h +++ b/arch/arm/include/asm/processor.h | |||
@@ -19,6 +19,7 @@ | |||
19 | 19 | ||
20 | #ifdef __KERNEL__ | 20 | #ifdef __KERNEL__ |
21 | 21 | ||
22 | #include <asm/hw_breakpoint.h> | ||
22 | #include <asm/ptrace.h> | 23 | #include <asm/ptrace.h> |
23 | #include <asm/types.h> | 24 | #include <asm/types.h> |
24 | 25 | ||
@@ -41,6 +42,9 @@ struct debug_entry { | |||
41 | struct debug_info { | 42 | struct debug_info { |
42 | int nsaved; | 43 | int nsaved; |
43 | struct debug_entry bp[2]; | 44 | struct debug_entry bp[2]; |
45 | #ifdef CONFIG_HAVE_HW_BREAKPOINT | ||
46 | struct perf_event *hbp[ARM_MAX_HBP_SLOTS]; | ||
47 | #endif | ||
44 | }; | 48 | }; |
45 | 49 | ||
46 | struct thread_struct { | 50 | struct thread_struct { |
diff --git a/arch/arm/include/asm/ptrace.h b/arch/arm/include/asm/ptrace.h index 7ce15eb15f72..783d50f32618 100644 --- a/arch/arm/include/asm/ptrace.h +++ b/arch/arm/include/asm/ptrace.h | |||
@@ -29,6 +29,8 @@ | |||
29 | #define PTRACE_SETCRUNCHREGS 26 | 29 | #define PTRACE_SETCRUNCHREGS 26 |
30 | #define PTRACE_GETVFPREGS 27 | 30 | #define PTRACE_GETVFPREGS 27 |
31 | #define PTRACE_SETVFPREGS 28 | 31 | #define PTRACE_SETVFPREGS 28 |
32 | #define PTRACE_GETHBPREGS 29 | ||
33 | #define PTRACE_SETHBPREGS 30 | ||
32 | 34 | ||
33 | /* | 35 | /* |
34 | * PSR bits | 36 | * PSR bits |
diff --git a/arch/arm/include/asm/smp_mpidr.h b/arch/arm/include/asm/smp_mpidr.h new file mode 100644 index 000000000000..6a9307d64900 --- /dev/null +++ b/arch/arm/include/asm/smp_mpidr.h | |||
@@ -0,0 +1,17 @@ | |||
1 | #ifndef ASMARM_SMP_MIDR_H | ||
2 | #define ASMARM_SMP_MIDR_H | ||
3 | |||
4 | #define hard_smp_processor_id() \ | ||
5 | ({ \ | ||
6 | unsigned int cpunum; \ | ||
7 | __asm__("\n" \ | ||
8 | "1: mrc p15, 0, %0, c0, c0, 5\n" \ | ||
9 | " .pushsection \".alt.smp.init\", \"a\"\n"\ | ||
10 | " .long 1b\n" \ | ||
11 | " mov %0, #0\n" \ | ||
12 | " .popsection" \ | ||
13 | : "=r" (cpunum)); \ | ||
14 | cpunum &= 0x0F; \ | ||
15 | }) | ||
16 | |||
17 | #endif | ||
diff --git a/arch/arm/include/asm/smp_plat.h b/arch/arm/include/asm/smp_plat.h index 963a338d567b..f24c1b9e211d 100644 --- a/arch/arm/include/asm/smp_plat.h +++ b/arch/arm/include/asm/smp_plat.h | |||
@@ -7,9 +7,27 @@ | |||
7 | 7 | ||
8 | #include <asm/cputype.h> | 8 | #include <asm/cputype.h> |
9 | 9 | ||
10 | /* | ||
11 | * Return true if we are running on a SMP platform | ||
12 | */ | ||
13 | static inline bool is_smp(void) | ||
14 | { | ||
15 | #ifndef CONFIG_SMP | ||
16 | return false; | ||
17 | #elif defined(CONFIG_SMP_ON_UP) | ||
18 | extern unsigned int smp_on_up; | ||
19 | return !!smp_on_up; | ||
20 | #else | ||
21 | return true; | ||
22 | #endif | ||
23 | } | ||
24 | |||
10 | /* all SMP configurations have the extended CPUID registers */ | 25 | /* all SMP configurations have the extended CPUID registers */ |
11 | static inline int tlb_ops_need_broadcast(void) | 26 | static inline int tlb_ops_need_broadcast(void) |
12 | { | 27 | { |
28 | if (!is_smp()) | ||
29 | return 0; | ||
30 | |||
13 | return ((read_cpuid_ext(CPUID_EXT_MMFR3) >> 12) & 0xf) < 2; | 31 | return ((read_cpuid_ext(CPUID_EXT_MMFR3) >> 12) & 0xf) < 2; |
14 | } | 32 | } |
15 | 33 | ||
@@ -18,6 +36,9 @@ static inline int tlb_ops_need_broadcast(void) | |||
18 | #else | 36 | #else |
19 | static inline int cache_ops_need_broadcast(void) | 37 | static inline int cache_ops_need_broadcast(void) |
20 | { | 38 | { |
39 | if (!is_smp()) | ||
40 | return 0; | ||
41 | |||
21 | return ((read_cpuid_ext(CPUID_EXT_MMFR3) >> 12) & 0xf) < 1; | 42 | return ((read_cpuid_ext(CPUID_EXT_MMFR3) >> 12) & 0xf) < 1; |
22 | } | 43 | } |
23 | #endif | 44 | #endif |
diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h index 8ba1ccf82a02..1120f18a6b17 100644 --- a/arch/arm/include/asm/system.h +++ b/arch/arm/include/asm/system.h | |||
@@ -85,6 +85,10 @@ void hook_fault_code(int nr, int (*fn)(unsigned long, unsigned int, | |||
85 | struct pt_regs *), | 85 | struct pt_regs *), |
86 | int sig, int code, const char *name); | 86 | int sig, int code, const char *name); |
87 | 87 | ||
88 | void hook_ifault_code(int nr, int (*fn)(unsigned long, unsigned int, | ||
89 | struct pt_regs *), | ||
90 | int sig, int code, const char *name); | ||
91 | |||
88 | #define xchg(ptr,x) \ | 92 | #define xchg(ptr,x) \ |
89 | ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr)))) | 93 | ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr)))) |
90 | 94 | ||
@@ -325,6 +329,8 @@ static inline unsigned long __xchg(unsigned long x, volatile void *ptr, int size | |||
325 | extern void disable_hlt(void); | 329 | extern void disable_hlt(void); |
326 | extern void enable_hlt(void); | 330 | extern void enable_hlt(void); |
327 | 331 | ||
332 | void cpu_idle_wait(void); | ||
333 | |||
328 | #include <asm-generic/cmpxchg-local.h> | 334 | #include <asm-generic/cmpxchg-local.h> |
329 | 335 | ||
330 | #if __LINUX_ARM_ARCH__ < 6 | 336 | #if __LINUX_ARM_ARCH__ < 6 |
diff --git a/arch/arm/include/asm/tlbflush.h b/arch/arm/include/asm/tlbflush.h index 989c9e57d92b..ce7378ea15a2 100644 --- a/arch/arm/include/asm/tlbflush.h +++ b/arch/arm/include/asm/tlbflush.h | |||
@@ -70,6 +70,10 @@ | |||
70 | #undef _TLB | 70 | #undef _TLB |
71 | #undef MULTI_TLB | 71 | #undef MULTI_TLB |
72 | 72 | ||
73 | #ifdef CONFIG_SMP_ON_UP | ||
74 | #define MULTI_TLB 1 | ||
75 | #endif | ||
76 | |||
73 | #define v3_tlb_flags (TLB_V3_FULL | TLB_V3_PAGE) | 77 | #define v3_tlb_flags (TLB_V3_FULL | TLB_V3_PAGE) |
74 | 78 | ||
75 | #ifdef CONFIG_CPU_TLB_V3 | 79 | #ifdef CONFIG_CPU_TLB_V3 |
@@ -185,17 +189,23 @@ | |||
185 | # define v6wbi_always_flags (-1UL) | 189 | # define v6wbi_always_flags (-1UL) |
186 | #endif | 190 | #endif |
187 | 191 | ||
188 | #ifdef CONFIG_SMP | 192 | #define v7wbi_tlb_flags_smp (TLB_WB | TLB_DCLEAN | TLB_V7_IS_BTB | \ |
189 | #define v7wbi_tlb_flags (TLB_WB | TLB_DCLEAN | TLB_V7_IS_BTB | \ | ||
190 | TLB_V7_UIS_FULL | TLB_V7_UIS_PAGE | TLB_V7_UIS_ASID) | 193 | TLB_V7_UIS_FULL | TLB_V7_UIS_PAGE | TLB_V7_UIS_ASID) |
191 | #else | 194 | #define v7wbi_tlb_flags_up (TLB_WB | TLB_DCLEAN | TLB_BTB | \ |
192 | #define v7wbi_tlb_flags (TLB_WB | TLB_DCLEAN | TLB_BTB | \ | ||
193 | TLB_V6_U_FULL | TLB_V6_U_PAGE | TLB_V6_U_ASID) | 195 | TLB_V6_U_FULL | TLB_V6_U_PAGE | TLB_V6_U_ASID) |
194 | #endif | ||
195 | 196 | ||
196 | #ifdef CONFIG_CPU_TLB_V7 | 197 | #ifdef CONFIG_CPU_TLB_V7 |
197 | # define v7wbi_possible_flags v7wbi_tlb_flags | 198 | |
198 | # define v7wbi_always_flags v7wbi_tlb_flags | 199 | # ifdef CONFIG_SMP_ON_UP |
200 | # define v7wbi_possible_flags (v7wbi_tlb_flags_smp | v7wbi_tlb_flags_up) | ||
201 | # define v7wbi_always_flags (v7wbi_tlb_flags_smp & v7wbi_tlb_flags_up) | ||
202 | # elif defined(CONFIG_SMP) | ||
203 | # define v7wbi_possible_flags v7wbi_tlb_flags_smp | ||
204 | # define v7wbi_always_flags v7wbi_tlb_flags_smp | ||
205 | # else | ||
206 | # define v7wbi_possible_flags v7wbi_tlb_flags_up | ||
207 | # define v7wbi_always_flags v7wbi_tlb_flags_up | ||
208 | # endif | ||
199 | # ifdef _TLB | 209 | # ifdef _TLB |
200 | # define MULTI_TLB 1 | 210 | # define MULTI_TLB 1 |
201 | # else | 211 | # else |
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile index 980b78e31328..5b9b268f4fbb 100644 --- a/arch/arm/kernel/Makefile +++ b/arch/arm/kernel/Makefile | |||
@@ -42,6 +42,7 @@ obj-$(CONFIG_KGDB) += kgdb.o | |||
42 | obj-$(CONFIG_ARM_UNWIND) += unwind.o | 42 | obj-$(CONFIG_ARM_UNWIND) += unwind.o |
43 | obj-$(CONFIG_HAVE_TCM) += tcm.o | 43 | obj-$(CONFIG_HAVE_TCM) += tcm.o |
44 | obj-$(CONFIG_CRASH_DUMP) += crash_dump.o | 44 | obj-$(CONFIG_CRASH_DUMP) += crash_dump.o |
45 | obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o | ||
45 | 46 | ||
46 | obj-$(CONFIG_CRUNCH) += crunch.o crunch-bits.o | 47 | obj-$(CONFIG_CRUNCH) += crunch.o crunch-bits.o |
47 | AFLAGS_crunch-bits.o := -Wa,-mcpu=ep9312 | 48 | AFLAGS_crunch-bits.o := -Wa,-mcpu=ep9312 |
diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c index 8214bfebfaca..e5e1e5387678 100644 --- a/arch/arm/kernel/armksyms.c +++ b/arch/arm/kernel/armksyms.c | |||
@@ -165,6 +165,8 @@ EXPORT_SYMBOL(_find_next_bit_be); | |||
165 | #endif | 165 | #endif |
166 | 166 | ||
167 | #ifdef CONFIG_FUNCTION_TRACER | 167 | #ifdef CONFIG_FUNCTION_TRACER |
168 | #ifdef CONFIG_OLD_MCOUNT | ||
168 | EXPORT_SYMBOL(mcount); | 169 | EXPORT_SYMBOL(mcount); |
170 | #endif | ||
169 | EXPORT_SYMBOL(__gnu_mcount_nc); | 171 | EXPORT_SYMBOL(__gnu_mcount_nc); |
170 | #endif | 172 | #endif |
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index bb8e93a76407..c09e3573c5de 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S | |||
@@ -46,7 +46,8 @@ | |||
46 | * this macro assumes that irqstat (r6) and base (r5) are | 46 | * this macro assumes that irqstat (r6) and base (r5) are |
47 | * preserved from get_irqnr_and_base above | 47 | * preserved from get_irqnr_and_base above |
48 | */ | 48 | */ |
49 | test_for_ipi r0, r6, r5, lr | 49 | ALT_SMP(test_for_ipi r0, r6, r5, lr) |
50 | ALT_UP_B(9997f) | ||
50 | movne r0, sp | 51 | movne r0, sp |
51 | adrne lr, BSYM(1b) | 52 | adrne lr, BSYM(1b) |
52 | bne do_IPI | 53 | bne do_IPI |
@@ -57,6 +58,7 @@ | |||
57 | adrne lr, BSYM(1b) | 58 | adrne lr, BSYM(1b) |
58 | bne do_local_timer | 59 | bne do_local_timer |
59 | #endif | 60 | #endif |
61 | 9997: | ||
60 | #endif | 62 | #endif |
61 | 63 | ||
62 | .endm | 64 | .endm |
@@ -965,11 +967,8 @@ kuser_cmpxchg_fixup: | |||
965 | beq 1b | 967 | beq 1b |
966 | rsbs r0, r3, #0 | 968 | rsbs r0, r3, #0 |
967 | /* beware -- each __kuser slot must be 8 instructions max */ | 969 | /* beware -- each __kuser slot must be 8 instructions max */ |
968 | #ifdef CONFIG_SMP | 970 | ALT_SMP(b __kuser_memory_barrier) |
969 | b __kuser_memory_barrier | 971 | ALT_UP(usr_ret lr) |
970 | #else | ||
971 | usr_ret lr | ||
972 | #endif | ||
973 | 972 | ||
974 | #endif | 973 | #endif |
975 | 974 | ||
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S index 1b560825e1cf..2d23ad985180 100644 --- a/arch/arm/kernel/entry-common.S +++ b/arch/arm/kernel/entry-common.S | |||
@@ -48,6 +48,8 @@ work_pending: | |||
48 | beq no_work_pending | 48 | beq no_work_pending |
49 | mov r0, sp @ 'regs' | 49 | mov r0, sp @ 'regs' |
50 | mov r2, why @ 'syscall' | 50 | mov r2, why @ 'syscall' |
51 | tst r1, #_TIF_SIGPENDING @ delivering a signal? | ||
52 | movne why, #0 @ prevent further restarts | ||
51 | bl do_notify_resume | 53 | bl do_notify_resume |
52 | b ret_slow_syscall @ Check work again | 54 | b ret_slow_syscall @ Check work again |
53 | 55 | ||
@@ -127,30 +129,58 @@ ENDPROC(ret_from_fork) | |||
127 | * clobber the ip register. This is OK because the ARM calling convention | 129 | * clobber the ip register. This is OK because the ARM calling convention |
128 | * allows it to be clobbered in subroutines and doesn't use it to hold | 130 | * allows it to be clobbered in subroutines and doesn't use it to hold |
129 | * parameters.) | 131 | * parameters.) |
132 | * | ||
133 | * When using dynamic ftrace, we patch out the mcount call by a "mov r0, r0" | ||
134 | * for the mcount case, and a "pop {lr}" for the __gnu_mcount_nc case (see | ||
135 | * arch/arm/kernel/ftrace.c). | ||
130 | */ | 136 | */ |
137 | |||
138 | #ifndef CONFIG_OLD_MCOUNT | ||
139 | #if (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 4)) | ||
140 | #error Ftrace requires CONFIG_FRAME_POINTER=y with GCC older than 4.4.0. | ||
141 | #endif | ||
142 | #endif | ||
143 | |||
131 | #ifdef CONFIG_DYNAMIC_FTRACE | 144 | #ifdef CONFIG_DYNAMIC_FTRACE |
132 | ENTRY(mcount) | 145 | ENTRY(__gnu_mcount_nc) |
146 | mov ip, lr | ||
147 | ldmia sp!, {lr} | ||
148 | mov pc, ip | ||
149 | ENDPROC(__gnu_mcount_nc) | ||
150 | |||
151 | ENTRY(ftrace_caller) | ||
133 | stmdb sp!, {r0-r3, lr} | 152 | stmdb sp!, {r0-r3, lr} |
134 | mov r0, lr | 153 | mov r0, lr |
135 | sub r0, r0, #MCOUNT_INSN_SIZE | 154 | sub r0, r0, #MCOUNT_INSN_SIZE |
155 | ldr r1, [sp, #20] | ||
136 | 156 | ||
137 | .globl mcount_call | 157 | .global ftrace_call |
138 | mcount_call: | 158 | ftrace_call: |
139 | bl ftrace_stub | 159 | bl ftrace_stub |
140 | ldr lr, [fp, #-4] @ restore lr | 160 | ldmia sp!, {r0-r3, ip, lr} |
141 | ldmia sp!, {r0-r3, pc} | 161 | mov pc, ip |
162 | ENDPROC(ftrace_caller) | ||
142 | 163 | ||
143 | ENTRY(ftrace_caller) | 164 | #ifdef CONFIG_OLD_MCOUNT |
165 | ENTRY(mcount) | ||
166 | stmdb sp!, {lr} | ||
167 | ldr lr, [fp, #-4] | ||
168 | ldmia sp!, {pc} | ||
169 | ENDPROC(mcount) | ||
170 | |||
171 | ENTRY(ftrace_caller_old) | ||
144 | stmdb sp!, {r0-r3, lr} | 172 | stmdb sp!, {r0-r3, lr} |
145 | ldr r1, [fp, #-4] | 173 | ldr r1, [fp, #-4] |
146 | mov r0, lr | 174 | mov r0, lr |
147 | sub r0, r0, #MCOUNT_INSN_SIZE | 175 | sub r0, r0, #MCOUNT_INSN_SIZE |
148 | 176 | ||
149 | .globl ftrace_call | 177 | .globl ftrace_call_old |
150 | ftrace_call: | 178 | ftrace_call_old: |
151 | bl ftrace_stub | 179 | bl ftrace_stub |
152 | ldr lr, [fp, #-4] @ restore lr | 180 | ldr lr, [fp, #-4] @ restore lr |
153 | ldmia sp!, {r0-r3, pc} | 181 | ldmia sp!, {r0-r3, pc} |
182 | ENDPROC(ftrace_caller_old) | ||
183 | #endif | ||
154 | 184 | ||
155 | #else | 185 | #else |
156 | 186 | ||
@@ -158,7 +188,7 @@ ENTRY(__gnu_mcount_nc) | |||
158 | stmdb sp!, {r0-r3, lr} | 188 | stmdb sp!, {r0-r3, lr} |
159 | ldr r0, =ftrace_trace_function | 189 | ldr r0, =ftrace_trace_function |
160 | ldr r2, [r0] | 190 | ldr r2, [r0] |
161 | adr r0, ftrace_stub | 191 | adr r0, .Lftrace_stub |
162 | cmp r0, r2 | 192 | cmp r0, r2 |
163 | bne gnu_trace | 193 | bne gnu_trace |
164 | ldmia sp!, {r0-r3, ip, lr} | 194 | ldmia sp!, {r0-r3, ip, lr} |
@@ -168,11 +198,19 @@ gnu_trace: | |||
168 | ldr r1, [sp, #20] @ lr of instrumented routine | 198 | ldr r1, [sp, #20] @ lr of instrumented routine |
169 | mov r0, lr | 199 | mov r0, lr |
170 | sub r0, r0, #MCOUNT_INSN_SIZE | 200 | sub r0, r0, #MCOUNT_INSN_SIZE |
171 | mov lr, pc | 201 | adr lr, BSYM(1f) |
172 | mov pc, r2 | 202 | mov pc, r2 |
203 | 1: | ||
173 | ldmia sp!, {r0-r3, ip, lr} | 204 | ldmia sp!, {r0-r3, ip, lr} |
174 | mov pc, ip | 205 | mov pc, ip |
206 | ENDPROC(__gnu_mcount_nc) | ||
175 | 207 | ||
208 | #ifdef CONFIG_OLD_MCOUNT | ||
209 | /* | ||
210 | * This is under an ifdef in order to force link-time errors for people trying | ||
211 | * to build with !FRAME_POINTER with a GCC which doesn't use the new-style | ||
212 | * mcount. | ||
213 | */ | ||
176 | ENTRY(mcount) | 214 | ENTRY(mcount) |
177 | stmdb sp!, {r0-r3, lr} | 215 | stmdb sp!, {r0-r3, lr} |
178 | ldr r0, =ftrace_trace_function | 216 | ldr r0, =ftrace_trace_function |
@@ -191,12 +229,15 @@ trace: | |||
191 | mov pc, r2 | 229 | mov pc, r2 |
192 | ldr lr, [fp, #-4] @ restore lr | 230 | ldr lr, [fp, #-4] @ restore lr |
193 | ldmia sp!, {r0-r3, pc} | 231 | ldmia sp!, {r0-r3, pc} |
232 | ENDPROC(mcount) | ||
233 | #endif | ||
194 | 234 | ||
195 | #endif /* CONFIG_DYNAMIC_FTRACE */ | 235 | #endif /* CONFIG_DYNAMIC_FTRACE */ |
196 | 236 | ||
197 | .globl ftrace_stub | 237 | ENTRY(ftrace_stub) |
198 | ftrace_stub: | 238 | .Lftrace_stub: |
199 | mov pc, lr | 239 | mov pc, lr |
240 | ENDPROC(ftrace_stub) | ||
200 | 241 | ||
201 | #endif /* CONFIG_FUNCTION_TRACER */ | 242 | #endif /* CONFIG_FUNCTION_TRACER */ |
202 | 243 | ||
diff --git a/arch/arm/kernel/etm.c b/arch/arm/kernel/etm.c index 33c7077174db..a48d51257988 100644 --- a/arch/arm/kernel/etm.c +++ b/arch/arm/kernel/etm.c | |||
@@ -30,6 +30,21 @@ | |||
30 | MODULE_LICENSE("GPL"); | 30 | MODULE_LICENSE("GPL"); |
31 | MODULE_AUTHOR("Alexander Shishkin"); | 31 | MODULE_AUTHOR("Alexander Shishkin"); |
32 | 32 | ||
33 | /* | ||
34 | * ETM tracer state | ||
35 | */ | ||
36 | struct tracectx { | ||
37 | unsigned int etb_bufsz; | ||
38 | void __iomem *etb_regs; | ||
39 | void __iomem *etm_regs; | ||
40 | unsigned long flags; | ||
41 | int ncmppairs; | ||
42 | int etm_portsz; | ||
43 | struct device *dev; | ||
44 | struct clk *emu_clk; | ||
45 | struct mutex mutex; | ||
46 | }; | ||
47 | |||
33 | static struct tracectx tracer; | 48 | static struct tracectx tracer; |
34 | 49 | ||
35 | static inline bool trace_isrunning(struct tracectx *t) | 50 | static inline bool trace_isrunning(struct tracectx *t) |
diff --git a/arch/arm/kernel/ftrace.c b/arch/arm/kernel/ftrace.c index 0298286ad4ad..971ac8c36ea7 100644 --- a/arch/arm/kernel/ftrace.c +++ b/arch/arm/kernel/ftrace.c | |||
@@ -2,102 +2,194 @@ | |||
2 | * Dynamic function tracing support. | 2 | * Dynamic function tracing support. |
3 | * | 3 | * |
4 | * Copyright (C) 2008 Abhishek Sagar <sagar.abhishek@gmail.com> | 4 | * Copyright (C) 2008 Abhishek Sagar <sagar.abhishek@gmail.com> |
5 | * Copyright (C) 2010 Rabin Vincent <rabin@rab.in> | ||
5 | * | 6 | * |
6 | * For licencing details, see COPYING. | 7 | * For licencing details, see COPYING. |
7 | * | 8 | * |
8 | * Defines low-level handling of mcount calls when the kernel | 9 | * Defines low-level handling of mcount calls when the kernel |
9 | * is compiled with the -pg flag. When using dynamic ftrace, the | 10 | * is compiled with the -pg flag. When using dynamic ftrace, the |
10 | * mcount call-sites get patched lazily with NOP till they are | 11 | * mcount call-sites get patched with NOP till they are enabled. |
11 | * enabled. All code mutation routines here take effect atomically. | 12 | * All code mutation routines here are called under stop_machine(). |
12 | */ | 13 | */ |
13 | 14 | ||
14 | #include <linux/ftrace.h> | 15 | #include <linux/ftrace.h> |
16 | #include <linux/uaccess.h> | ||
15 | 17 | ||
16 | #include <asm/cacheflush.h> | 18 | #include <asm/cacheflush.h> |
17 | #include <asm/ftrace.h> | 19 | #include <asm/ftrace.h> |
18 | 20 | ||
19 | #define PC_OFFSET 8 | 21 | #ifdef CONFIG_THUMB2_KERNEL |
20 | #define BL_OPCODE 0xeb000000 | 22 | #define NOP 0xeb04f85d /* pop.w {lr} */ |
21 | #define BL_OFFSET_MASK 0x00ffffff | 23 | #else |
24 | #define NOP 0xe8bd4000 /* pop {lr} */ | ||
25 | #endif | ||
22 | 26 | ||
23 | static unsigned long bl_insn; | 27 | #ifdef CONFIG_OLD_MCOUNT |
24 | static const unsigned long NOP = 0xe1a00000; /* mov r0, r0 */ | 28 | #define OLD_MCOUNT_ADDR ((unsigned long) mcount) |
29 | #define OLD_FTRACE_ADDR ((unsigned long) ftrace_caller_old) | ||
25 | 30 | ||
26 | unsigned char *ftrace_nop_replace(void) | 31 | #define OLD_NOP 0xe1a00000 /* mov r0, r0 */ |
32 | |||
33 | static unsigned long ftrace_nop_replace(struct dyn_ftrace *rec) | ||
27 | { | 34 | { |
28 | return (char *)&NOP; | 35 | return rec->arch.old_mcount ? OLD_NOP : NOP; |
29 | } | 36 | } |
30 | 37 | ||
38 | static unsigned long adjust_address(struct dyn_ftrace *rec, unsigned long addr) | ||
39 | { | ||
40 | if (!rec->arch.old_mcount) | ||
41 | return addr; | ||
42 | |||
43 | if (addr == MCOUNT_ADDR) | ||
44 | addr = OLD_MCOUNT_ADDR; | ||
45 | else if (addr == FTRACE_ADDR) | ||
46 | addr = OLD_FTRACE_ADDR; | ||
47 | |||
48 | return addr; | ||
49 | } | ||
50 | #else | ||
51 | static unsigned long ftrace_nop_replace(struct dyn_ftrace *rec) | ||
52 | { | ||
53 | return NOP; | ||
54 | } | ||
55 | |||
56 | static unsigned long adjust_address(struct dyn_ftrace *rec, unsigned long addr) | ||
57 | { | ||
58 | return addr; | ||
59 | } | ||
60 | #endif | ||
61 | |||
31 | /* construct a branch (BL) instruction to addr */ | 62 | /* construct a branch (BL) instruction to addr */ |
32 | unsigned char *ftrace_call_replace(unsigned long pc, unsigned long addr) | 63 | #ifdef CONFIG_THUMB2_KERNEL |
64 | static unsigned long ftrace_call_replace(unsigned long pc, unsigned long addr) | ||
33 | { | 65 | { |
66 | unsigned long s, j1, j2, i1, i2, imm10, imm11; | ||
67 | unsigned long first, second; | ||
34 | long offset; | 68 | long offset; |
35 | 69 | ||
36 | offset = (long)addr - (long)(pc + PC_OFFSET); | 70 | offset = (long)addr - (long)(pc + 4); |
71 | if (offset < -16777216 || offset > 16777214) { | ||
72 | WARN_ON_ONCE(1); | ||
73 | return 0; | ||
74 | } | ||
75 | |||
76 | s = (offset >> 24) & 0x1; | ||
77 | i1 = (offset >> 23) & 0x1; | ||
78 | i2 = (offset >> 22) & 0x1; | ||
79 | imm10 = (offset >> 12) & 0x3ff; | ||
80 | imm11 = (offset >> 1) & 0x7ff; | ||
81 | |||
82 | j1 = (!i1) ^ s; | ||
83 | j2 = (!i2) ^ s; | ||
84 | |||
85 | first = 0xf000 | (s << 10) | imm10; | ||
86 | second = 0xd000 | (j1 << 13) | (j2 << 11) | imm11; | ||
87 | |||
88 | return (second << 16) | first; | ||
89 | } | ||
90 | #else | ||
91 | static unsigned long ftrace_call_replace(unsigned long pc, unsigned long addr) | ||
92 | { | ||
93 | long offset; | ||
94 | |||
95 | offset = (long)addr - (long)(pc + 8); | ||
37 | if (unlikely(offset < -33554432 || offset > 33554428)) { | 96 | if (unlikely(offset < -33554432 || offset > 33554428)) { |
38 | /* Can't generate branches that far (from ARM ARM). Ftrace | 97 | /* Can't generate branches that far (from ARM ARM). Ftrace |
39 | * doesn't generate branches outside of kernel text. | 98 | * doesn't generate branches outside of kernel text. |
40 | */ | 99 | */ |
41 | WARN_ON_ONCE(1); | 100 | WARN_ON_ONCE(1); |
42 | return NULL; | 101 | return 0; |
43 | } | 102 | } |
44 | offset = (offset >> 2) & BL_OFFSET_MASK; | ||
45 | bl_insn = BL_OPCODE | offset; | ||
46 | return (unsigned char *)&bl_insn; | ||
47 | } | ||
48 | 103 | ||
49 | int ftrace_modify_code(unsigned long pc, unsigned char *old_code, | 104 | offset = (offset >> 2) & 0x00ffffff; |
50 | unsigned char *new_code) | ||
51 | { | ||
52 | unsigned long err = 0, replaced = 0, old, new; | ||
53 | 105 | ||
54 | old = *(unsigned long *)old_code; | 106 | return 0xeb000000 | offset; |
55 | new = *(unsigned long *)new_code; | 107 | } |
108 | #endif | ||
56 | 109 | ||
57 | __asm__ __volatile__ ( | 110 | static int ftrace_modify_code(unsigned long pc, unsigned long old, |
58 | "1: ldr %1, [%2] \n" | 111 | unsigned long new) |
59 | " cmp %1, %4 \n" | 112 | { |
60 | "2: streq %3, [%2] \n" | 113 | unsigned long replaced; |
61 | " cmpne %1, %3 \n" | ||
62 | " movne %0, #2 \n" | ||
63 | "3:\n" | ||
64 | 114 | ||
65 | ".pushsection .fixup, \"ax\"\n" | 115 | if (probe_kernel_read(&replaced, (void *)pc, MCOUNT_INSN_SIZE)) |
66 | "4: mov %0, #1 \n" | 116 | return -EFAULT; |
67 | " b 3b \n" | ||
68 | ".popsection\n" | ||
69 | 117 | ||
70 | ".pushsection __ex_table, \"a\"\n" | 118 | if (replaced != old) |
71 | " .long 1b, 4b \n" | 119 | return -EINVAL; |
72 | " .long 2b, 4b \n" | ||
73 | ".popsection\n" | ||
74 | 120 | ||
75 | : "=r"(err), "=r"(replaced) | 121 | if (probe_kernel_write((void *)pc, &new, MCOUNT_INSN_SIZE)) |
76 | : "r"(pc), "r"(new), "r"(old), "0"(err), "1"(replaced) | 122 | return -EPERM; |
77 | : "memory"); | ||
78 | 123 | ||
79 | if (!err && (replaced == old)) | 124 | flush_icache_range(pc, pc + MCOUNT_INSN_SIZE); |
80 | flush_icache_range(pc, pc + MCOUNT_INSN_SIZE); | ||
81 | 125 | ||
82 | return err; | 126 | return 0; |
83 | } | 127 | } |
84 | 128 | ||
85 | int ftrace_update_ftrace_func(ftrace_func_t func) | 129 | int ftrace_update_ftrace_func(ftrace_func_t func) |
86 | { | 130 | { |
87 | int ret; | ||
88 | unsigned long pc, old; | 131 | unsigned long pc, old; |
89 | unsigned char *new; | 132 | unsigned long new; |
133 | int ret; | ||
90 | 134 | ||
91 | pc = (unsigned long)&ftrace_call; | 135 | pc = (unsigned long)&ftrace_call; |
92 | memcpy(&old, &ftrace_call, MCOUNT_INSN_SIZE); | 136 | memcpy(&old, &ftrace_call, MCOUNT_INSN_SIZE); |
93 | new = ftrace_call_replace(pc, (unsigned long)func); | 137 | new = ftrace_call_replace(pc, (unsigned long)func); |
94 | ret = ftrace_modify_code(pc, (unsigned char *)&old, new); | 138 | |
139 | ret = ftrace_modify_code(pc, old, new); | ||
140 | |||
141 | #ifdef CONFIG_OLD_MCOUNT | ||
142 | if (!ret) { | ||
143 | pc = (unsigned long)&ftrace_call_old; | ||
144 | memcpy(&old, &ftrace_call_old, MCOUNT_INSN_SIZE); | ||
145 | new = ftrace_call_replace(pc, (unsigned long)func); | ||
146 | |||
147 | ret = ftrace_modify_code(pc, old, new); | ||
148 | } | ||
149 | #endif | ||
150 | |||
151 | return ret; | ||
152 | } | ||
153 | |||
154 | int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) | ||
155 | { | ||
156 | unsigned long new, old; | ||
157 | unsigned long ip = rec->ip; | ||
158 | |||
159 | old = ftrace_nop_replace(rec); | ||
160 | new = ftrace_call_replace(ip, adjust_address(rec, addr)); | ||
161 | |||
162 | return ftrace_modify_code(rec->ip, old, new); | ||
163 | } | ||
164 | |||
165 | int ftrace_make_nop(struct module *mod, | ||
166 | struct dyn_ftrace *rec, unsigned long addr) | ||
167 | { | ||
168 | unsigned long ip = rec->ip; | ||
169 | unsigned long old; | ||
170 | unsigned long new; | ||
171 | int ret; | ||
172 | |||
173 | old = ftrace_call_replace(ip, adjust_address(rec, addr)); | ||
174 | new = ftrace_nop_replace(rec); | ||
175 | ret = ftrace_modify_code(ip, old, new); | ||
176 | |||
177 | #ifdef CONFIG_OLD_MCOUNT | ||
178 | if (ret == -EINVAL && addr == MCOUNT_ADDR) { | ||
179 | rec->arch.old_mcount = true; | ||
180 | |||
181 | old = ftrace_call_replace(ip, adjust_address(rec, addr)); | ||
182 | new = ftrace_nop_replace(rec); | ||
183 | ret = ftrace_modify_code(ip, old, new); | ||
184 | } | ||
185 | #endif | ||
186 | |||
95 | return ret; | 187 | return ret; |
96 | } | 188 | } |
97 | 189 | ||
98 | /* run from ftrace_init with irqs disabled */ | ||
99 | int __init ftrace_dyn_arch_init(void *data) | 190 | int __init ftrace_dyn_arch_init(void *data) |
100 | { | 191 | { |
101 | ftrace_mcount_set(data); | 192 | *(unsigned long *)data = 0; |
193 | |||
102 | return 0; | 194 | return 0; |
103 | } | 195 | } |
diff --git a/arch/arm/kernel/head-common.S b/arch/arm/kernel/head-common.S index b9505aa267c0..58a3e632b6d5 100644 --- a/arch/arm/kernel/head-common.S +++ b/arch/arm/kernel/head-common.S | |||
@@ -20,7 +20,7 @@ | |||
20 | __switch_data: | 20 | __switch_data: |
21 | .long __mmap_switched | 21 | .long __mmap_switched |
22 | .long __data_loc @ r4 | 22 | .long __data_loc @ r4 |
23 | .long _data @ r5 | 23 | .long _sdata @ r5 |
24 | .long __bss_start @ r6 | 24 | .long __bss_start @ r6 |
25 | .long _end @ r7 | 25 | .long _end @ r7 |
26 | .long processor_id @ r4 | 26 | .long processor_id @ r4 |
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S index eb62bf947212..b44d21e1e344 100644 --- a/arch/arm/kernel/head.S +++ b/arch/arm/kernel/head.S | |||
@@ -86,6 +86,9 @@ ENTRY(stext) | |||
86 | movs r8, r5 @ invalid machine (r5=0)? | 86 | movs r8, r5 @ invalid machine (r5=0)? |
87 | beq __error_a @ yes, error 'a' | 87 | beq __error_a @ yes, error 'a' |
88 | bl __vet_atags | 88 | bl __vet_atags |
89 | #ifdef CONFIG_SMP_ON_UP | ||
90 | bl __fixup_smp | ||
91 | #endif | ||
89 | bl __create_page_tables | 92 | bl __create_page_tables |
90 | 93 | ||
91 | /* | 94 | /* |
@@ -333,4 +336,51 @@ __create_page_tables: | |||
333 | ENDPROC(__create_page_tables) | 336 | ENDPROC(__create_page_tables) |
334 | .ltorg | 337 | .ltorg |
335 | 338 | ||
339 | #ifdef CONFIG_SMP_ON_UP | ||
340 | __fixup_smp: | ||
341 | mov r7, #0x00070000 | ||
342 | orr r6, r7, #0xff000000 @ mask 0xff070000 | ||
343 | orr r7, r7, #0x41000000 @ val 0x41070000 | ||
344 | and r0, r9, r6 | ||
345 | teq r0, r7 @ ARM CPU and ARMv6/v7? | ||
346 | bne __fixup_smp_on_up @ no, assume UP | ||
347 | |||
348 | orr r6, r6, #0x0000ff00 | ||
349 | orr r6, r6, #0x000000f0 @ mask 0xff07fff0 | ||
350 | orr r7, r7, #0x0000b000 | ||
351 | orr r7, r7, #0x00000020 @ val 0x4107b020 | ||
352 | and r0, r9, r6 | ||
353 | teq r0, r7 @ ARM 11MPCore? | ||
354 | moveq pc, lr @ yes, assume SMP | ||
355 | |||
356 | mrc p15, 0, r0, c0, c0, 5 @ read MPIDR | ||
357 | tst r0, #1 << 31 | ||
358 | movne pc, lr @ bit 31 => SMP | ||
359 | |||
360 | __fixup_smp_on_up: | ||
361 | adr r0, 1f | ||
362 | ldmia r0, {r3, r6, r7} | ||
363 | sub r3, r0, r3 | ||
364 | add r6, r6, r3 | ||
365 | add r7, r7, r3 | ||
366 | 2: cmp r6, r7 | ||
367 | ldmia r6!, {r0, r4} | ||
368 | strlo r4, [r0, r3] | ||
369 | blo 2b | ||
370 | mov pc, lr | ||
371 | ENDPROC(__fixup_smp) | ||
372 | |||
373 | 1: .word . | ||
374 | .word __smpalt_begin | ||
375 | .word __smpalt_end | ||
376 | |||
377 | .pushsection .data | ||
378 | .globl smp_on_up | ||
379 | smp_on_up: | ||
380 | ALT_SMP(.long 1) | ||
381 | ALT_UP(.long 0) | ||
382 | .popsection | ||
383 | |||
384 | #endif | ||
385 | |||
336 | #include "head-common.S" | 386 | #include "head-common.S" |
diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c new file mode 100644 index 000000000000..54593b0c241b --- /dev/null +++ b/arch/arm/kernel/hw_breakpoint.c | |||
@@ -0,0 +1,849 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify | ||
3 | * it under the terms of the GNU General Public License version 2 as | ||
4 | * published by the Free Software Foundation. | ||
5 | * | ||
6 | * This program is distributed in the hope that it will be useful, | ||
7 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
8 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
9 | * GNU General Public License for more details. | ||
10 | * | ||
11 | * You should have received a copy of the GNU General Public License | ||
12 | * along with this program; if not, write to the Free Software | ||
13 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
14 | * | ||
15 | * Copyright (C) 2009, 2010 ARM Limited | ||
16 | * | ||
17 | * Author: Will Deacon <will.deacon@arm.com> | ||
18 | */ | ||
19 | |||
20 | /* | ||
21 | * HW_breakpoint: a unified kernel/user-space hardware breakpoint facility, | ||
22 | * using the CPU's debug registers. | ||
23 | */ | ||
24 | #define pr_fmt(fmt) "hw-breakpoint: " fmt | ||
25 | |||
26 | #include <linux/errno.h> | ||
27 | #include <linux/perf_event.h> | ||
28 | #include <linux/hw_breakpoint.h> | ||
29 | #include <linux/smp.h> | ||
30 | |||
31 | #include <asm/cacheflush.h> | ||
32 | #include <asm/cputype.h> | ||
33 | #include <asm/current.h> | ||
34 | #include <asm/hw_breakpoint.h> | ||
35 | #include <asm/kdebug.h> | ||
36 | #include <asm/system.h> | ||
37 | #include <asm/traps.h> | ||
38 | |||
39 | /* Breakpoint currently in use for each BRP. */ | ||
40 | static DEFINE_PER_CPU(struct perf_event *, bp_on_reg[ARM_MAX_BRP]); | ||
41 | |||
42 | /* Watchpoint currently in use for each WRP. */ | ||
43 | static DEFINE_PER_CPU(struct perf_event *, wp_on_reg[ARM_MAX_WRP]); | ||
44 | |||
45 | /* Number of BRP/WRP registers on this CPU. */ | ||
46 | static int core_num_brps; | ||
47 | static int core_num_wrps; | ||
48 | |||
49 | /* Debug architecture version. */ | ||
50 | static u8 debug_arch; | ||
51 | |||
52 | /* Maximum supported watchpoint length. */ | ||
53 | static u8 max_watchpoint_len; | ||
54 | |||
55 | /* Determine number of BRP registers available. */ | ||
56 | static int get_num_brps(void) | ||
57 | { | ||
58 | u32 didr; | ||
59 | ARM_DBG_READ(c0, 0, didr); | ||
60 | return ((didr >> 24) & 0xf) + 1; | ||
61 | } | ||
62 | |||
63 | /* Determine number of WRP registers available. */ | ||
64 | static int get_num_wrps(void) | ||
65 | { | ||
66 | /* | ||
67 | * FIXME: When a watchpoint fires, the only way to work out which | ||
68 | * watchpoint it was is by disassembling the faulting instruction | ||
69 | * and working out the address of the memory access. | ||
70 | * | ||
71 | * Furthermore, we can only do this if the watchpoint was precise | ||
72 | * since imprecise watchpoints prevent us from calculating register | ||
73 | * based addresses. | ||
74 | * | ||
75 | * For the time being, we only report 1 watchpoint register so we | ||
76 | * always know which watchpoint fired. In the future we can either | ||
77 | * add a disassembler and address generation emulator, or we can | ||
78 | * insert a check to see if the DFAR is set on watchpoint exception | ||
79 | * entry [the ARM ARM states that the DFAR is UNKNOWN, but | ||
80 | * experience shows that it is set on some implementations]. | ||
81 | */ | ||
82 | |||
83 | #if 0 | ||
84 | u32 didr, wrps; | ||
85 | ARM_DBG_READ(c0, 0, didr); | ||
86 | return ((didr >> 28) & 0xf) + 1; | ||
87 | #endif | ||
88 | |||
89 | return 1; | ||
90 | } | ||
91 | |||
92 | int hw_breakpoint_slots(int type) | ||
93 | { | ||
94 | /* | ||
95 | * We can be called early, so don't rely on | ||
96 | * our static variables being initialised. | ||
97 | */ | ||
98 | switch (type) { | ||
99 | case TYPE_INST: | ||
100 | return get_num_brps(); | ||
101 | case TYPE_DATA: | ||
102 | return get_num_wrps(); | ||
103 | default: | ||
104 | pr_warning("unknown slot type: %d\n", type); | ||
105 | return 0; | ||
106 | } | ||
107 | } | ||
108 | |||
109 | /* Determine debug architecture. */ | ||
110 | static u8 get_debug_arch(void) | ||
111 | { | ||
112 | u32 didr; | ||
113 | |||
114 | /* Do we implement the extended CPUID interface? */ | ||
115 | if (((read_cpuid_id() >> 16) & 0xf) != 0xf) { | ||
116 | pr_warning("CPUID feature registers not supported. " | ||
117 | "Assuming v6 debug is present.\n"); | ||
118 | return ARM_DEBUG_ARCH_V6; | ||
119 | } | ||
120 | |||
121 | ARM_DBG_READ(c0, 0, didr); | ||
122 | return (didr >> 16) & 0xf; | ||
123 | } | ||
124 | |||
125 | /* Does this core support mismatch breakpoints? */ | ||
126 | static int core_has_mismatch_bps(void) | ||
127 | { | ||
128 | return debug_arch >= ARM_DEBUG_ARCH_V7_ECP14 && core_num_brps > 1; | ||
129 | } | ||
130 | |||
131 | u8 arch_get_debug_arch(void) | ||
132 | { | ||
133 | return debug_arch; | ||
134 | } | ||
135 | |||
136 | #define READ_WB_REG_CASE(OP2, M, VAL) \ | ||
137 | case ((OP2 << 4) + M): \ | ||
138 | ARM_DBG_READ(c ## M, OP2, VAL); \ | ||
139 | break | ||
140 | |||
141 | #define WRITE_WB_REG_CASE(OP2, M, VAL) \ | ||
142 | case ((OP2 << 4) + M): \ | ||
143 | ARM_DBG_WRITE(c ## M, OP2, VAL);\ | ||
144 | break | ||
145 | |||
146 | #define GEN_READ_WB_REG_CASES(OP2, VAL) \ | ||
147 | READ_WB_REG_CASE(OP2, 0, VAL); \ | ||
148 | READ_WB_REG_CASE(OP2, 1, VAL); \ | ||
149 | READ_WB_REG_CASE(OP2, 2, VAL); \ | ||
150 | READ_WB_REG_CASE(OP2, 3, VAL); \ | ||
151 | READ_WB_REG_CASE(OP2, 4, VAL); \ | ||
152 | READ_WB_REG_CASE(OP2, 5, VAL); \ | ||
153 | READ_WB_REG_CASE(OP2, 6, VAL); \ | ||
154 | READ_WB_REG_CASE(OP2, 7, VAL); \ | ||
155 | READ_WB_REG_CASE(OP2, 8, VAL); \ | ||
156 | READ_WB_REG_CASE(OP2, 9, VAL); \ | ||
157 | READ_WB_REG_CASE(OP2, 10, VAL); \ | ||
158 | READ_WB_REG_CASE(OP2, 11, VAL); \ | ||
159 | READ_WB_REG_CASE(OP2, 12, VAL); \ | ||
160 | READ_WB_REG_CASE(OP2, 13, VAL); \ | ||
161 | READ_WB_REG_CASE(OP2, 14, VAL); \ | ||
162 | READ_WB_REG_CASE(OP2, 15, VAL) | ||
163 | |||
164 | #define GEN_WRITE_WB_REG_CASES(OP2, VAL) \ | ||
165 | WRITE_WB_REG_CASE(OP2, 0, VAL); \ | ||
166 | WRITE_WB_REG_CASE(OP2, 1, VAL); \ | ||
167 | WRITE_WB_REG_CASE(OP2, 2, VAL); \ | ||
168 | WRITE_WB_REG_CASE(OP2, 3, VAL); \ | ||
169 | WRITE_WB_REG_CASE(OP2, 4, VAL); \ | ||
170 | WRITE_WB_REG_CASE(OP2, 5, VAL); \ | ||
171 | WRITE_WB_REG_CASE(OP2, 6, VAL); \ | ||
172 | WRITE_WB_REG_CASE(OP2, 7, VAL); \ | ||
173 | WRITE_WB_REG_CASE(OP2, 8, VAL); \ | ||
174 | WRITE_WB_REG_CASE(OP2, 9, VAL); \ | ||
175 | WRITE_WB_REG_CASE(OP2, 10, VAL); \ | ||
176 | WRITE_WB_REG_CASE(OP2, 11, VAL); \ | ||
177 | WRITE_WB_REG_CASE(OP2, 12, VAL); \ | ||
178 | WRITE_WB_REG_CASE(OP2, 13, VAL); \ | ||
179 | WRITE_WB_REG_CASE(OP2, 14, VAL); \ | ||
180 | WRITE_WB_REG_CASE(OP2, 15, VAL) | ||
181 | |||
182 | static u32 read_wb_reg(int n) | ||
183 | { | ||
184 | u32 val = 0; | ||
185 | |||
186 | switch (n) { | ||
187 | GEN_READ_WB_REG_CASES(ARM_OP2_BVR, val); | ||
188 | GEN_READ_WB_REG_CASES(ARM_OP2_BCR, val); | ||
189 | GEN_READ_WB_REG_CASES(ARM_OP2_WVR, val); | ||
190 | GEN_READ_WB_REG_CASES(ARM_OP2_WCR, val); | ||
191 | default: | ||
192 | pr_warning("attempt to read from unknown breakpoint " | ||
193 | "register %d\n", n); | ||
194 | } | ||
195 | |||
196 | return val; | ||
197 | } | ||
198 | |||
199 | static void write_wb_reg(int n, u32 val) | ||
200 | { | ||
201 | switch (n) { | ||
202 | GEN_WRITE_WB_REG_CASES(ARM_OP2_BVR, val); | ||
203 | GEN_WRITE_WB_REG_CASES(ARM_OP2_BCR, val); | ||
204 | GEN_WRITE_WB_REG_CASES(ARM_OP2_WVR, val); | ||
205 | GEN_WRITE_WB_REG_CASES(ARM_OP2_WCR, val); | ||
206 | default: | ||
207 | pr_warning("attempt to write to unknown breakpoint " | ||
208 | "register %d\n", n); | ||
209 | } | ||
210 | isb(); | ||
211 | } | ||
212 | |||
213 | /* | ||
214 | * In order to access the breakpoint/watchpoint control registers, | ||
215 | * we must be running in debug monitor mode. Unfortunately, we can | ||
216 | * be put into halting debug mode at any time by an external debugger | ||
217 | * but there is nothing we can do to prevent that. | ||
218 | */ | ||
219 | static int enable_monitor_mode(void) | ||
220 | { | ||
221 | u32 dscr; | ||
222 | int ret = 0; | ||
223 | |||
224 | ARM_DBG_READ(c1, 0, dscr); | ||
225 | |||
226 | /* Ensure that halting mode is disabled. */ | ||
227 | if (WARN_ONCE(dscr & ARM_DSCR_HDBGEN, "halting debug mode enabled." | ||
228 | "Unable to access hardware resources.")) { | ||
229 | ret = -EPERM; | ||
230 | goto out; | ||
231 | } | ||
232 | |||
233 | /* Write to the corresponding DSCR. */ | ||
234 | switch (debug_arch) { | ||
235 | case ARM_DEBUG_ARCH_V6: | ||
236 | case ARM_DEBUG_ARCH_V6_1: | ||
237 | ARM_DBG_WRITE(c1, 0, (dscr | ARM_DSCR_MDBGEN)); | ||
238 | break; | ||
239 | case ARM_DEBUG_ARCH_V7_ECP14: | ||
240 | ARM_DBG_WRITE(c2, 2, (dscr | ARM_DSCR_MDBGEN)); | ||
241 | break; | ||
242 | default: | ||
243 | ret = -ENODEV; | ||
244 | goto out; | ||
245 | } | ||
246 | |||
247 | /* Check that the write made it through. */ | ||
248 | ARM_DBG_READ(c1, 0, dscr); | ||
249 | if (WARN_ONCE(!(dscr & ARM_DSCR_MDBGEN), | ||
250 | "failed to enable monitor mode.")) { | ||
251 | ret = -EPERM; | ||
252 | } | ||
253 | |||
254 | out: | ||
255 | return ret; | ||
256 | } | ||
257 | |||
258 | /* | ||
259 | * Check if 8-bit byte-address select is available. | ||
260 | * This clobbers WRP 0. | ||
261 | */ | ||
262 | static u8 get_max_wp_len(void) | ||
263 | { | ||
264 | u32 ctrl_reg; | ||
265 | struct arch_hw_breakpoint_ctrl ctrl; | ||
266 | u8 size = 4; | ||
267 | |||
268 | if (debug_arch < ARM_DEBUG_ARCH_V7_ECP14) | ||
269 | goto out; | ||
270 | |||
271 | if (enable_monitor_mode()) | ||
272 | goto out; | ||
273 | |||
274 | memset(&ctrl, 0, sizeof(ctrl)); | ||
275 | ctrl.len = ARM_BREAKPOINT_LEN_8; | ||
276 | ctrl_reg = encode_ctrl_reg(ctrl); | ||
277 | |||
278 | write_wb_reg(ARM_BASE_WVR, 0); | ||
279 | write_wb_reg(ARM_BASE_WCR, ctrl_reg); | ||
280 | if ((read_wb_reg(ARM_BASE_WCR) & ctrl_reg) == ctrl_reg) | ||
281 | size = 8; | ||
282 | |||
283 | out: | ||
284 | return size; | ||
285 | } | ||
286 | |||
287 | u8 arch_get_max_wp_len(void) | ||
288 | { | ||
289 | return max_watchpoint_len; | ||
290 | } | ||
291 | |||
292 | /* | ||
293 | * Handler for reactivating a suspended watchpoint when the single | ||
294 | * step `mismatch' breakpoint is triggered. | ||
295 | */ | ||
296 | static void wp_single_step_handler(struct perf_event *bp, int unused, | ||
297 | struct perf_sample_data *data, | ||
298 | struct pt_regs *regs) | ||
299 | { | ||
300 | perf_event_enable(counter_arch_bp(bp)->suspended_wp); | ||
301 | unregister_hw_breakpoint(bp); | ||
302 | } | ||
303 | |||
304 | static int bp_is_single_step(struct perf_event *bp) | ||
305 | { | ||
306 | return bp->overflow_handler == wp_single_step_handler; | ||
307 | } | ||
308 | |||
309 | /* | ||
310 | * Install a perf counter breakpoint. | ||
311 | */ | ||
312 | int arch_install_hw_breakpoint(struct perf_event *bp) | ||
313 | { | ||
314 | struct arch_hw_breakpoint *info = counter_arch_bp(bp); | ||
315 | struct perf_event **slot, **slots; | ||
316 | int i, max_slots, ctrl_base, val_base, ret = 0; | ||
317 | |||
318 | /* Ensure that we are in monitor mode and halting mode is disabled. */ | ||
319 | ret = enable_monitor_mode(); | ||
320 | if (ret) | ||
321 | goto out; | ||
322 | |||
323 | if (info->ctrl.type == ARM_BREAKPOINT_EXECUTE) { | ||
324 | /* Breakpoint */ | ||
325 | ctrl_base = ARM_BASE_BCR; | ||
326 | val_base = ARM_BASE_BVR; | ||
327 | slots = __get_cpu_var(bp_on_reg); | ||
328 | max_slots = core_num_brps - 1; | ||
329 | |||
330 | if (bp_is_single_step(bp)) { | ||
331 | info->ctrl.mismatch = 1; | ||
332 | i = max_slots; | ||
333 | slots[i] = bp; | ||
334 | goto setup; | ||
335 | } | ||
336 | } else { | ||
337 | /* Watchpoint */ | ||
338 | ctrl_base = ARM_BASE_WCR; | ||
339 | val_base = ARM_BASE_WVR; | ||
340 | slots = __get_cpu_var(wp_on_reg); | ||
341 | max_slots = core_num_wrps; | ||
342 | } | ||
343 | |||
344 | for (i = 0; i < max_slots; ++i) { | ||
345 | slot = &slots[i]; | ||
346 | |||
347 | if (!*slot) { | ||
348 | *slot = bp; | ||
349 | break; | ||
350 | } | ||
351 | } | ||
352 | |||
353 | if (WARN_ONCE(i == max_slots, "Can't find any breakpoint slot")) { | ||
354 | ret = -EBUSY; | ||
355 | goto out; | ||
356 | } | ||
357 | |||
358 | setup: | ||
359 | /* Setup the address register. */ | ||
360 | write_wb_reg(val_base + i, info->address); | ||
361 | |||
362 | /* Setup the control register. */ | ||
363 | write_wb_reg(ctrl_base + i, encode_ctrl_reg(info->ctrl) | 0x1); | ||
364 | |||
365 | out: | ||
366 | return ret; | ||
367 | } | ||
368 | |||
369 | void arch_uninstall_hw_breakpoint(struct perf_event *bp) | ||
370 | { | ||
371 | struct arch_hw_breakpoint *info = counter_arch_bp(bp); | ||
372 | struct perf_event **slot, **slots; | ||
373 | int i, max_slots, base; | ||
374 | |||
375 | if (info->ctrl.type == ARM_BREAKPOINT_EXECUTE) { | ||
376 | /* Breakpoint */ | ||
377 | base = ARM_BASE_BCR; | ||
378 | slots = __get_cpu_var(bp_on_reg); | ||
379 | max_slots = core_num_brps - 1; | ||
380 | |||
381 | if (bp_is_single_step(bp)) { | ||
382 | i = max_slots; | ||
383 | slots[i] = NULL; | ||
384 | goto reset; | ||
385 | } | ||
386 | } else { | ||
387 | /* Watchpoint */ | ||
388 | base = ARM_BASE_WCR; | ||
389 | slots = __get_cpu_var(wp_on_reg); | ||
390 | max_slots = core_num_wrps; | ||
391 | } | ||
392 | |||
393 | /* Remove the breakpoint. */ | ||
394 | for (i = 0; i < max_slots; ++i) { | ||
395 | slot = &slots[i]; | ||
396 | |||
397 | if (*slot == bp) { | ||
398 | *slot = NULL; | ||
399 | break; | ||
400 | } | ||
401 | } | ||
402 | |||
403 | if (WARN_ONCE(i == max_slots, "Can't find any breakpoint slot")) | ||
404 | return; | ||
405 | |||
406 | reset: | ||
407 | /* Reset the control register. */ | ||
408 | write_wb_reg(base + i, 0); | ||
409 | } | ||
410 | |||
411 | static int get_hbp_len(u8 hbp_len) | ||
412 | { | ||
413 | unsigned int len_in_bytes = 0; | ||
414 | |||
415 | switch (hbp_len) { | ||
416 | case ARM_BREAKPOINT_LEN_1: | ||
417 | len_in_bytes = 1; | ||
418 | break; | ||
419 | case ARM_BREAKPOINT_LEN_2: | ||
420 | len_in_bytes = 2; | ||
421 | break; | ||
422 | case ARM_BREAKPOINT_LEN_4: | ||
423 | len_in_bytes = 4; | ||
424 | break; | ||
425 | case ARM_BREAKPOINT_LEN_8: | ||
426 | len_in_bytes = 8; | ||
427 | break; | ||
428 | } | ||
429 | |||
430 | return len_in_bytes; | ||
431 | } | ||
432 | |||
433 | /* | ||
434 | * Check whether bp virtual address is in kernel space. | ||
435 | */ | ||
436 | int arch_check_bp_in_kernelspace(struct perf_event *bp) | ||
437 | { | ||
438 | unsigned int len; | ||
439 | unsigned long va; | ||
440 | struct arch_hw_breakpoint *info = counter_arch_bp(bp); | ||
441 | |||
442 | va = info->address; | ||
443 | len = get_hbp_len(info->ctrl.len); | ||
444 | |||
445 | return (va >= TASK_SIZE) && ((va + len - 1) >= TASK_SIZE); | ||
446 | } | ||
447 | |||
448 | /* | ||
449 | * Extract generic type and length encodings from an arch_hw_breakpoint_ctrl. | ||
450 | * Hopefully this will disappear when ptrace can bypass the conversion | ||
451 | * to generic breakpoint descriptions. | ||
452 | */ | ||
453 | int arch_bp_generic_fields(struct arch_hw_breakpoint_ctrl ctrl, | ||
454 | int *gen_len, int *gen_type) | ||
455 | { | ||
456 | /* Type */ | ||
457 | switch (ctrl.type) { | ||
458 | case ARM_BREAKPOINT_EXECUTE: | ||
459 | *gen_type = HW_BREAKPOINT_X; | ||
460 | break; | ||
461 | case ARM_BREAKPOINT_LOAD: | ||
462 | *gen_type = HW_BREAKPOINT_R; | ||
463 | break; | ||
464 | case ARM_BREAKPOINT_STORE: | ||
465 | *gen_type = HW_BREAKPOINT_W; | ||
466 | break; | ||
467 | case ARM_BREAKPOINT_LOAD | ARM_BREAKPOINT_STORE: | ||
468 | *gen_type = HW_BREAKPOINT_RW; | ||
469 | break; | ||
470 | default: | ||
471 | return -EINVAL; | ||
472 | } | ||
473 | |||
474 | /* Len */ | ||
475 | switch (ctrl.len) { | ||
476 | case ARM_BREAKPOINT_LEN_1: | ||
477 | *gen_len = HW_BREAKPOINT_LEN_1; | ||
478 | break; | ||
479 | case ARM_BREAKPOINT_LEN_2: | ||
480 | *gen_len = HW_BREAKPOINT_LEN_2; | ||
481 | break; | ||
482 | case ARM_BREAKPOINT_LEN_4: | ||
483 | *gen_len = HW_BREAKPOINT_LEN_4; | ||
484 | break; | ||
485 | case ARM_BREAKPOINT_LEN_8: | ||
486 | *gen_len = HW_BREAKPOINT_LEN_8; | ||
487 | break; | ||
488 | default: | ||
489 | return -EINVAL; | ||
490 | } | ||
491 | |||
492 | return 0; | ||
493 | } | ||
494 | |||
495 | /* | ||
496 | * Construct an arch_hw_breakpoint from a perf_event. | ||
497 | */ | ||
498 | static int arch_build_bp_info(struct perf_event *bp) | ||
499 | { | ||
500 | struct arch_hw_breakpoint *info = counter_arch_bp(bp); | ||
501 | |||
502 | /* Type */ | ||
503 | switch (bp->attr.bp_type) { | ||
504 | case HW_BREAKPOINT_X: | ||
505 | info->ctrl.type = ARM_BREAKPOINT_EXECUTE; | ||
506 | break; | ||
507 | case HW_BREAKPOINT_R: | ||
508 | info->ctrl.type = ARM_BREAKPOINT_LOAD; | ||
509 | break; | ||
510 | case HW_BREAKPOINT_W: | ||
511 | info->ctrl.type = ARM_BREAKPOINT_STORE; | ||
512 | break; | ||
513 | case HW_BREAKPOINT_RW: | ||
514 | info->ctrl.type = ARM_BREAKPOINT_LOAD | ARM_BREAKPOINT_STORE; | ||
515 | break; | ||
516 | default: | ||
517 | return -EINVAL; | ||
518 | } | ||
519 | |||
520 | /* Len */ | ||
521 | switch (bp->attr.bp_len) { | ||
522 | case HW_BREAKPOINT_LEN_1: | ||
523 | info->ctrl.len = ARM_BREAKPOINT_LEN_1; | ||
524 | break; | ||
525 | case HW_BREAKPOINT_LEN_2: | ||
526 | info->ctrl.len = ARM_BREAKPOINT_LEN_2; | ||
527 | break; | ||
528 | case HW_BREAKPOINT_LEN_4: | ||
529 | info->ctrl.len = ARM_BREAKPOINT_LEN_4; | ||
530 | break; | ||
531 | case HW_BREAKPOINT_LEN_8: | ||
532 | info->ctrl.len = ARM_BREAKPOINT_LEN_8; | ||
533 | if ((info->ctrl.type != ARM_BREAKPOINT_EXECUTE) | ||
534 | && max_watchpoint_len >= 8) | ||
535 | break; | ||
536 | default: | ||
537 | return -EINVAL; | ||
538 | } | ||
539 | |||
540 | /* Address */ | ||
541 | info->address = bp->attr.bp_addr; | ||
542 | |||
543 | /* Privilege */ | ||
544 | info->ctrl.privilege = ARM_BREAKPOINT_USER; | ||
545 | if (arch_check_bp_in_kernelspace(bp) && !bp_is_single_step(bp)) | ||
546 | info->ctrl.privilege |= ARM_BREAKPOINT_PRIV; | ||
547 | |||
548 | /* Enabled? */ | ||
549 | info->ctrl.enabled = !bp->attr.disabled; | ||
550 | |||
551 | /* Mismatch */ | ||
552 | info->ctrl.mismatch = 0; | ||
553 | |||
554 | return 0; | ||
555 | } | ||
556 | |||
557 | /* | ||
558 | * Validate the arch-specific HW Breakpoint register settings. | ||
559 | */ | ||
560 | int arch_validate_hwbkpt_settings(struct perf_event *bp) | ||
561 | { | ||
562 | struct arch_hw_breakpoint *info = counter_arch_bp(bp); | ||
563 | int ret = 0; | ||
564 | u32 bytelen, max_len, offset, alignment_mask = 0x3; | ||
565 | |||
566 | /* Build the arch_hw_breakpoint. */ | ||
567 | ret = arch_build_bp_info(bp); | ||
568 | if (ret) | ||
569 | goto out; | ||
570 | |||
571 | /* Check address alignment. */ | ||
572 | if (info->ctrl.len == ARM_BREAKPOINT_LEN_8) | ||
573 | alignment_mask = 0x7; | ||
574 | if (info->address & alignment_mask) { | ||
575 | /* | ||
576 | * Try to fix the alignment. This may result in a length | ||
577 | * that is too large, so we must check for that. | ||
578 | */ | ||
579 | bytelen = get_hbp_len(info->ctrl.len); | ||
580 | max_len = info->ctrl.type == ARM_BREAKPOINT_EXECUTE ? 4 : | ||
581 | max_watchpoint_len; | ||
582 | |||
583 | if (max_len >= 8) | ||
584 | offset = info->address & 0x7; | ||
585 | else | ||
586 | offset = info->address & 0x3; | ||
587 | |||
588 | if (bytelen > (1 << ((max_len - (offset + 1)) >> 1))) { | ||
589 | ret = -EFBIG; | ||
590 | goto out; | ||
591 | } | ||
592 | |||
593 | info->ctrl.len <<= offset; | ||
594 | info->address &= ~offset; | ||
595 | |||
596 | pr_debug("breakpoint alignment fixup: length = 0x%x, " | ||
597 | "address = 0x%x\n", info->ctrl.len, info->address); | ||
598 | } | ||
599 | |||
600 | /* | ||
601 | * Currently we rely on an overflow handler to take | ||
602 | * care of single-stepping the breakpoint when it fires. | ||
603 | * In the case of userspace breakpoints on a core with V7 debug, | ||
604 | * we can use the mismatch feature as a poor-man's hardware single-step. | ||
605 | */ | ||
606 | if (WARN_ONCE(!bp->overflow_handler && | ||
607 | (arch_check_bp_in_kernelspace(bp) || !core_has_mismatch_bps()), | ||
608 | "overflow handler required but none found")) { | ||
609 | ret = -EINVAL; | ||
610 | goto out; | ||
611 | } | ||
612 | out: | ||
613 | return ret; | ||
614 | } | ||
615 | |||
616 | static void update_mismatch_flag(int idx, int flag) | ||
617 | { | ||
618 | struct perf_event *bp = __get_cpu_var(bp_on_reg[idx]); | ||
619 | struct arch_hw_breakpoint *info; | ||
620 | |||
621 | if (bp == NULL) | ||
622 | return; | ||
623 | |||
624 | info = counter_arch_bp(bp); | ||
625 | |||
626 | /* Update the mismatch field to enter/exit `single-step' mode */ | ||
627 | if (!bp->overflow_handler && info->ctrl.mismatch != flag) { | ||
628 | info->ctrl.mismatch = flag; | ||
629 | write_wb_reg(ARM_BASE_BCR + idx, encode_ctrl_reg(info->ctrl) | 0x1); | ||
630 | } | ||
631 | } | ||
632 | |||
633 | static void watchpoint_handler(unsigned long unknown, struct pt_regs *regs) | ||
634 | { | ||
635 | int i; | ||
636 | struct perf_event *bp, **slots = __get_cpu_var(wp_on_reg); | ||
637 | struct arch_hw_breakpoint *info; | ||
638 | struct perf_event_attr attr; | ||
639 | |||
640 | /* Without a disassembler, we can only handle 1 watchpoint. */ | ||
641 | BUG_ON(core_num_wrps > 1); | ||
642 | |||
643 | hw_breakpoint_init(&attr); | ||
644 | attr.bp_addr = regs->ARM_pc & ~0x3; | ||
645 | attr.bp_len = HW_BREAKPOINT_LEN_4; | ||
646 | attr.bp_type = HW_BREAKPOINT_X; | ||
647 | |||
648 | for (i = 0; i < core_num_wrps; ++i) { | ||
649 | rcu_read_lock(); | ||
650 | |||
651 | if (slots[i] == NULL) { | ||
652 | rcu_read_unlock(); | ||
653 | continue; | ||
654 | } | ||
655 | |||
656 | /* | ||
657 | * The DFAR is an unknown value. Since we only allow a | ||
658 | * single watchpoint, we can set the trigger to the lowest | ||
659 | * possible faulting address. | ||
660 | */ | ||
661 | info = counter_arch_bp(slots[i]); | ||
662 | info->trigger = slots[i]->attr.bp_addr; | ||
663 | pr_debug("watchpoint fired: address = 0x%x\n", info->trigger); | ||
664 | perf_bp_event(slots[i], regs); | ||
665 | |||
666 | /* | ||
667 | * If no overflow handler is present, insert a temporary | ||
668 | * mismatch breakpoint so we can single-step over the | ||
669 | * watchpoint trigger. | ||
670 | */ | ||
671 | if (!slots[i]->overflow_handler) { | ||
672 | bp = register_user_hw_breakpoint(&attr, | ||
673 | wp_single_step_handler, | ||
674 | current); | ||
675 | counter_arch_bp(bp)->suspended_wp = slots[i]; | ||
676 | perf_event_disable(slots[i]); | ||
677 | } | ||
678 | |||
679 | rcu_read_unlock(); | ||
680 | } | ||
681 | } | ||
682 | |||
683 | static void breakpoint_handler(unsigned long unknown, struct pt_regs *regs) | ||
684 | { | ||
685 | int i; | ||
686 | int mismatch; | ||
687 | u32 ctrl_reg, val, addr; | ||
688 | struct perf_event *bp, **slots = __get_cpu_var(bp_on_reg); | ||
689 | struct arch_hw_breakpoint *info; | ||
690 | struct arch_hw_breakpoint_ctrl ctrl; | ||
691 | |||
692 | /* The exception entry code places the amended lr in the PC. */ | ||
693 | addr = regs->ARM_pc; | ||
694 | |||
695 | for (i = 0; i < core_num_brps; ++i) { | ||
696 | rcu_read_lock(); | ||
697 | |||
698 | bp = slots[i]; | ||
699 | |||
700 | if (bp == NULL) { | ||
701 | rcu_read_unlock(); | ||
702 | continue; | ||
703 | } | ||
704 | |||
705 | mismatch = 0; | ||
706 | |||
707 | /* Check if the breakpoint value matches. */ | ||
708 | val = read_wb_reg(ARM_BASE_BVR + i); | ||
709 | if (val != (addr & ~0x3)) | ||
710 | goto unlock; | ||
711 | |||
712 | /* Possible match, check the byte address select to confirm. */ | ||
713 | ctrl_reg = read_wb_reg(ARM_BASE_BCR + i); | ||
714 | decode_ctrl_reg(ctrl_reg, &ctrl); | ||
715 | if ((1 << (addr & 0x3)) & ctrl.len) { | ||
716 | mismatch = 1; | ||
717 | info = counter_arch_bp(bp); | ||
718 | info->trigger = addr; | ||
719 | } | ||
720 | |||
721 | unlock: | ||
722 | if ((mismatch && !info->ctrl.mismatch) || bp_is_single_step(bp)) { | ||
723 | pr_debug("breakpoint fired: address = 0x%x\n", addr); | ||
724 | perf_bp_event(bp, regs); | ||
725 | } | ||
726 | |||
727 | update_mismatch_flag(i, mismatch); | ||
728 | rcu_read_unlock(); | ||
729 | } | ||
730 | } | ||
731 | |||
732 | /* | ||
733 | * Called from either the Data Abort Handler [watchpoint] or the | ||
734 | * Prefetch Abort Handler [breakpoint]. | ||
735 | */ | ||
736 | static int hw_breakpoint_pending(unsigned long addr, unsigned int fsr, | ||
737 | struct pt_regs *regs) | ||
738 | { | ||
739 | int ret = 1; /* Unhandled fault. */ | ||
740 | u32 dscr; | ||
741 | |||
742 | /* We only handle watchpoints and hardware breakpoints. */ | ||
743 | ARM_DBG_READ(c1, 0, dscr); | ||
744 | |||
745 | /* Perform perf callbacks. */ | ||
746 | switch (ARM_DSCR_MOE(dscr)) { | ||
747 | case ARM_ENTRY_BREAKPOINT: | ||
748 | breakpoint_handler(addr, regs); | ||
749 | break; | ||
750 | case ARM_ENTRY_ASYNC_WATCHPOINT: | ||
751 | WARN_ON("Asynchronous watchpoint exception taken. " | ||
752 | "Debugging results may be unreliable"); | ||
753 | case ARM_ENTRY_SYNC_WATCHPOINT: | ||
754 | watchpoint_handler(addr, regs); | ||
755 | break; | ||
756 | default: | ||
757 | goto out; | ||
758 | } | ||
759 | |||
760 | ret = 0; | ||
761 | out: | ||
762 | return ret; | ||
763 | } | ||
764 | |||
765 | /* | ||
766 | * One-time initialisation. | ||
767 | */ | ||
768 | static void __init reset_ctrl_regs(void *unused) | ||
769 | { | ||
770 | int i; | ||
771 | |||
772 | if (enable_monitor_mode()) | ||
773 | return; | ||
774 | |||
775 | for (i = 0; i < core_num_brps; ++i) { | ||
776 | write_wb_reg(ARM_BASE_BCR + i, 0UL); | ||
777 | write_wb_reg(ARM_BASE_BVR + i, 0UL); | ||
778 | } | ||
779 | |||
780 | for (i = 0; i < core_num_wrps; ++i) { | ||
781 | write_wb_reg(ARM_BASE_WCR + i, 0UL); | ||
782 | write_wb_reg(ARM_BASE_WVR + i, 0UL); | ||
783 | } | ||
784 | } | ||
785 | |||
786 | static int __init arch_hw_breakpoint_init(void) | ||
787 | { | ||
788 | int ret = 0; | ||
789 | u32 dscr; | ||
790 | |||
791 | debug_arch = get_debug_arch(); | ||
792 | |||
793 | if (debug_arch > ARM_DEBUG_ARCH_V7_ECP14) { | ||
794 | pr_info("debug architecture 0x%x unsupported.\n", debug_arch); | ||
795 | ret = -ENODEV; | ||
796 | goto out; | ||
797 | } | ||
798 | |||
799 | /* Determine how many BRPs/WRPs are available. */ | ||
800 | core_num_brps = get_num_brps(); | ||
801 | core_num_wrps = get_num_wrps(); | ||
802 | |||
803 | pr_info("found %d breakpoint and %d watchpoint registers.\n", | ||
804 | core_num_brps, core_num_wrps); | ||
805 | |||
806 | if (core_has_mismatch_bps()) | ||
807 | pr_info("1 breakpoint reserved for watchpoint single-step.\n"); | ||
808 | |||
809 | ARM_DBG_READ(c1, 0, dscr); | ||
810 | if (dscr & ARM_DSCR_HDBGEN) { | ||
811 | pr_warning("halting debug mode enabled. Assuming maximum " | ||
812 | "watchpoint size of 4 bytes."); | ||
813 | } else { | ||
814 | /* Work out the maximum supported watchpoint length. */ | ||
815 | max_watchpoint_len = get_max_wp_len(); | ||
816 | pr_info("maximum watchpoint size is %u bytes.\n", | ||
817 | max_watchpoint_len); | ||
818 | |||
819 | /* | ||
820 | * Reset the breakpoint resources. We assume that a halting | ||
821 | * debugger will leave the world in a nice state for us. | ||
822 | */ | ||
823 | smp_call_function(reset_ctrl_regs, NULL, 1); | ||
824 | reset_ctrl_regs(NULL); | ||
825 | } | ||
826 | |||
827 | /* Register debug fault handler. */ | ||
828 | hook_fault_code(2, hw_breakpoint_pending, SIGTRAP, TRAP_HWBKPT, | ||
829 | "watchpoint debug exception"); | ||
830 | hook_ifault_code(2, hw_breakpoint_pending, SIGTRAP, TRAP_HWBKPT, | ||
831 | "breakpoint debug exception"); | ||
832 | |||
833 | out: | ||
834 | return ret; | ||
835 | } | ||
836 | arch_initcall(arch_hw_breakpoint_init); | ||
837 | |||
838 | void hw_breakpoint_pmu_read(struct perf_event *bp) | ||
839 | { | ||
840 | } | ||
841 | |||
842 | /* | ||
843 | * Dummy function to register with die_notifier. | ||
844 | */ | ||
845 | int hw_breakpoint_exceptions_notify(struct notifier_block *unused, | ||
846 | unsigned long val, void *data) | ||
847 | { | ||
848 | return NOTIFY_DONE; | ||
849 | } | ||
diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c index 6b4605893f1e..d9bd786ce23d 100644 --- a/arch/arm/kernel/module.c +++ b/arch/arm/kernel/module.c | |||
@@ -69,20 +69,31 @@ int module_frob_arch_sections(Elf_Ehdr *hdr, | |||
69 | { | 69 | { |
70 | #ifdef CONFIG_ARM_UNWIND | 70 | #ifdef CONFIG_ARM_UNWIND |
71 | Elf_Shdr *s, *sechdrs_end = sechdrs + hdr->e_shnum; | 71 | Elf_Shdr *s, *sechdrs_end = sechdrs + hdr->e_shnum; |
72 | struct arm_unwind_mapping *maps = mod->arch.map; | ||
72 | 73 | ||
73 | for (s = sechdrs; s < sechdrs_end; s++) { | 74 | for (s = sechdrs; s < sechdrs_end; s++) { |
74 | if (strcmp(".ARM.exidx.init.text", secstrings + s->sh_name) == 0) | 75 | char const *secname = secstrings + s->sh_name; |
75 | mod->arch.unw_sec_init = s; | 76 | |
76 | else if (strcmp(".ARM.exidx.devinit.text", secstrings + s->sh_name) == 0) | 77 | if (strcmp(".ARM.exidx.init.text", secname) == 0) |
77 | mod->arch.unw_sec_devinit = s; | 78 | maps[ARM_SEC_INIT].unw_sec = s; |
78 | else if (strcmp(".ARM.exidx", secstrings + s->sh_name) == 0) | 79 | else if (strcmp(".ARM.exidx.devinit.text", secname) == 0) |
79 | mod->arch.unw_sec_core = s; | 80 | maps[ARM_SEC_DEVINIT].unw_sec = s; |
80 | else if (strcmp(".init.text", secstrings + s->sh_name) == 0) | 81 | else if (strcmp(".ARM.exidx", secname) == 0) |
81 | mod->arch.sec_init_text = s; | 82 | maps[ARM_SEC_CORE].unw_sec = s; |
82 | else if (strcmp(".devinit.text", secstrings + s->sh_name) == 0) | 83 | else if (strcmp(".ARM.exidx.exit.text", secname) == 0) |
83 | mod->arch.sec_devinit_text = s; | 84 | maps[ARM_SEC_EXIT].unw_sec = s; |
84 | else if (strcmp(".text", secstrings + s->sh_name) == 0) | 85 | else if (strcmp(".ARM.exidx.devexit.text", secname) == 0) |
85 | mod->arch.sec_core_text = s; | 86 | maps[ARM_SEC_DEVEXIT].unw_sec = s; |
87 | else if (strcmp(".init.text", secname) == 0) | ||
88 | maps[ARM_SEC_INIT].sec_text = s; | ||
89 | else if (strcmp(".devinit.text", secname) == 0) | ||
90 | maps[ARM_SEC_DEVINIT].sec_text = s; | ||
91 | else if (strcmp(".text", secname) == 0) | ||
92 | maps[ARM_SEC_CORE].sec_text = s; | ||
93 | else if (strcmp(".exit.text", secname) == 0) | ||
94 | maps[ARM_SEC_EXIT].sec_text = s; | ||
95 | else if (strcmp(".devexit.text", secname) == 0) | ||
96 | maps[ARM_SEC_DEVEXIT].sec_text = s; | ||
86 | } | 97 | } |
87 | #endif | 98 | #endif |
88 | return 0; | 99 | return 0; |
@@ -292,31 +303,22 @@ apply_relocate_add(Elf32_Shdr *sechdrs, const char *strtab, | |||
292 | #ifdef CONFIG_ARM_UNWIND | 303 | #ifdef CONFIG_ARM_UNWIND |
293 | static void register_unwind_tables(struct module *mod) | 304 | static void register_unwind_tables(struct module *mod) |
294 | { | 305 | { |
295 | if (mod->arch.unw_sec_init && mod->arch.sec_init_text) | 306 | int i; |
296 | mod->arch.unwind_init = | 307 | for (i = 0; i < ARM_SEC_MAX; ++i) { |
297 | unwind_table_add(mod->arch.unw_sec_init->sh_addr, | 308 | struct arm_unwind_mapping *map = &mod->arch.map[i]; |
298 | mod->arch.unw_sec_init->sh_size, | 309 | if (map->unw_sec && map->sec_text) |
299 | mod->arch.sec_init_text->sh_addr, | 310 | map->unwind = unwind_table_add(map->unw_sec->sh_addr, |
300 | mod->arch.sec_init_text->sh_size); | 311 | map->unw_sec->sh_size, |
301 | if (mod->arch.unw_sec_devinit && mod->arch.sec_devinit_text) | 312 | map->sec_text->sh_addr, |
302 | mod->arch.unwind_devinit = | 313 | map->sec_text->sh_size); |
303 | unwind_table_add(mod->arch.unw_sec_devinit->sh_addr, | 314 | } |
304 | mod->arch.unw_sec_devinit->sh_size, | ||
305 | mod->arch.sec_devinit_text->sh_addr, | ||
306 | mod->arch.sec_devinit_text->sh_size); | ||
307 | if (mod->arch.unw_sec_core && mod->arch.sec_core_text) | ||
308 | mod->arch.unwind_core = | ||
309 | unwind_table_add(mod->arch.unw_sec_core->sh_addr, | ||
310 | mod->arch.unw_sec_core->sh_size, | ||
311 | mod->arch.sec_core_text->sh_addr, | ||
312 | mod->arch.sec_core_text->sh_size); | ||
313 | } | 315 | } |
314 | 316 | ||
315 | static void unregister_unwind_tables(struct module *mod) | 317 | static void unregister_unwind_tables(struct module *mod) |
316 | { | 318 | { |
317 | unwind_table_del(mod->arch.unwind_init); | 319 | int i = ARM_SEC_MAX; |
318 | unwind_table_del(mod->arch.unwind_devinit); | 320 | while (--i >= 0) |
319 | unwind_table_del(mod->arch.unwind_core); | 321 | unwind_table_del(mod->arch.map[i].unwind); |
320 | } | 322 | } |
321 | #else | 323 | #else |
322 | static inline void register_unwind_tables(struct module *mod) { } | 324 | static inline void register_unwind_tables(struct module *mod) { } |
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index 401e38be1f78..3af34bf4f4df 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <linux/utsname.h> | 29 | #include <linux/utsname.h> |
30 | #include <linux/uaccess.h> | 30 | #include <linux/uaccess.h> |
31 | #include <linux/random.h> | 31 | #include <linux/random.h> |
32 | #include <linux/hw_breakpoint.h> | ||
32 | 33 | ||
33 | #include <asm/cacheflush.h> | 34 | #include <asm/cacheflush.h> |
34 | #include <asm/leds.h> | 35 | #include <asm/leds.h> |
@@ -135,6 +136,25 @@ EXPORT_SYMBOL(pm_power_off); | |||
135 | void (*arm_pm_restart)(char str, const char *cmd) = arm_machine_restart; | 136 | void (*arm_pm_restart)(char str, const char *cmd) = arm_machine_restart; |
136 | EXPORT_SYMBOL_GPL(arm_pm_restart); | 137 | EXPORT_SYMBOL_GPL(arm_pm_restart); |
137 | 138 | ||
139 | static void do_nothing(void *unused) | ||
140 | { | ||
141 | } | ||
142 | |||
143 | /* | ||
144 | * cpu_idle_wait - Used to ensure that all the CPUs discard old value of | ||
145 | * pm_idle and update to new pm_idle value. Required while changing pm_idle | ||
146 | * handler on SMP systems. | ||
147 | * | ||
148 | * Caller must have changed pm_idle to the new value before the call. Old | ||
149 | * pm_idle value will not be used by any CPU after the return of this function. | ||
150 | */ | ||
151 | void cpu_idle_wait(void) | ||
152 | { | ||
153 | smp_mb(); | ||
154 | /* kick all the CPUs so that they exit out of pm_idle */ | ||
155 | smp_call_function(do_nothing, NULL, 1); | ||
156 | } | ||
157 | EXPORT_SYMBOL_GPL(cpu_idle_wait); | ||
138 | 158 | ||
139 | /* | 159 | /* |
140 | * This is our default idle handler. We need to disable | 160 | * This is our default idle handler. We need to disable |
@@ -317,6 +337,8 @@ void flush_thread(void) | |||
317 | struct thread_info *thread = current_thread_info(); | 337 | struct thread_info *thread = current_thread_info(); |
318 | struct task_struct *tsk = current; | 338 | struct task_struct *tsk = current; |
319 | 339 | ||
340 | flush_ptrace_hw_breakpoint(tsk); | ||
341 | |||
320 | memset(thread->used_cp, 0, sizeof(thread->used_cp)); | 342 | memset(thread->used_cp, 0, sizeof(thread->used_cp)); |
321 | memset(&tsk->thread.debug, 0, sizeof(struct debug_info)); | 343 | memset(&tsk->thread.debug, 0, sizeof(struct debug_info)); |
322 | memset(&thread->fpstate, 0, sizeof(union fp_state)); | 344 | memset(&thread->fpstate, 0, sizeof(union fp_state)); |
@@ -345,6 +367,8 @@ copy_thread(unsigned long clone_flags, unsigned long stack_start, | |||
345 | thread->cpu_context.sp = (unsigned long)childregs; | 367 | thread->cpu_context.sp = (unsigned long)childregs; |
346 | thread->cpu_context.pc = (unsigned long)ret_from_fork; | 368 | thread->cpu_context.pc = (unsigned long)ret_from_fork; |
347 | 369 | ||
370 | clear_ptrace_hw_breakpoint(p); | ||
371 | |||
348 | if (clone_flags & CLONE_SETTLS) | 372 | if (clone_flags & CLONE_SETTLS) |
349 | thread->tp_value = regs->ARM_r3; | 373 | thread->tp_value = regs->ARM_r3; |
350 | 374 | ||
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c index f99d489822d5..e0cb6370ed14 100644 --- a/arch/arm/kernel/ptrace.c +++ b/arch/arm/kernel/ptrace.c | |||
@@ -19,6 +19,8 @@ | |||
19 | #include <linux/init.h> | 19 | #include <linux/init.h> |
20 | #include <linux/signal.h> | 20 | #include <linux/signal.h> |
21 | #include <linux/uaccess.h> | 21 | #include <linux/uaccess.h> |
22 | #include <linux/perf_event.h> | ||
23 | #include <linux/hw_breakpoint.h> | ||
22 | 24 | ||
23 | #include <asm/pgtable.h> | 25 | #include <asm/pgtable.h> |
24 | #include <asm/system.h> | 26 | #include <asm/system.h> |
@@ -847,6 +849,232 @@ static int ptrace_setvfpregs(struct task_struct *tsk, void __user *data) | |||
847 | } | 849 | } |
848 | #endif | 850 | #endif |
849 | 851 | ||
852 | #ifdef CONFIG_HAVE_HW_BREAKPOINT | ||
853 | /* | ||
854 | * Convert a virtual register number into an index for a thread_info | ||
855 | * breakpoint array. Breakpoints are identified using positive numbers | ||
856 | * whilst watchpoints are negative. The registers are laid out as pairs | ||
857 | * of (address, control), each pair mapping to a unique hw_breakpoint struct. | ||
858 | * Register 0 is reserved for describing resource information. | ||
859 | */ | ||
860 | static int ptrace_hbp_num_to_idx(long num) | ||
861 | { | ||
862 | if (num < 0) | ||
863 | num = (ARM_MAX_BRP << 1) - num; | ||
864 | return (num - 1) >> 1; | ||
865 | } | ||
866 | |||
867 | /* | ||
868 | * Returns the virtual register number for the address of the | ||
869 | * breakpoint at index idx. | ||
870 | */ | ||
871 | static long ptrace_hbp_idx_to_num(int idx) | ||
872 | { | ||
873 | long mid = ARM_MAX_BRP << 1; | ||
874 | long num = (idx << 1) + 1; | ||
875 | return num > mid ? mid - num : num; | ||
876 | } | ||
877 | |||
878 | /* | ||
879 | * Handle hitting a HW-breakpoint. | ||
880 | */ | ||
881 | static void ptrace_hbptriggered(struct perf_event *bp, int unused, | ||
882 | struct perf_sample_data *data, | ||
883 | struct pt_regs *regs) | ||
884 | { | ||
885 | struct arch_hw_breakpoint *bkpt = counter_arch_bp(bp); | ||
886 | long num; | ||
887 | int i; | ||
888 | siginfo_t info; | ||
889 | |||
890 | for (i = 0; i < ARM_MAX_HBP_SLOTS; ++i) | ||
891 | if (current->thread.debug.hbp[i] == bp) | ||
892 | break; | ||
893 | |||
894 | num = (i == ARM_MAX_HBP_SLOTS) ? 0 : ptrace_hbp_idx_to_num(i); | ||
895 | |||
896 | info.si_signo = SIGTRAP; | ||
897 | info.si_errno = (int)num; | ||
898 | info.si_code = TRAP_HWBKPT; | ||
899 | info.si_addr = (void __user *)(bkpt->trigger); | ||
900 | |||
901 | force_sig_info(SIGTRAP, &info, current); | ||
902 | } | ||
903 | |||
904 | /* | ||
905 | * Set ptrace breakpoint pointers to zero for this task. | ||
906 | * This is required in order to prevent child processes from unregistering | ||
907 | * breakpoints held by their parent. | ||
908 | */ | ||
909 | void clear_ptrace_hw_breakpoint(struct task_struct *tsk) | ||
910 | { | ||
911 | memset(tsk->thread.debug.hbp, 0, sizeof(tsk->thread.debug.hbp)); | ||
912 | } | ||
913 | |||
914 | /* | ||
915 | * Unregister breakpoints from this task and reset the pointers in | ||
916 | * the thread_struct. | ||
917 | */ | ||
918 | void flush_ptrace_hw_breakpoint(struct task_struct *tsk) | ||
919 | { | ||
920 | int i; | ||
921 | struct thread_struct *t = &tsk->thread; | ||
922 | |||
923 | for (i = 0; i < ARM_MAX_HBP_SLOTS; i++) { | ||
924 | if (t->debug.hbp[i]) { | ||
925 | unregister_hw_breakpoint(t->debug.hbp[i]); | ||
926 | t->debug.hbp[i] = NULL; | ||
927 | } | ||
928 | } | ||
929 | } | ||
930 | |||
931 | static u32 ptrace_get_hbp_resource_info(void) | ||
932 | { | ||
933 | u8 num_brps, num_wrps, debug_arch, wp_len; | ||
934 | u32 reg = 0; | ||
935 | |||
936 | num_brps = hw_breakpoint_slots(TYPE_INST); | ||
937 | num_wrps = hw_breakpoint_slots(TYPE_DATA); | ||
938 | debug_arch = arch_get_debug_arch(); | ||
939 | wp_len = arch_get_max_wp_len(); | ||
940 | |||
941 | reg |= debug_arch; | ||
942 | reg <<= 8; | ||
943 | reg |= wp_len; | ||
944 | reg <<= 8; | ||
945 | reg |= num_wrps; | ||
946 | reg <<= 8; | ||
947 | reg |= num_brps; | ||
948 | |||
949 | return reg; | ||
950 | } | ||
951 | |||
952 | static struct perf_event *ptrace_hbp_create(struct task_struct *tsk, int type) | ||
953 | { | ||
954 | struct perf_event_attr attr; | ||
955 | |||
956 | ptrace_breakpoint_init(&attr); | ||
957 | |||
958 | /* Initialise fields to sane defaults. */ | ||
959 | attr.bp_addr = 0; | ||
960 | attr.bp_len = HW_BREAKPOINT_LEN_4; | ||
961 | attr.bp_type = type; | ||
962 | attr.disabled = 1; | ||
963 | |||
964 | return register_user_hw_breakpoint(&attr, ptrace_hbptriggered, tsk); | ||
965 | } | ||
966 | |||
967 | static int ptrace_gethbpregs(struct task_struct *tsk, long num, | ||
968 | unsigned long __user *data) | ||
969 | { | ||
970 | u32 reg; | ||
971 | int idx, ret = 0; | ||
972 | struct perf_event *bp; | ||
973 | struct arch_hw_breakpoint_ctrl arch_ctrl; | ||
974 | |||
975 | if (num == 0) { | ||
976 | reg = ptrace_get_hbp_resource_info(); | ||
977 | } else { | ||
978 | idx = ptrace_hbp_num_to_idx(num); | ||
979 | if (idx < 0 || idx >= ARM_MAX_HBP_SLOTS) { | ||
980 | ret = -EINVAL; | ||
981 | goto out; | ||
982 | } | ||
983 | |||
984 | bp = tsk->thread.debug.hbp[idx]; | ||
985 | if (!bp) { | ||
986 | reg = 0; | ||
987 | goto put; | ||
988 | } | ||
989 | |||
990 | arch_ctrl = counter_arch_bp(bp)->ctrl; | ||
991 | |||
992 | /* | ||
993 | * Fix up the len because we may have adjusted it | ||
994 | * to compensate for an unaligned address. | ||
995 | */ | ||
996 | while (!(arch_ctrl.len & 0x1)) | ||
997 | arch_ctrl.len >>= 1; | ||
998 | |||
999 | if (idx & 0x1) | ||
1000 | reg = encode_ctrl_reg(arch_ctrl); | ||
1001 | else | ||
1002 | reg = bp->attr.bp_addr; | ||
1003 | } | ||
1004 | |||
1005 | put: | ||
1006 | if (put_user(reg, data)) | ||
1007 | ret = -EFAULT; | ||
1008 | |||
1009 | out: | ||
1010 | return ret; | ||
1011 | } | ||
1012 | |||
1013 | static int ptrace_sethbpregs(struct task_struct *tsk, long num, | ||
1014 | unsigned long __user *data) | ||
1015 | { | ||
1016 | int idx, gen_len, gen_type, implied_type, ret = 0; | ||
1017 | u32 user_val; | ||
1018 | struct perf_event *bp; | ||
1019 | struct arch_hw_breakpoint_ctrl ctrl; | ||
1020 | struct perf_event_attr attr; | ||
1021 | |||
1022 | if (num == 0) | ||
1023 | goto out; | ||
1024 | else if (num < 0) | ||
1025 | implied_type = HW_BREAKPOINT_RW; | ||
1026 | else | ||
1027 | implied_type = HW_BREAKPOINT_X; | ||
1028 | |||
1029 | idx = ptrace_hbp_num_to_idx(num); | ||
1030 | if (idx < 0 || idx >= ARM_MAX_HBP_SLOTS) { | ||
1031 | ret = -EINVAL; | ||
1032 | goto out; | ||
1033 | } | ||
1034 | |||
1035 | if (get_user(user_val, data)) { | ||
1036 | ret = -EFAULT; | ||
1037 | goto out; | ||
1038 | } | ||
1039 | |||
1040 | bp = tsk->thread.debug.hbp[idx]; | ||
1041 | if (!bp) { | ||
1042 | bp = ptrace_hbp_create(tsk, implied_type); | ||
1043 | if (IS_ERR(bp)) { | ||
1044 | ret = PTR_ERR(bp); | ||
1045 | goto out; | ||
1046 | } | ||
1047 | tsk->thread.debug.hbp[idx] = bp; | ||
1048 | } | ||
1049 | |||
1050 | attr = bp->attr; | ||
1051 | |||
1052 | if (num & 0x1) { | ||
1053 | /* Address */ | ||
1054 | attr.bp_addr = user_val; | ||
1055 | } else { | ||
1056 | /* Control */ | ||
1057 | decode_ctrl_reg(user_val, &ctrl); | ||
1058 | ret = arch_bp_generic_fields(ctrl, &gen_len, &gen_type); | ||
1059 | if (ret) | ||
1060 | goto out; | ||
1061 | |||
1062 | if ((gen_type & implied_type) != gen_type) { | ||
1063 | ret = -EINVAL; | ||
1064 | goto out; | ||
1065 | } | ||
1066 | |||
1067 | attr.bp_len = gen_len; | ||
1068 | attr.bp_type = gen_type; | ||
1069 | attr.disabled = !ctrl.enabled; | ||
1070 | } | ||
1071 | |||
1072 | ret = modify_user_hw_breakpoint(bp, &attr); | ||
1073 | out: | ||
1074 | return ret; | ||
1075 | } | ||
1076 | #endif | ||
1077 | |||
850 | long arch_ptrace(struct task_struct *child, long request, long addr, long data) | 1078 | long arch_ptrace(struct task_struct *child, long request, long addr, long data) |
851 | { | 1079 | { |
852 | int ret; | 1080 | int ret; |
@@ -916,6 +1144,17 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
916 | break; | 1144 | break; |
917 | #endif | 1145 | #endif |
918 | 1146 | ||
1147 | #ifdef CONFIG_HAVE_HW_BREAKPOINT | ||
1148 | case PTRACE_GETHBPREGS: | ||
1149 | ret = ptrace_gethbpregs(child, addr, | ||
1150 | (unsigned long __user *)data); | ||
1151 | break; | ||
1152 | case PTRACE_SETHBPREGS: | ||
1153 | ret = ptrace_sethbpregs(child, addr, | ||
1154 | (unsigned long __user *)data); | ||
1155 | break; | ||
1156 | #endif | ||
1157 | |||
919 | default: | 1158 | default: |
920 | ret = ptrace_request(child, request, addr, data); | 1159 | ret = ptrace_request(child, request, addr, data); |
921 | break; | 1160 | break; |
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index e0430d036cea..336f14e0e5c2 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <asm/procinfo.h> | 36 | #include <asm/procinfo.h> |
37 | #include <asm/sections.h> | 37 | #include <asm/sections.h> |
38 | #include <asm/setup.h> | 38 | #include <asm/setup.h> |
39 | #include <asm/smp_plat.h> | ||
39 | #include <asm/mach-types.h> | 40 | #include <asm/mach-types.h> |
40 | #include <asm/cacheflush.h> | 41 | #include <asm/cacheflush.h> |
41 | #include <asm/cachetype.h> | 42 | #include <asm/cachetype.h> |
@@ -524,7 +525,7 @@ request_standard_resources(struct meminfo *mi, struct machine_desc *mdesc) | |||
524 | 525 | ||
525 | kernel_code.start = virt_to_phys(_text); | 526 | kernel_code.start = virt_to_phys(_text); |
526 | kernel_code.end = virt_to_phys(_etext - 1); | 527 | kernel_code.end = virt_to_phys(_etext - 1); |
527 | kernel_data.start = virt_to_phys(_data); | 528 | kernel_data.start = virt_to_phys(_sdata); |
528 | kernel_data.end = virt_to_phys(_end - 1); | 529 | kernel_data.end = virt_to_phys(_end - 1); |
529 | 530 | ||
530 | for (i = 0; i < mi->nr_banks; i++) { | 531 | for (i = 0; i < mi->nr_banks; i++) { |
@@ -859,7 +860,8 @@ void __init setup_arch(char **cmdline_p) | |||
859 | request_standard_resources(&meminfo, mdesc); | 860 | request_standard_resources(&meminfo, mdesc); |
860 | 861 | ||
861 | #ifdef CONFIG_SMP | 862 | #ifdef CONFIG_SMP |
862 | smp_init_cpus(); | 863 | if (is_smp()) |
864 | smp_init_cpus(); | ||
863 | #endif | 865 | #endif |
864 | reserve_crashkernel(); | 866 | reserve_crashkernel(); |
865 | 867 | ||
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index 40dc74f2b27f..32e16da5cbce 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c | |||
@@ -567,7 +567,8 @@ void smp_send_stop(void) | |||
567 | { | 567 | { |
568 | cpumask_t mask = cpu_online_map; | 568 | cpumask_t mask = cpu_online_map; |
569 | cpu_clear(smp_processor_id(), mask); | 569 | cpu_clear(smp_processor_id(), mask); |
570 | send_ipi_message(&mask, IPI_CPU_STOP); | 570 | if (!cpus_empty(mask)) |
571 | send_ipi_message(&mask, IPI_CPU_STOP); | ||
571 | } | 572 | } |
572 | 573 | ||
573 | /* | 574 | /* |
diff --git a/arch/arm/kernel/unwind.c b/arch/arm/kernel/unwind.c index dd81a918c106..2a161765f6d5 100644 --- a/arch/arm/kernel/unwind.c +++ b/arch/arm/kernel/unwind.c | |||
@@ -146,6 +146,8 @@ static struct unwind_idx *unwind_find_idx(unsigned long addr) | |||
146 | addr < table->end_addr) { | 146 | addr < table->end_addr) { |
147 | idx = search_index(addr, table->start, | 147 | idx = search_index(addr, table->start, |
148 | table->stop - 1); | 148 | table->stop - 1); |
149 | /* Move-to-front to exploit common traces */ | ||
150 | list_move(&table->list, &unwind_tables); | ||
149 | break; | 151 | break; |
150 | } | 152 | } |
151 | } | 153 | } |
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S index b16c07914b55..065d35de0e01 100644 --- a/arch/arm/kernel/vmlinux.lds.S +++ b/arch/arm/kernel/vmlinux.lds.S | |||
@@ -40,6 +40,11 @@ SECTIONS | |||
40 | __tagtable_begin = .; | 40 | __tagtable_begin = .; |
41 | *(.taglist.init) | 41 | *(.taglist.init) |
42 | __tagtable_end = .; | 42 | __tagtable_end = .; |
43 | #ifdef CONFIG_SMP_ON_UP | ||
44 | __smpalt_begin = .; | ||
45 | *(.alt.smp.init) | ||
46 | __smpalt_end = .; | ||
47 | #endif | ||
43 | 48 | ||
44 | INIT_SETUP(16) | 49 | INIT_SETUP(16) |
45 | 50 | ||
@@ -104,8 +109,6 @@ SECTIONS | |||
104 | 109 | ||
105 | RO_DATA(PAGE_SIZE) | 110 | RO_DATA(PAGE_SIZE) |
106 | 111 | ||
107 | _etext = .; /* End of text and rodata section */ | ||
108 | |||
109 | #ifdef CONFIG_ARM_UNWIND | 112 | #ifdef CONFIG_ARM_UNWIND |
110 | /* | 113 | /* |
111 | * Stack unwinding tables | 114 | * Stack unwinding tables |
@@ -123,6 +126,8 @@ SECTIONS | |||
123 | } | 126 | } |
124 | #endif | 127 | #endif |
125 | 128 | ||
129 | _etext = .; /* End of text and rodata section */ | ||
130 | |||
126 | #ifdef CONFIG_XIP_KERNEL | 131 | #ifdef CONFIG_XIP_KERNEL |
127 | __data_loc = ALIGN(4); /* location in binary */ | 132 | __data_loc = ALIGN(4); /* location in binary */ |
128 | . = PAGE_OFFSET + TEXT_OFFSET; | 133 | . = PAGE_OFFSET + TEXT_OFFSET; |
@@ -237,6 +242,12 @@ SECTIONS | |||
237 | 242 | ||
238 | /* Default discards */ | 243 | /* Default discards */ |
239 | DISCARDS | 244 | DISCARDS |
245 | |||
246 | #ifndef CONFIG_SMP_ON_UP | ||
247 | /DISCARD/ : { | ||
248 | *(.alt.smp.init) | ||
249 | } | ||
250 | #endif | ||
240 | } | 251 | } |
241 | 252 | ||
242 | /* | 253 | /* |
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig index 939bccd70569..ca33862b4bf4 100644 --- a/arch/arm/mach-at91/Kconfig +++ b/arch/arm/mach-at91/Kconfig | |||
@@ -248,6 +248,12 @@ config MACH_CPU9260 | |||
248 | Select this if you are using a Eukrea Electromatique's | 248 | Select this if you are using a Eukrea Electromatique's |
249 | CPU9260 Board <http://www.eukrea.com/> | 249 | CPU9260 Board <http://www.eukrea.com/> |
250 | 250 | ||
251 | config MACH_FLEXIBITY | ||
252 | bool "Flexibity Connect board" | ||
253 | help | ||
254 | Select this if you are using Flexibity Connect board | ||
255 | <http://www.flexibity.com> | ||
256 | |||
251 | endif | 257 | endif |
252 | 258 | ||
253 | # ---------------------------------------------------------- | 259 | # ---------------------------------------------------------- |
diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile index ca2ac003f41f..7cbe06d7cee9 100644 --- a/arch/arm/mach-at91/Makefile +++ b/arch/arm/mach-at91/Makefile | |||
@@ -46,6 +46,7 @@ obj-$(CONFIG_MACH_USB_A9260) += board-usb-a9260.o | |||
46 | obj-$(CONFIG_MACH_QIL_A9260) += board-qil-a9260.o | 46 | obj-$(CONFIG_MACH_QIL_A9260) += board-qil-a9260.o |
47 | obj-$(CONFIG_MACH_AFEB9260) += board-afeb-9260v1.o | 47 | obj-$(CONFIG_MACH_AFEB9260) += board-afeb-9260v1.o |
48 | obj-$(CONFIG_MACH_CPU9260) += board-cpu9krea.o | 48 | obj-$(CONFIG_MACH_CPU9260) += board-cpu9krea.o |
49 | obj-$(CONFIG_MACH_FLEXIBITY) += board-flexibity.o | ||
49 | 50 | ||
50 | # AT91SAM9261 board-specific support | 51 | # AT91SAM9261 board-specific support |
51 | obj-$(CONFIG_MACH_AT91SAM9261EK) += board-sam9261ek.o | 52 | obj-$(CONFIG_MACH_AT91SAM9261EK) += board-sam9261ek.o |
diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c index 5e71ccd5e7d3..1276babf84d5 100644 --- a/arch/arm/mach-at91/at91sam9g45_devices.c +++ b/arch/arm/mach-at91/at91sam9g45_devices.c | |||
@@ -426,7 +426,7 @@ static struct i2c_gpio_platform_data pdata_i2c0 = { | |||
426 | .sda_is_open_drain = 1, | 426 | .sda_is_open_drain = 1, |
427 | .scl_pin = AT91_PIN_PA21, | 427 | .scl_pin = AT91_PIN_PA21, |
428 | .scl_is_open_drain = 1, | 428 | .scl_is_open_drain = 1, |
429 | .udelay = 2, /* ~100 kHz */ | 429 | .udelay = 5, /* ~100 kHz */ |
430 | }; | 430 | }; |
431 | 431 | ||
432 | static struct platform_device at91sam9g45_twi0_device = { | 432 | static struct platform_device at91sam9g45_twi0_device = { |
@@ -440,7 +440,7 @@ static struct i2c_gpio_platform_data pdata_i2c1 = { | |||
440 | .sda_is_open_drain = 1, | 440 | .sda_is_open_drain = 1, |
441 | .scl_pin = AT91_PIN_PB11, | 441 | .scl_pin = AT91_PIN_PB11, |
442 | .scl_is_open_drain = 1, | 442 | .scl_is_open_drain = 1, |
443 | .udelay = 2, /* ~100 kHz */ | 443 | .udelay = 5, /* ~100 kHz */ |
444 | }; | 444 | }; |
445 | 445 | ||
446 | static struct platform_device at91sam9g45_twi1_device = { | 446 | static struct platform_device at91sam9g45_twi1_device = { |
diff --git a/arch/arm/mach-at91/board-flexibity.c b/arch/arm/mach-at91/board-flexibity.c new file mode 100644 index 000000000000..216c8ca985f4 --- /dev/null +++ b/arch/arm/mach-at91/board-flexibity.c | |||
@@ -0,0 +1,164 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mach-at91/board-flexibity.c | ||
3 | * | ||
4 | * Copyright (C) 2010 Flexibity | ||
5 | * Copyright (C) 2005 SAN People | ||
6 | * Copyright (C) 2006 Atmel | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
21 | */ | ||
22 | |||
23 | #include <linux/init.h> | ||
24 | #include <linux/platform_device.h> | ||
25 | #include <linux/spi/spi.h> | ||
26 | #include <linux/input.h> | ||
27 | #include <linux/gpio.h> | ||
28 | |||
29 | #include <asm/mach-types.h> | ||
30 | |||
31 | #include <asm/mach/arch.h> | ||
32 | #include <asm/mach/map.h> | ||
33 | #include <asm/mach/irq.h> | ||
34 | |||
35 | #include <mach/hardware.h> | ||
36 | #include <mach/board.h> | ||
37 | |||
38 | #include "generic.h" | ||
39 | |||
40 | static void __init flexibity_map_io(void) | ||
41 | { | ||
42 | /* Initialize processor: 18.432 MHz crystal */ | ||
43 | at91sam9260_initialize(18432000); | ||
44 | |||
45 | /* DBGU on ttyS0. (Rx & Tx only) */ | ||
46 | at91_register_uart(0, 0, 0); | ||
47 | |||
48 | /* set serial console to ttyS0 (ie, DBGU) */ | ||
49 | at91_set_serial_console(0); | ||
50 | } | ||
51 | |||
52 | static void __init flexibity_init_irq(void) | ||
53 | { | ||
54 | at91sam9260_init_interrupts(NULL); | ||
55 | } | ||
56 | |||
57 | /* USB Host port */ | ||
58 | static struct at91_usbh_data __initdata flexibity_usbh_data = { | ||
59 | .ports = 2, | ||
60 | }; | ||
61 | |||
62 | /* USB Device port */ | ||
63 | static struct at91_udc_data __initdata flexibity_udc_data = { | ||
64 | .vbus_pin = AT91_PIN_PC5, | ||
65 | .pullup_pin = 0, /* pull-up driven by UDC */ | ||
66 | }; | ||
67 | |||
68 | /* SPI devices */ | ||
69 | static struct spi_board_info flexibity_spi_devices[] = { | ||
70 | { /* DataFlash chip */ | ||
71 | .modalias = "mtd_dataflash", | ||
72 | .chip_select = 1, | ||
73 | .max_speed_hz = 15 * 1000 * 1000, | ||
74 | .bus_num = 0, | ||
75 | }, | ||
76 | }; | ||
77 | |||
78 | /* MCI (SD/MMC) */ | ||
79 | static struct at91_mmc_data __initdata flexibity_mmc_data = { | ||
80 | .slot_b = 0, | ||
81 | .wire4 = 1, | ||
82 | .det_pin = AT91_PIN_PC9, | ||
83 | .wp_pin = AT91_PIN_PC4, | ||
84 | }; | ||
85 | |||
86 | /* LEDs */ | ||
87 | static struct gpio_led flexibity_leds[] = { | ||
88 | { | ||
89 | .name = "usb1:green", | ||
90 | .gpio = AT91_PIN_PA12, | ||
91 | .active_low = 1, | ||
92 | .default_trigger = "default-on", | ||
93 | }, | ||
94 | { | ||
95 | .name = "usb1:red", | ||
96 | .gpio = AT91_PIN_PA13, | ||
97 | .active_low = 1, | ||
98 | .default_trigger = "default-on", | ||
99 | }, | ||
100 | { | ||
101 | .name = "usb2:green", | ||
102 | .gpio = AT91_PIN_PB26, | ||
103 | .active_low = 1, | ||
104 | .default_trigger = "default-on", | ||
105 | }, | ||
106 | { | ||
107 | .name = "usb2:red", | ||
108 | .gpio = AT91_PIN_PB27, | ||
109 | .active_low = 1, | ||
110 | .default_trigger = "default-on", | ||
111 | }, | ||
112 | { | ||
113 | .name = "usb3:green", | ||
114 | .gpio = AT91_PIN_PC8, | ||
115 | .active_low = 1, | ||
116 | .default_trigger = "default-on", | ||
117 | }, | ||
118 | { | ||
119 | .name = "usb3:red", | ||
120 | .gpio = AT91_PIN_PC6, | ||
121 | .active_low = 1, | ||
122 | .default_trigger = "default-on", | ||
123 | }, | ||
124 | { | ||
125 | .name = "usb4:green", | ||
126 | .gpio = AT91_PIN_PB4, | ||
127 | .active_low = 1, | ||
128 | .default_trigger = "default-on", | ||
129 | }, | ||
130 | { | ||
131 | .name = "usb4:red", | ||
132 | .gpio = AT91_PIN_PB5, | ||
133 | .active_low = 1, | ||
134 | .default_trigger = "default-on", | ||
135 | } | ||
136 | }; | ||
137 | |||
138 | static void __init flexibity_board_init(void) | ||
139 | { | ||
140 | /* Serial */ | ||
141 | at91_add_device_serial(); | ||
142 | /* USB Host */ | ||
143 | at91_add_device_usbh(&flexibity_usbh_data); | ||
144 | /* USB Device */ | ||
145 | at91_add_device_udc(&flexibity_udc_data); | ||
146 | /* SPI */ | ||
147 | at91_add_device_spi(flexibity_spi_devices, | ||
148 | ARRAY_SIZE(flexibity_spi_devices)); | ||
149 | /* MMC */ | ||
150 | at91_add_device_mmc(0, &flexibity_mmc_data); | ||
151 | /* LEDs */ | ||
152 | at91_gpio_leds(flexibity_leds, ARRAY_SIZE(flexibity_leds)); | ||
153 | } | ||
154 | |||
155 | MACHINE_START(FLEXIBITY, "Flexibity Connect") | ||
156 | /* Maintainer: Maxim Osipov */ | ||
157 | .phys_io = AT91_BASE_SYS, | ||
158 | .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc, | ||
159 | .boot_params = AT91_SDRAM_BASE + 0x100, | ||
160 | .timer = &at91sam926x_timer, | ||
161 | .map_io = flexibity_map_io, | ||
162 | .init_irq = flexibity_init_irq, | ||
163 | .init_machine = flexibity_board_init, | ||
164 | MACHINE_END | ||
diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c index 3d996b659ff4..9be261beae7d 100644 --- a/arch/arm/mach-davinci/dm355.c +++ b/arch/arm/mach-davinci/dm355.c | |||
@@ -769,8 +769,7 @@ static struct map_desc dm355_io_desc[] = { | |||
769 | .virtual = SRAM_VIRT, | 769 | .virtual = SRAM_VIRT, |
770 | .pfn = __phys_to_pfn(0x00010000), | 770 | .pfn = __phys_to_pfn(0x00010000), |
771 | .length = SZ_32K, | 771 | .length = SZ_32K, |
772 | /* MT_MEMORY_NONCACHED requires supersection alignment */ | 772 | .type = MT_MEMORY_NONCACHED, |
773 | .type = MT_DEVICE, | ||
774 | }, | 773 | }, |
775 | }; | 774 | }; |
776 | 775 | ||
diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c index 6b6f4c643709..7781e35daec3 100644 --- a/arch/arm/mach-davinci/dm365.c +++ b/arch/arm/mach-davinci/dm365.c | |||
@@ -969,8 +969,7 @@ static struct map_desc dm365_io_desc[] = { | |||
969 | .virtual = SRAM_VIRT, | 969 | .virtual = SRAM_VIRT, |
970 | .pfn = __phys_to_pfn(0x00010000), | 970 | .pfn = __phys_to_pfn(0x00010000), |
971 | .length = SZ_32K, | 971 | .length = SZ_32K, |
972 | /* MT_MEMORY_NONCACHED requires supersection alignment */ | 972 | .type = MT_MEMORY_NONCACHED, |
973 | .type = MT_DEVICE, | ||
974 | }, | 973 | }, |
975 | }; | 974 | }; |
976 | 975 | ||
diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c index 40fec315c99a..5e5b0a7831fb 100644 --- a/arch/arm/mach-davinci/dm644x.c +++ b/arch/arm/mach-davinci/dm644x.c | |||
@@ -653,8 +653,7 @@ static struct map_desc dm644x_io_desc[] = { | |||
653 | .virtual = SRAM_VIRT, | 653 | .virtual = SRAM_VIRT, |
654 | .pfn = __phys_to_pfn(0x00008000), | 654 | .pfn = __phys_to_pfn(0x00008000), |
655 | .length = SZ_16K, | 655 | .length = SZ_16K, |
656 | /* MT_MEMORY_NONCACHED requires supersection alignment */ | 656 | .type = MT_MEMORY_NONCACHED, |
657 | .type = MT_DEVICE, | ||
658 | }, | 657 | }, |
659 | }; | 658 | }; |
660 | 659 | ||
diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c index e4a3df1872ac..26e8a9c7f50b 100644 --- a/arch/arm/mach-davinci/dm646x.c +++ b/arch/arm/mach-davinci/dm646x.c | |||
@@ -737,8 +737,7 @@ static struct map_desc dm646x_io_desc[] = { | |||
737 | .virtual = SRAM_VIRT, | 737 | .virtual = SRAM_VIRT, |
738 | .pfn = __phys_to_pfn(0x00010000), | 738 | .pfn = __phys_to_pfn(0x00010000), |
739 | .length = SZ_32K, | 739 | .length = SZ_32K, |
740 | /* MT_MEMORY_NONCACHED requires supersection alignment */ | 740 | .type = MT_MEMORY_NONCACHED, |
741 | .type = MT_DEVICE, | ||
742 | }, | 741 | }, |
743 | }; | 742 | }; |
744 | 743 | ||
diff --git a/arch/arm/mach-dove/include/mach/io.h b/arch/arm/mach-dove/include/mach/io.h index 3b3e4721ce2e..eb4936ff90ad 100644 --- a/arch/arm/mach-dove/include/mach/io.h +++ b/arch/arm/mach-dove/include/mach/io.h | |||
@@ -13,8 +13,8 @@ | |||
13 | 13 | ||
14 | #define IO_SPACE_LIMIT 0xffffffff | 14 | #define IO_SPACE_LIMIT 0xffffffff |
15 | 15 | ||
16 | #define __io(a) ((void __iomem *)(((a) - DOVE_PCIE0_IO_PHYS_BASE) +\ | 16 | #define __io(a) ((void __iomem *)(((a) - DOVE_PCIE0_IO_BUS_BASE) + \ |
17 | DOVE_PCIE0_IO_VIRT_BASE)) | 17 | DOVE_PCIE0_IO_VIRT_BASE)) |
18 | #define __mem_pci(a) (a) | 18 | #define __mem_pci(a) (a) |
19 | 19 | ||
20 | #endif | 20 | #endif |
diff --git a/arch/arm/mach-ixp4xx/common-pci.c b/arch/arm/mach-ixp4xx/common-pci.c index 61cd4d64b985..24498a932ba6 100644 --- a/arch/arm/mach-ixp4xx/common-pci.c +++ b/arch/arm/mach-ixp4xx/common-pci.c | |||
@@ -503,6 +503,14 @@ struct pci_bus * __devinit ixp4xx_scan_bus(int nr, struct pci_sys_data *sys) | |||
503 | return pci_scan_bus(sys->busnr, &ixp4xx_ops, sys); | 503 | return pci_scan_bus(sys->busnr, &ixp4xx_ops, sys); |
504 | } | 504 | } |
505 | 505 | ||
506 | int dma_set_coherent_mask(struct device *dev, u64 mask) | ||
507 | { | ||
508 | if (mask >= SZ_64M - 1) | ||
509 | return 0; | ||
510 | |||
511 | return -EIO; | ||
512 | } | ||
513 | |||
506 | EXPORT_SYMBOL(ixp4xx_pci_read); | 514 | EXPORT_SYMBOL(ixp4xx_pci_read); |
507 | EXPORT_SYMBOL(ixp4xx_pci_write); | 515 | EXPORT_SYMBOL(ixp4xx_pci_write); |
508 | 516 | ||
diff --git a/arch/arm/mach-ixp4xx/include/mach/hardware.h b/arch/arm/mach-ixp4xx/include/mach/hardware.h index f91ca6d4fbe8..8138371c406e 100644 --- a/arch/arm/mach-ixp4xx/include/mach/hardware.h +++ b/arch/arm/mach-ixp4xx/include/mach/hardware.h | |||
@@ -26,6 +26,8 @@ | |||
26 | #define PCIBIOS_MAX_MEM 0x4BFFFFFF | 26 | #define PCIBIOS_MAX_MEM 0x4BFFFFFF |
27 | #endif | 27 | #endif |
28 | 28 | ||
29 | #define ARCH_HAS_DMA_SET_COHERENT_MASK | ||
30 | |||
29 | #define pcibios_assign_all_busses() 1 | 31 | #define pcibios_assign_all_busses() 1 |
30 | 32 | ||
31 | /* Register locations and bits */ | 33 | /* Register locations and bits */ |
diff --git a/arch/arm/mach-kirkwood/include/mach/kirkwood.h b/arch/arm/mach-kirkwood/include/mach/kirkwood.h index 93fc2ec95e76..6e924b398919 100644 --- a/arch/arm/mach-kirkwood/include/mach/kirkwood.h +++ b/arch/arm/mach-kirkwood/include/mach/kirkwood.h | |||
@@ -38,7 +38,7 @@ | |||
38 | 38 | ||
39 | #define KIRKWOOD_PCIE1_IO_PHYS_BASE 0xf3000000 | 39 | #define KIRKWOOD_PCIE1_IO_PHYS_BASE 0xf3000000 |
40 | #define KIRKWOOD_PCIE1_IO_VIRT_BASE 0xfef00000 | 40 | #define KIRKWOOD_PCIE1_IO_VIRT_BASE 0xfef00000 |
41 | #define KIRKWOOD_PCIE1_IO_BUS_BASE 0x00000000 | 41 | #define KIRKWOOD_PCIE1_IO_BUS_BASE 0x00100000 |
42 | #define KIRKWOOD_PCIE1_IO_SIZE SZ_1M | 42 | #define KIRKWOOD_PCIE1_IO_SIZE SZ_1M |
43 | 43 | ||
44 | #define KIRKWOOD_PCIE_IO_PHYS_BASE 0xf2000000 | 44 | #define KIRKWOOD_PCIE_IO_PHYS_BASE 0xf2000000 |
diff --git a/arch/arm/mach-kirkwood/pcie.c b/arch/arm/mach-kirkwood/pcie.c index 55e7f00836b7..513ad3102d7c 100644 --- a/arch/arm/mach-kirkwood/pcie.c +++ b/arch/arm/mach-kirkwood/pcie.c | |||
@@ -117,7 +117,7 @@ static void __init pcie0_ioresources_init(struct pcie_port *pp) | |||
117 | * IORESOURCE_IO | 117 | * IORESOURCE_IO |
118 | */ | 118 | */ |
119 | pp->res[0].name = "PCIe 0 I/O Space"; | 119 | pp->res[0].name = "PCIe 0 I/O Space"; |
120 | pp->res[0].start = KIRKWOOD_PCIE_IO_PHYS_BASE; | 120 | pp->res[0].start = KIRKWOOD_PCIE_IO_BUS_BASE; |
121 | pp->res[0].end = pp->res[0].start + KIRKWOOD_PCIE_IO_SIZE - 1; | 121 | pp->res[0].end = pp->res[0].start + KIRKWOOD_PCIE_IO_SIZE - 1; |
122 | pp->res[0].flags = IORESOURCE_IO; | 122 | pp->res[0].flags = IORESOURCE_IO; |
123 | 123 | ||
@@ -139,7 +139,7 @@ static void __init pcie1_ioresources_init(struct pcie_port *pp) | |||
139 | * IORESOURCE_IO | 139 | * IORESOURCE_IO |
140 | */ | 140 | */ |
141 | pp->res[0].name = "PCIe 1 I/O Space"; | 141 | pp->res[0].name = "PCIe 1 I/O Space"; |
142 | pp->res[0].start = KIRKWOOD_PCIE1_IO_PHYS_BASE; | 142 | pp->res[0].start = KIRKWOOD_PCIE1_IO_BUS_BASE; |
143 | pp->res[0].end = pp->res[0].start + KIRKWOOD_PCIE1_IO_SIZE - 1; | 143 | pp->res[0].end = pp->res[0].start + KIRKWOOD_PCIE1_IO_SIZE - 1; |
144 | pp->res[0].flags = IORESOURCE_IO; | 144 | pp->res[0].flags = IORESOURCE_IO; |
145 | 145 | ||
diff --git a/arch/arm/mach-mmp/include/mach/system.h b/arch/arm/mach-mmp/include/mach/system.h index 4f5b0e0ce6cf..1a8a25edb1b4 100644 --- a/arch/arm/mach-mmp/include/mach/system.h +++ b/arch/arm/mach-mmp/include/mach/system.h | |||
@@ -9,6 +9,8 @@ | |||
9 | #ifndef __ASM_MACH_SYSTEM_H | 9 | #ifndef __ASM_MACH_SYSTEM_H |
10 | #define __ASM_MACH_SYSTEM_H | 10 | #define __ASM_MACH_SYSTEM_H |
11 | 11 | ||
12 | #include <mach/cputype.h> | ||
13 | |||
12 | static inline void arch_idle(void) | 14 | static inline void arch_idle(void) |
13 | { | 15 | { |
14 | cpu_do_idle(); | 16 | cpu_do_idle(); |
@@ -16,6 +18,9 @@ static inline void arch_idle(void) | |||
16 | 18 | ||
17 | static inline void arch_reset(char mode, const char *cmd) | 19 | static inline void arch_reset(char mode, const char *cmd) |
18 | { | 20 | { |
19 | cpu_reset(0); | 21 | if (cpu_is_pxa168()) |
22 | cpu_reset(0xffff0000); | ||
23 | else | ||
24 | cpu_reset(0); | ||
20 | } | 25 | } |
21 | #endif /* __ASM_MACH_SYSTEM_H */ | 26 | #endif /* __ASM_MACH_SYSTEM_H */ |
diff --git a/arch/arm/mach-pxa/cpufreq-pxa2xx.c b/arch/arm/mach-pxa/cpufreq-pxa2xx.c index 50d5939a78f1..58093d9e07be 100644 --- a/arch/arm/mach-pxa/cpufreq-pxa2xx.c +++ b/arch/arm/mach-pxa/cpufreq-pxa2xx.c | |||
@@ -312,8 +312,7 @@ static int pxa_set_target(struct cpufreq_policy *policy, | |||
312 | freqs.cpu = policy->cpu; | 312 | freqs.cpu = policy->cpu; |
313 | 313 | ||
314 | if (freq_debug) | 314 | if (freq_debug) |
315 | pr_debug(KERN_INFO "Changing CPU frequency to %d Mhz, " | 315 | pr_debug("Changing CPU frequency to %d Mhz, (SDRAM %d Mhz)\n", |
316 | "(SDRAM %d Mhz)\n", | ||
317 | freqs.new / 1000, (pxa_freq_settings[idx].div2) ? | 316 | freqs.new / 1000, (pxa_freq_settings[idx].div2) ? |
318 | (new_freq_mem / 2000) : (new_freq_mem / 1000)); | 317 | (new_freq_mem / 2000) : (new_freq_mem / 1000)); |
319 | 318 | ||
diff --git a/arch/arm/mach-pxa/include/mach/hardware.h b/arch/arm/mach-pxa/include/mach/hardware.h index 7f64d24cd564..814f1458a06a 100644 --- a/arch/arm/mach-pxa/include/mach/hardware.h +++ b/arch/arm/mach-pxa/include/mach/hardware.h | |||
@@ -264,23 +264,35 @@ | |||
264 | * <= 0x2 for pxa21x/pxa25x/pxa26x/pxa27x | 264 | * <= 0x2 for pxa21x/pxa25x/pxa26x/pxa27x |
265 | * == 0x3 for pxa300/pxa310/pxa320 | 265 | * == 0x3 for pxa300/pxa310/pxa320 |
266 | */ | 266 | */ |
267 | #if defined(CONFIG_PXA25x) || defined(CONFIG_PXA27x) | ||
267 | #define __cpu_is_pxa2xx(id) \ | 268 | #define __cpu_is_pxa2xx(id) \ |
268 | ({ \ | 269 | ({ \ |
269 | unsigned int _id = (id) >> 13 & 0x7; \ | 270 | unsigned int _id = (id) >> 13 & 0x7; \ |
270 | _id <= 0x2; \ | 271 | _id <= 0x2; \ |
271 | }) | 272 | }) |
273 | #else | ||
274 | #define __cpu_is_pxa2xx(id) (0) | ||
275 | #endif | ||
272 | 276 | ||
277 | #ifdef CONFIG_PXA3xx | ||
273 | #define __cpu_is_pxa3xx(id) \ | 278 | #define __cpu_is_pxa3xx(id) \ |
274 | ({ \ | 279 | ({ \ |
275 | unsigned int _id = (id) >> 13 & 0x7; \ | 280 | unsigned int _id = (id) >> 13 & 0x7; \ |
276 | _id == 0x3; \ | 281 | _id == 0x3; \ |
277 | }) | 282 | }) |
283 | #else | ||
284 | #define __cpu_is_pxa3xx(id) (0) | ||
285 | #endif | ||
278 | 286 | ||
287 | #if defined(CONFIG_CPU_PXA930) || defined(CONFIG_CPU_PXA935) | ||
279 | #define __cpu_is_pxa93x(id) \ | 288 | #define __cpu_is_pxa93x(id) \ |
280 | ({ \ | 289 | ({ \ |
281 | unsigned int _id = (id) >> 4 & 0xfff; \ | 290 | unsigned int _id = (id) >> 4 & 0xfff; \ |
282 | _id == 0x683 || _id == 0x693; \ | 291 | _id == 0x683 || _id == 0x693; \ |
283 | }) | 292 | }) |
293 | #else | ||
294 | #define __cpu_is_pxa93x(id) (0) | ||
295 | #endif | ||
284 | 296 | ||
285 | #define cpu_is_pxa2xx() \ | 297 | #define cpu_is_pxa2xx() \ |
286 | ({ \ | 298 | ({ \ |
@@ -309,7 +321,7 @@ extern unsigned long get_clock_tick_rate(void); | |||
309 | #define PCIBIOS_MIN_IO 0 | 321 | #define PCIBIOS_MIN_IO 0 |
310 | #define PCIBIOS_MIN_MEM 0 | 322 | #define PCIBIOS_MIN_MEM 0 |
311 | #define pcibios_assign_all_busses() 1 | 323 | #define pcibios_assign_all_busses() 1 |
324 | #define ARCH_HAS_DMA_SET_COHERENT_MASK | ||
312 | #endif | 325 | #endif |
313 | 326 | ||
314 | |||
315 | #endif /* _ASM_ARCH_HARDWARE_H */ | 327 | #endif /* _ASM_ARCH_HARDWARE_H */ |
diff --git a/arch/arm/mach-pxa/include/mach/io.h b/arch/arm/mach-pxa/include/mach/io.h index 262691fb97d8..fdca3be47d9b 100644 --- a/arch/arm/mach-pxa/include/mach/io.h +++ b/arch/arm/mach-pxa/include/mach/io.h | |||
@@ -6,6 +6,8 @@ | |||
6 | #ifndef __ASM_ARM_ARCH_IO_H | 6 | #ifndef __ASM_ARM_ARCH_IO_H |
7 | #define __ASM_ARM_ARCH_IO_H | 7 | #define __ASM_ARM_ARCH_IO_H |
8 | 8 | ||
9 | #include <mach/hardware.h> | ||
10 | |||
9 | #define IO_SPACE_LIMIT 0xffffffff | 11 | #define IO_SPACE_LIMIT 0xffffffff |
10 | 12 | ||
11 | /* | 13 | /* |
diff --git a/arch/arm/mach-pxa/palm27x.c b/arch/arm/mach-pxa/palm27x.c index 77ad6d34ab5b..405b92a29793 100644 --- a/arch/arm/mach-pxa/palm27x.c +++ b/arch/arm/mach-pxa/palm27x.c | |||
@@ -469,9 +469,13 @@ static struct i2c_board_info __initdata palm27x_pi2c_board_info[] = { | |||
469 | }, | 469 | }, |
470 | }; | 470 | }; |
471 | 471 | ||
472 | static struct i2c_pxa_platform_data palm27x_i2c_power_info = { | ||
473 | .use_pio = 1, | ||
474 | }; | ||
475 | |||
472 | void __init palm27x_pmic_init(void) | 476 | void __init palm27x_pmic_init(void) |
473 | { | 477 | { |
474 | i2c_register_board_info(1, ARRAY_AND_SIZE(palm27x_pi2c_board_info)); | 478 | i2c_register_board_info(1, ARRAY_AND_SIZE(palm27x_pi2c_board_info)); |
475 | pxa27x_set_i2c_power_info(NULL); | 479 | pxa27x_set_i2c_power_info(&palm27x_i2c_power_info); |
476 | } | 480 | } |
477 | #endif | 481 | #endif |
diff --git a/arch/arm/mach-pxa/vpac270.c b/arch/arm/mach-pxa/vpac270.c index c9b747cedea8..37d6173bbb66 100644 --- a/arch/arm/mach-pxa/vpac270.c +++ b/arch/arm/mach-pxa/vpac270.c | |||
@@ -240,6 +240,7 @@ static void __init vpac270_onenand_init(void) {} | |||
240 | #if defined(CONFIG_MMC_PXA) || defined(CONFIG_MMC_PXA_MODULE) | 240 | #if defined(CONFIG_MMC_PXA) || defined(CONFIG_MMC_PXA_MODULE) |
241 | static struct pxamci_platform_data vpac270_mci_platform_data = { | 241 | static struct pxamci_platform_data vpac270_mci_platform_data = { |
242 | .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, | 242 | .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, |
243 | .gpio_power = -1, | ||
243 | .gpio_card_detect = GPIO53_VPAC270_SD_DETECT_N, | 244 | .gpio_card_detect = GPIO53_VPAC270_SD_DETECT_N, |
244 | .gpio_card_ro = GPIO52_VPAC270_SD_READONLY, | 245 | .gpio_card_ro = GPIO52_VPAC270_SD_READONLY, |
245 | .detect_delay_ms = 200, | 246 | .detect_delay_ms = 200, |
diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c index 2fa38df28414..07c08151dfe6 100644 --- a/arch/arm/mach-realview/core.c +++ b/arch/arm/mach-realview/core.c | |||
@@ -259,6 +259,7 @@ struct mmci_platform_data realview_mmc0_plat_data = { | |||
259 | .status = realview_mmc_status, | 259 | .status = realview_mmc_status, |
260 | .gpio_wp = 17, | 260 | .gpio_wp = 17, |
261 | .gpio_cd = 16, | 261 | .gpio_cd = 16, |
262 | .cd_invert = true, | ||
262 | }; | 263 | }; |
263 | 264 | ||
264 | struct mmci_platform_data realview_mmc1_plat_data = { | 265 | struct mmci_platform_data realview_mmc1_plat_data = { |
@@ -266,6 +267,7 @@ struct mmci_platform_data realview_mmc1_plat_data = { | |||
266 | .status = realview_mmc_status, | 267 | .status = realview_mmc_status, |
267 | .gpio_wp = 19, | 268 | .gpio_wp = 19, |
268 | .gpio_cd = 18, | 269 | .gpio_cd = 18, |
270 | .cd_invert = true, | ||
269 | }; | 271 | }; |
270 | 272 | ||
271 | /* | 273 | /* |
diff --git a/arch/arm/mach-realview/include/mach/smp.h b/arch/arm/mach-realview/include/mach/smp.h index dd53892d44a7..d3cd265cb058 100644 --- a/arch/arm/mach-realview/include/mach/smp.h +++ b/arch/arm/mach-realview/include/mach/smp.h | |||
@@ -1,16 +1,8 @@ | |||
1 | #ifndef ASMARM_ARCH_SMP_H | 1 | #ifndef ASMARM_ARCH_SMP_H |
2 | #define ASMARM_ARCH_SMP_H | 2 | #define ASMARM_ARCH_SMP_H |
3 | 3 | ||
4 | |||
5 | #include <asm/hardware/gic.h> | 4 | #include <asm/hardware/gic.h> |
6 | 5 | #include <asm/smp_mpidr.h> | |
7 | #define hard_smp_processor_id() \ | ||
8 | ({ \ | ||
9 | unsigned int cpunum; \ | ||
10 | __asm__("mrc p15, 0, %0, c0, c0, 5" \ | ||
11 | : "=r" (cpunum)); \ | ||
12 | cpunum &= 0x0F; \ | ||
13 | }) | ||
14 | 6 | ||
15 | /* | 7 | /* |
16 | * We use IRQ1 as the IPI | 8 | * We use IRQ1 as the IPI |
diff --git a/arch/arm/mach-s3c64xx/dev-spi.c b/arch/arm/mach-s3c64xx/dev-spi.c index a492b982aa06..405e62128917 100644 --- a/arch/arm/mach-s3c64xx/dev-spi.c +++ b/arch/arm/mach-s3c64xx/dev-spi.c | |||
@@ -18,10 +18,11 @@ | |||
18 | #include <mach/map.h> | 18 | #include <mach/map.h> |
19 | #include <mach/gpio-bank-c.h> | 19 | #include <mach/gpio-bank-c.h> |
20 | #include <mach/spi-clocks.h> | 20 | #include <mach/spi-clocks.h> |
21 | #include <mach/irqs.h> | ||
21 | 22 | ||
22 | #include <plat/s3c64xx-spi.h> | 23 | #include <plat/s3c64xx-spi.h> |
23 | #include <plat/gpio-cfg.h> | 24 | #include <plat/gpio-cfg.h> |
24 | #include <plat/irqs.h> | 25 | #include <plat/devs.h> |
25 | 26 | ||
26 | static char *spi_src_clks[] = { | 27 | static char *spi_src_clks[] = { |
27 | [S3C64XX_SPI_SRCCLK_PCLK] = "pclk", | 28 | [S3C64XX_SPI_SRCCLK_PCLK] = "pclk", |
diff --git a/arch/arm/mach-s3c64xx/mach-real6410.c b/arch/arm/mach-s3c64xx/mach-real6410.c index 5c07d013b23d..e130379ba0e8 100644 --- a/arch/arm/mach-s3c64xx/mach-real6410.c +++ b/arch/arm/mach-s3c64xx/mach-real6410.c | |||
@@ -30,73 +30,73 @@ | |||
30 | #include <plat/devs.h> | 30 | #include <plat/devs.h> |
31 | #include <plat/regs-serial.h> | 31 | #include <plat/regs-serial.h> |
32 | 32 | ||
33 | #define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK | 33 | #define UCON (S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK) |
34 | #define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB | 34 | #define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB) |
35 | #define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE | 35 | #define UFCON (S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE) |
36 | 36 | ||
37 | static struct s3c2410_uartcfg real6410_uartcfgs[] __initdata = { | 37 | static struct s3c2410_uartcfg real6410_uartcfgs[] __initdata = { |
38 | [0] = { | 38 | [0] = { |
39 | .hwport = 0, | 39 | .hwport = 0, |
40 | .flags = 0, | 40 | .flags = 0, |
41 | .ucon = UCON, | 41 | .ucon = UCON, |
42 | .ulcon = ULCON, | 42 | .ulcon = ULCON, |
43 | .ufcon = UFCON, | 43 | .ufcon = UFCON, |
44 | }, | 44 | }, |
45 | [1] = { | 45 | [1] = { |
46 | .hwport = 1, | 46 | .hwport = 1, |
47 | .flags = 0, | 47 | .flags = 0, |
48 | .ucon = UCON, | 48 | .ucon = UCON, |
49 | .ulcon = ULCON, | 49 | .ulcon = ULCON, |
50 | .ufcon = UFCON, | 50 | .ufcon = UFCON, |
51 | }, | 51 | }, |
52 | [2] = { | 52 | [2] = { |
53 | .hwport = 2, | 53 | .hwport = 2, |
54 | .flags = 0, | 54 | .flags = 0, |
55 | .ucon = UCON, | 55 | .ucon = UCON, |
56 | .ulcon = ULCON, | 56 | .ulcon = ULCON, |
57 | .ufcon = UFCON, | 57 | .ufcon = UFCON, |
58 | }, | 58 | }, |
59 | [3] = { | 59 | [3] = { |
60 | .hwport = 3, | 60 | .hwport = 3, |
61 | .flags = 0, | 61 | .flags = 0, |
62 | .ucon = UCON, | 62 | .ucon = UCON, |
63 | .ulcon = ULCON, | 63 | .ulcon = ULCON, |
64 | .ufcon = UFCON, | 64 | .ufcon = UFCON, |
65 | }, | 65 | }, |
66 | }; | 66 | }; |
67 | 67 | ||
68 | /* DM9000AEP 10/100 ethernet controller */ | 68 | /* DM9000AEP 10/100 ethernet controller */ |
69 | 69 | ||
70 | static struct resource real6410_dm9k_resource[] = { | 70 | static struct resource real6410_dm9k_resource[] = { |
71 | [0] = { | 71 | [0] = { |
72 | .start = S3C64XX_PA_XM0CSN1, | 72 | .start = S3C64XX_PA_XM0CSN1, |
73 | .end = S3C64XX_PA_XM0CSN1 + 1, | 73 | .end = S3C64XX_PA_XM0CSN1 + 1, |
74 | .flags = IORESOURCE_MEM | 74 | .flags = IORESOURCE_MEM |
75 | }, | 75 | }, |
76 | [1] = { | 76 | [1] = { |
77 | .start = S3C64XX_PA_XM0CSN1 + 4, | 77 | .start = S3C64XX_PA_XM0CSN1 + 4, |
78 | .end = S3C64XX_PA_XM0CSN1 + 5, | 78 | .end = S3C64XX_PA_XM0CSN1 + 5, |
79 | .flags = IORESOURCE_MEM | 79 | .flags = IORESOURCE_MEM |
80 | }, | 80 | }, |
81 | [2] = { | 81 | [2] = { |
82 | .start = S3C_EINT(7), | 82 | .start = S3C_EINT(7), |
83 | .end = S3C_EINT(7), | 83 | .end = S3C_EINT(7), |
84 | .flags = IORESOURCE_IRQ, | 84 | .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL |
85 | } | 85 | } |
86 | }; | 86 | }; |
87 | 87 | ||
88 | static struct dm9000_plat_data real6410_dm9k_pdata = { | 88 | static struct dm9000_plat_data real6410_dm9k_pdata = { |
89 | .flags = (DM9000_PLATF_16BITONLY | DM9000_PLATF_NO_EEPROM), | 89 | .flags = (DM9000_PLATF_16BITONLY | DM9000_PLATF_NO_EEPROM), |
90 | }; | 90 | }; |
91 | 91 | ||
92 | static struct platform_device real6410_device_eth = { | 92 | static struct platform_device real6410_device_eth = { |
93 | .name = "dm9000", | 93 | .name = "dm9000", |
94 | .id = -1, | 94 | .id = -1, |
95 | .num_resources = ARRAY_SIZE(real6410_dm9k_resource), | 95 | .num_resources = ARRAY_SIZE(real6410_dm9k_resource), |
96 | .resource = real6410_dm9k_resource, | 96 | .resource = real6410_dm9k_resource, |
97 | .dev = { | 97 | .dev = { |
98 | .platform_data = &real6410_dm9k_pdata, | 98 | .platform_data = &real6410_dm9k_pdata, |
99 | }, | 99 | }, |
100 | }; | 100 | }; |
101 | 101 | ||
102 | static struct platform_device *real6410_devices[] __initdata = { | 102 | static struct platform_device *real6410_devices[] __initdata = { |
@@ -129,12 +129,12 @@ static void __init real6410_machine_init(void) | |||
129 | /* set timing for nCS1 suitable for ethernet chip */ | 129 | /* set timing for nCS1 suitable for ethernet chip */ |
130 | 130 | ||
131 | __raw_writel((0 << S3C64XX_SROM_BCX__PMC__SHIFT) | | 131 | __raw_writel((0 << S3C64XX_SROM_BCX__PMC__SHIFT) | |
132 | (6 << S3C64XX_SROM_BCX__TACP__SHIFT) | | 132 | (6 << S3C64XX_SROM_BCX__TACP__SHIFT) | |
133 | (4 << S3C64XX_SROM_BCX__TCAH__SHIFT) | | 133 | (4 << S3C64XX_SROM_BCX__TCAH__SHIFT) | |
134 | (1 << S3C64XX_SROM_BCX__TCOH__SHIFT) | | 134 | (1 << S3C64XX_SROM_BCX__TCOH__SHIFT) | |
135 | (13 << S3C64XX_SROM_BCX__TACC__SHIFT) | | 135 | (13 << S3C64XX_SROM_BCX__TACC__SHIFT) | |
136 | (4 << S3C64XX_SROM_BCX__TCOS__SHIFT) | | 136 | (4 << S3C64XX_SROM_BCX__TCOS__SHIFT) | |
137 | (0 << S3C64XX_SROM_BCX__TACS__SHIFT), S3C64XX_SROM_BC1); | 137 | (0 << S3C64XX_SROM_BCX__TACS__SHIFT), S3C64XX_SROM_BC1); |
138 | 138 | ||
139 | platform_add_devices(real6410_devices, ARRAY_SIZE(real6410_devices)); | 139 | platform_add_devices(real6410_devices, ARRAY_SIZE(real6410_devices)); |
140 | } | 140 | } |
diff --git a/arch/arm/mach-s3c64xx/mach-smartq.c b/arch/arm/mach-s3c64xx/mach-smartq.c index 3a9639bc3d9b..cb1ebeb08763 100644 --- a/arch/arm/mach-s3c64xx/mach-smartq.c +++ b/arch/arm/mach-s3c64xx/mach-smartq.c | |||
@@ -136,7 +136,7 @@ static struct platform_device smartq_usb_otg_vbus_dev = { | |||
136 | .dev.platform_data = &smartq_usb_otg_vbus_pdata, | 136 | .dev.platform_data = &smartq_usb_otg_vbus_pdata, |
137 | }; | 137 | }; |
138 | 138 | ||
139 | static int __init smartq_bl_init(struct device *dev) | 139 | static int smartq_bl_init(struct device *dev) |
140 | { | 140 | { |
141 | s3c_gpio_cfgpin(S3C64XX_GPF(15), S3C_GPIO_SFN(2)); | 141 | s3c_gpio_cfgpin(S3C64XX_GPF(15), S3C_GPIO_SFN(2)); |
142 | 142 | ||
diff --git a/arch/arm/mach-s3c64xx/mach-smartq5.c b/arch/arm/mach-s3c64xx/mach-smartq5.c index a4d59b076e3d..235e43928cb8 100644 --- a/arch/arm/mach-s3c64xx/mach-smartq5.c +++ b/arch/arm/mach-s3c64xx/mach-smartq5.c | |||
@@ -32,7 +32,7 @@ | |||
32 | 32 | ||
33 | #include "mach-smartq.h" | 33 | #include "mach-smartq.h" |
34 | 34 | ||
35 | static struct gpio_led smartq5_leds[] __initdata = { | 35 | static struct gpio_led smartq5_leds[] = { |
36 | { | 36 | { |
37 | .name = "smartq5:green", | 37 | .name = "smartq5:green", |
38 | .active_low = 1, | 38 | .active_low = 1, |
diff --git a/arch/arm/mach-s3c64xx/mach-smartq7.c b/arch/arm/mach-s3c64xx/mach-smartq7.c index e50a7d781732..78a58c351f0a 100644 --- a/arch/arm/mach-s3c64xx/mach-smartq7.c +++ b/arch/arm/mach-s3c64xx/mach-smartq7.c | |||
@@ -32,7 +32,7 @@ | |||
32 | 32 | ||
33 | #include "mach-smartq.h" | 33 | #include "mach-smartq.h" |
34 | 34 | ||
35 | static struct gpio_led smartq7_leds[] __initdata = { | 35 | static struct gpio_led smartq7_leds[] = { |
36 | { | 36 | { |
37 | .name = "smartq7:red", | 37 | .name = "smartq7:red", |
38 | .active_low = 1, | 38 | .active_low = 1, |
diff --git a/arch/arm/mach-s5pv210/clock.c b/arch/arm/mach-s5pv210/clock.c index af91fefef2c6..cfecd70657cb 100644 --- a/arch/arm/mach-s5pv210/clock.c +++ b/arch/arm/mach-s5pv210/clock.c | |||
@@ -281,6 +281,24 @@ static struct clk init_clocks_disable[] = { | |||
281 | .enable = s5pv210_clk_ip0_ctrl, | 281 | .enable = s5pv210_clk_ip0_ctrl, |
282 | .ctrlbit = (1<<29), | 282 | .ctrlbit = (1<<29), |
283 | }, { | 283 | }, { |
284 | .name = "fimc", | ||
285 | .id = 0, | ||
286 | .parent = &clk_hclk_dsys.clk, | ||
287 | .enable = s5pv210_clk_ip0_ctrl, | ||
288 | .ctrlbit = (1 << 24), | ||
289 | }, { | ||
290 | .name = "fimc", | ||
291 | .id = 1, | ||
292 | .parent = &clk_hclk_dsys.clk, | ||
293 | .enable = s5pv210_clk_ip0_ctrl, | ||
294 | .ctrlbit = (1 << 25), | ||
295 | }, { | ||
296 | .name = "fimc", | ||
297 | .id = 2, | ||
298 | .parent = &clk_hclk_dsys.clk, | ||
299 | .enable = s5pv210_clk_ip0_ctrl, | ||
300 | .ctrlbit = (1 << 26), | ||
301 | }, { | ||
284 | .name = "otg", | 302 | .name = "otg", |
285 | .id = -1, | 303 | .id = -1, |
286 | .parent = &clk_hclk_psys.clk, | 304 | .parent = &clk_hclk_psys.clk, |
@@ -357,7 +375,7 @@ static struct clk init_clocks_disable[] = { | |||
357 | .id = 1, | 375 | .id = 1, |
358 | .parent = &clk_pclk_psys.clk, | 376 | .parent = &clk_pclk_psys.clk, |
359 | .enable = s5pv210_clk_ip3_ctrl, | 377 | .enable = s5pv210_clk_ip3_ctrl, |
360 | .ctrlbit = (1<<8), | 378 | .ctrlbit = (1 << 10), |
361 | }, { | 379 | }, { |
362 | .name = "i2c", | 380 | .name = "i2c", |
363 | .id = 2, | 381 | .id = 2, |
diff --git a/arch/arm/mach-s5pv210/cpu.c b/arch/arm/mach-s5pv210/cpu.c index b9f4d677cf55..77f456c91ad3 100644 --- a/arch/arm/mach-s5pv210/cpu.c +++ b/arch/arm/mach-s5pv210/cpu.c | |||
@@ -47,7 +47,7 @@ static struct map_desc s5pv210_iodesc[] __initdata = { | |||
47 | { | 47 | { |
48 | .virtual = (unsigned long)S5P_VA_SYSTIMER, | 48 | .virtual = (unsigned long)S5P_VA_SYSTIMER, |
49 | .pfn = __phys_to_pfn(S5PV210_PA_SYSTIMER), | 49 | .pfn = __phys_to_pfn(S5PV210_PA_SYSTIMER), |
50 | .length = SZ_1M, | 50 | .length = SZ_4K, |
51 | .type = MT_DEVICE, | 51 | .type = MT_DEVICE, |
52 | }, { | 52 | }, { |
53 | .virtual = (unsigned long)VA_VIC2, | 53 | .virtual = (unsigned long)VA_VIC2, |
diff --git a/arch/arm/mach-s5pv310/include/mach/smp.h b/arch/arm/mach-s5pv310/include/mach/smp.h index 990f3ba88a1f..b7ec252384f4 100644 --- a/arch/arm/mach-s5pv310/include/mach/smp.h +++ b/arch/arm/mach-s5pv310/include/mach/smp.h | |||
@@ -7,17 +7,10 @@ | |||
7 | #define ASM_ARCH_SMP_H __FILE__ | 7 | #define ASM_ARCH_SMP_H __FILE__ |
8 | 8 | ||
9 | #include <asm/hardware/gic.h> | 9 | #include <asm/hardware/gic.h> |
10 | #include <asm/smp_mpidr.h> | ||
10 | 11 | ||
11 | extern void __iomem *gic_cpu_base_addr; | 12 | extern void __iomem *gic_cpu_base_addr; |
12 | 13 | ||
13 | #define hard_smp_processor_id() \ | ||
14 | ({ \ | ||
15 | unsigned int cpunum; \ | ||
16 | __asm__("mrc p15, 0, %0, c0, c0, 5" \ | ||
17 | : "=r" (cpunum)); \ | ||
18 | cpunum &= 0x03; \ | ||
19 | }) | ||
20 | |||
21 | /* | 14 | /* |
22 | * We use IRQ1 as the IPI | 15 | * We use IRQ1 as the IPI |
23 | */ | 16 | */ |
diff --git a/arch/arm/mach-tegra/include/mach/smp.h b/arch/arm/mach-tegra/include/mach/smp.h index 8b42dab79a70..e4a34a35a544 100644 --- a/arch/arm/mach-tegra/include/mach/smp.h +++ b/arch/arm/mach-tegra/include/mach/smp.h | |||
@@ -1,16 +1,8 @@ | |||
1 | #ifndef ASMARM_ARCH_SMP_H | 1 | #ifndef ASMARM_ARCH_SMP_H |
2 | #define ASMARM_ARCH_SMP_H | 2 | #define ASMARM_ARCH_SMP_H |
3 | 3 | ||
4 | |||
5 | #include <asm/hardware/gic.h> | 4 | #include <asm/hardware/gic.h> |
6 | 5 | #include <asm/smp_mpidr.h> | |
7 | #define hard_smp_processor_id() \ | ||
8 | ({ \ | ||
9 | unsigned int cpunum; \ | ||
10 | __asm__("mrc p15, 0, %0, c0, c0, 5" \ | ||
11 | : "=r" (cpunum)); \ | ||
12 | cpunum &= 0x0F; \ | ||
13 | }) | ||
14 | 6 | ||
15 | /* | 7 | /* |
16 | * We use IRQ1 as the IPI | 8 | * We use IRQ1 as the IPI |
diff --git a/arch/arm/mach-u300/include/mach/gpio.h b/arch/arm/mach-u300/include/mach/gpio.h index 7b1fc984abb6..d5a71abcbaea 100644 --- a/arch/arm/mach-u300/include/mach/gpio.h +++ b/arch/arm/mach-u300/include/mach/gpio.h | |||
@@ -273,6 +273,9 @@ extern void gpio_pullup(unsigned gpio, int value); | |||
273 | extern int gpio_get_value(unsigned gpio); | 273 | extern int gpio_get_value(unsigned gpio); |
274 | extern void gpio_set_value(unsigned gpio, int value); | 274 | extern void gpio_set_value(unsigned gpio, int value); |
275 | 275 | ||
276 | #define gpio_get_value_cansleep gpio_get_value | ||
277 | #define gpio_set_value_cansleep gpio_set_value | ||
278 | |||
276 | /* wrappers to sleep-enable the previous two functions */ | 279 | /* wrappers to sleep-enable the previous two functions */ |
277 | static inline unsigned gpio_to_irq(unsigned gpio) | 280 | static inline unsigned gpio_to_irq(unsigned gpio) |
278 | { | 281 | { |
diff --git a/arch/arm/mach-ux500/Kconfig b/arch/arm/mach-ux500/Kconfig index 6625e5bbf4d6..2dd44a0b4615 100644 --- a/arch/arm/mach-ux500/Kconfig +++ b/arch/arm/mach-ux500/Kconfig | |||
@@ -21,9 +21,7 @@ config MACH_U8500_MOP | |||
21 | bool "U8500 Development platform" | 21 | bool "U8500 Development platform" |
22 | select UX500_SOC_DB8500 | 22 | select UX500_SOC_DB8500 |
23 | help | 23 | help |
24 | Include support for mop500 development platform | 24 | Include support for the mop500 development platform. |
25 | based on U8500 architecture. The platform is based | ||
26 | on early drop silicon version of 8500. | ||
27 | 25 | ||
28 | config MACH_U5500 | 26 | config MACH_U5500 |
29 | bool "U5500 Development platform" | 27 | bool "U5500 Development platform" |
@@ -39,4 +37,18 @@ config UX500_DEBUG_UART | |||
39 | Choose the UART on which kernel low-level debug messages should be | 37 | Choose the UART on which kernel low-level debug messages should be |
40 | output. | 38 | output. |
41 | 39 | ||
40 | config U5500_MODEM_IRQ | ||
41 | bool "Modem IRQ support" | ||
42 | depends on MACH_U5500 | ||
43 | default y | ||
44 | help | ||
45 | Add support for handling IRQ:s from modem side | ||
46 | |||
47 | config U5500_MBOX | ||
48 | bool "Mailbox support" | ||
49 | depends on MACH_U5500 && U5500_MODEM_IRQ | ||
50 | default y | ||
51 | help | ||
52 | Add support for U5500 mailbox communication with modem side | ||
53 | |||
42 | endif | 54 | endif |
diff --git a/arch/arm/mach-ux500/Makefile b/arch/arm/mach-ux500/Makefile index 4556aea9c3c5..9e27a84433cb 100644 --- a/arch/arm/mach-ux500/Makefile +++ b/arch/arm/mach-ux500/Makefile | |||
@@ -4,8 +4,12 @@ | |||
4 | 4 | ||
5 | obj-y := clock.o cpu.o devices.o | 5 | obj-y := clock.o cpu.o devices.o |
6 | obj-$(CONFIG_UX500_SOC_DB5500) += cpu-db5500.o devices-db5500.o | 6 | obj-$(CONFIG_UX500_SOC_DB5500) += cpu-db5500.o devices-db5500.o |
7 | obj-$(CONFIG_UX500_SOC_DB8500) += cpu-db8500.o devices-db8500.o | 7 | obj-$(CONFIG_UX500_SOC_DB8500) += cpu-db8500.o devices-db8500.o prcmu.o |
8 | obj-$(CONFIG_MACH_U8500_MOP) += board-mop500.o | 8 | obj-$(CONFIG_MACH_U8500_MOP) += board-mop500.o board-mop500-sdi.o |
9 | obj-$(CONFIG_MACH_U5500) += board-u5500.o | 9 | obj-$(CONFIG_MACH_U5500) += board-u5500.o |
10 | obj-$(CONFIG_SMP) += platsmp.o headsmp.o | 10 | obj-$(CONFIG_SMP) += platsmp.o headsmp.o |
11 | obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o | ||
11 | obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o | 12 | obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o |
13 | obj-$(CONFIG_REGULATOR_AB8500) += board-mop500-regulators.o | ||
14 | obj-$(CONFIG_U5500_MODEM_IRQ) += modem_irq.o | ||
15 | obj-$(CONFIG_U5500_MBOX) += mbox.o | ||
diff --git a/arch/arm/mach-ux500/board-mop500-regulators.c b/arch/arm/mach-ux500/board-mop500-regulators.c new file mode 100644 index 000000000000..1187f1fc2e53 --- /dev/null +++ b/arch/arm/mach-ux500/board-mop500-regulators.c | |||
@@ -0,0 +1,101 @@ | |||
1 | /* | ||
2 | * Copyright (C) ST-Ericsson SA 2010 | ||
3 | * | ||
4 | * License Terms: GNU General Public License v2 | ||
5 | * | ||
6 | * Author: Sundar Iyer <sundar.iyer@stericsson.com> | ||
7 | * | ||
8 | * MOP500 board specific initialization for regulators | ||
9 | */ | ||
10 | #include <linux/kernel.h> | ||
11 | #include <linux/regulator/machine.h> | ||
12 | |||
13 | /* supplies to the display/camera */ | ||
14 | static struct regulator_init_data ab8500_vaux1_regulator = { | ||
15 | .constraints = { | ||
16 | .name = "V-DISPLAY", | ||
17 | .min_uV = 2500000, | ||
18 | .max_uV = 2900000, | ||
19 | .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE| | ||
20 | REGULATOR_CHANGE_STATUS, | ||
21 | }, | ||
22 | }; | ||
23 | |||
24 | /* supplies to the on-board eMMC */ | ||
25 | static struct regulator_init_data ab8500_vaux2_regulator = { | ||
26 | .constraints = { | ||
27 | .name = "V-eMMC1", | ||
28 | .min_uV = 1100000, | ||
29 | .max_uV = 3300000, | ||
30 | .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE| | ||
31 | REGULATOR_CHANGE_STATUS, | ||
32 | }, | ||
33 | }; | ||
34 | |||
35 | /* supply for VAUX3, supplies to SDcard slots */ | ||
36 | static struct regulator_init_data ab8500_vaux3_regulator = { | ||
37 | .constraints = { | ||
38 | .name = "V-MMC-SD", | ||
39 | .min_uV = 1100000, | ||
40 | .max_uV = 3300000, | ||
41 | .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE| | ||
42 | REGULATOR_CHANGE_STATUS, | ||
43 | }, | ||
44 | }; | ||
45 | |||
46 | /* supply for tvout, gpadc, TVOUT LDO */ | ||
47 | static struct regulator_init_data ab8500_vtvout_init = { | ||
48 | .constraints = { | ||
49 | .name = "V-TVOUT", | ||
50 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, | ||
51 | }, | ||
52 | }; | ||
53 | |||
54 | /* supply for ab8500-vaudio, VAUDIO LDO */ | ||
55 | static struct regulator_init_data ab8500_vaudio_init = { | ||
56 | .constraints = { | ||
57 | .name = "V-AUD", | ||
58 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, | ||
59 | }, | ||
60 | }; | ||
61 | |||
62 | /* supply for v-anamic1 VAMic1-LDO */ | ||
63 | static struct regulator_init_data ab8500_vamic1_init = { | ||
64 | .constraints = { | ||
65 | .name = "V-AMIC1", | ||
66 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, | ||
67 | }, | ||
68 | }; | ||
69 | |||
70 | /* supply for v-amic2, VAMIC2 LDO, reuse constants for AMIC1 */ | ||
71 | static struct regulator_init_data ab8500_vamic2_init = { | ||
72 | .constraints = { | ||
73 | .name = "V-AMIC2", | ||
74 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, | ||
75 | }, | ||
76 | }; | ||
77 | |||
78 | /* supply for v-dmic, VDMIC LDO */ | ||
79 | static struct regulator_init_data ab8500_vdmic_init = { | ||
80 | .constraints = { | ||
81 | .name = "V-DMIC", | ||
82 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, | ||
83 | }, | ||
84 | }; | ||
85 | |||
86 | /* supply for v-intcore12, VINTCORE12 LDO */ | ||
87 | static struct regulator_init_data ab8500_vintcore_init = { | ||
88 | .constraints = { | ||
89 | .name = "V-INTCORE", | ||
90 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, | ||
91 | }, | ||
92 | }; | ||
93 | |||
94 | /* supply for U8500 CSI/DSI, VANA LDO */ | ||
95 | static struct regulator_init_data ab8500_vana_init = { | ||
96 | .constraints = { | ||
97 | .name = "V-CSI/DSI", | ||
98 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, | ||
99 | }, | ||
100 | }; | ||
101 | |||
diff --git a/arch/arm/mach-ux500/board-mop500-sdi.c b/arch/arm/mach-ux500/board-mop500-sdi.c new file mode 100644 index 000000000000..bac995665b58 --- /dev/null +++ b/arch/arm/mach-ux500/board-mop500-sdi.c | |||
@@ -0,0 +1,91 @@ | |||
1 | /* | ||
2 | * Copyright (C) ST-Ericsson SA 2010 | ||
3 | * | ||
4 | * Author: Hanumath Prasad <hanumath.prasad@stericsson.com> | ||
5 | * License terms: GNU General Public License (GPL) version 2 | ||
6 | */ | ||
7 | |||
8 | #include <linux/kernel.h> | ||
9 | #include <linux/gpio.h> | ||
10 | #include <linux/amba/bus.h> | ||
11 | #include <linux/amba/mmci.h> | ||
12 | #include <linux/mmc/host.h> | ||
13 | #include <linux/platform_device.h> | ||
14 | |||
15 | #include <plat/pincfg.h> | ||
16 | #include <mach/devices.h> | ||
17 | #include <mach/hardware.h> | ||
18 | |||
19 | #include "pins-db8500.h" | ||
20 | #include "board-mop500.h" | ||
21 | |||
22 | static pin_cfg_t mop500_sdi_pins[] = { | ||
23 | /* SDI4 (on-board eMMC) */ | ||
24 | GPIO197_MC4_DAT3, | ||
25 | GPIO198_MC4_DAT2, | ||
26 | GPIO199_MC4_DAT1, | ||
27 | GPIO200_MC4_DAT0, | ||
28 | GPIO201_MC4_CMD, | ||
29 | GPIO202_MC4_FBCLK, | ||
30 | GPIO203_MC4_CLK, | ||
31 | GPIO204_MC4_DAT7, | ||
32 | GPIO205_MC4_DAT6, | ||
33 | GPIO206_MC4_DAT5, | ||
34 | GPIO207_MC4_DAT4, | ||
35 | }; | ||
36 | |||
37 | static pin_cfg_t mop500_sdi2_pins[] = { | ||
38 | /* SDI2 (POP eMMC) */ | ||
39 | GPIO128_MC2_CLK, | ||
40 | GPIO129_MC2_CMD, | ||
41 | GPIO130_MC2_FBCLK, | ||
42 | GPIO131_MC2_DAT0, | ||
43 | GPIO132_MC2_DAT1, | ||
44 | GPIO133_MC2_DAT2, | ||
45 | GPIO134_MC2_DAT3, | ||
46 | GPIO135_MC2_DAT4, | ||
47 | GPIO136_MC2_DAT5, | ||
48 | GPIO137_MC2_DAT6, | ||
49 | GPIO138_MC2_DAT7, | ||
50 | }; | ||
51 | |||
52 | /* | ||
53 | * SDI 2 (POP eMMC, not on DB8500ed) | ||
54 | */ | ||
55 | |||
56 | static struct mmci_platform_data mop500_sdi2_data = { | ||
57 | .ocr_mask = MMC_VDD_165_195, | ||
58 | .f_max = 100000000, | ||
59 | .capabilities = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA, | ||
60 | .gpio_cd = -1, | ||
61 | .gpio_wp = -1, | ||
62 | }; | ||
63 | |||
64 | /* | ||
65 | * SDI 4 (on-board eMMC) | ||
66 | */ | ||
67 | |||
68 | static struct mmci_platform_data mop500_sdi4_data = { | ||
69 | .ocr_mask = MMC_VDD_29_30, | ||
70 | .f_max = 100000000, | ||
71 | .capabilities = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA | | ||
72 | MMC_CAP_MMC_HIGHSPEED, | ||
73 | .gpio_cd = -1, | ||
74 | .gpio_wp = -1, | ||
75 | }; | ||
76 | |||
77 | void mop500_sdi_init(void) | ||
78 | { | ||
79 | nmk_config_pins(mop500_sdi_pins, ARRAY_SIZE(mop500_sdi_pins)); | ||
80 | |||
81 | u8500_sdi2_device.dev.platform_data = &mop500_sdi2_data; | ||
82 | u8500_sdi4_device.dev.platform_data = &mop500_sdi4_data; | ||
83 | |||
84 | if (!cpu_is_u8500ed()) { | ||
85 | nmk_config_pins(mop500_sdi2_pins, ARRAY_SIZE(mop500_sdi2_pins)); | ||
86 | amba_device_register(&u8500_sdi2_device, &iomem_resource); | ||
87 | } | ||
88 | |||
89 | /* On-board eMMC */ | ||
90 | amba_device_register(&u8500_sdi4_device, &iomem_resource); | ||
91 | } | ||
diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c index 0e8fd135a57d..642b8e60d119 100644 --- a/arch/arm/mach-ux500/board-mop500.c +++ b/arch/arm/mach-ux500/board-mop500.c | |||
@@ -28,8 +28,10 @@ | |||
28 | #include <mach/hardware.h> | 28 | #include <mach/hardware.h> |
29 | #include <mach/setup.h> | 29 | #include <mach/setup.h> |
30 | #include <mach/devices.h> | 30 | #include <mach/devices.h> |
31 | #include <mach/irqs.h> | ||
31 | 32 | ||
32 | #include "pins-db8500.h" | 33 | #include "pins-db8500.h" |
34 | #include "board-mop500.h" | ||
33 | 35 | ||
34 | static pin_cfg_t mop500_pins[] = { | 36 | static pin_cfg_t mop500_pins[] = { |
35 | /* SSP0 */ | 37 | /* SSP0 */ |
@@ -75,9 +77,27 @@ static struct ab8500_platform_data ab8500_platdata = { | |||
75 | .irq_base = MOP500_AB8500_IRQ_BASE, | 77 | .irq_base = MOP500_AB8500_IRQ_BASE, |
76 | }; | 78 | }; |
77 | 79 | ||
78 | static struct spi_board_info u8500_spi_devices[] = { | 80 | static struct resource ab8500_resources[] = { |
81 | [0] = { | ||
82 | .start = IRQ_AB8500, | ||
83 | .end = IRQ_AB8500, | ||
84 | .flags = IORESOURCE_IRQ | ||
85 | } | ||
86 | }; | ||
87 | |||
88 | struct platform_device ab8500_device = { | ||
89 | .name = "ab8500-i2c", | ||
90 | .id = 0, | ||
91 | .dev = { | ||
92 | .platform_data = &ab8500_platdata, | ||
93 | }, | ||
94 | .num_resources = 1, | ||
95 | .resource = ab8500_resources, | ||
96 | }; | ||
97 | |||
98 | static struct spi_board_info ab8500_spi_devices[] = { | ||
79 | { | 99 | { |
80 | .modalias = "ab8500", | 100 | .modalias = "ab8500-spi", |
81 | .controller_data = &ab4500_chip_info, | 101 | .controller_data = &ab4500_chip_info, |
82 | .platform_data = &ab8500_platdata, | 102 | .platform_data = &ab8500_platdata, |
83 | .max_speed_hz = 12000000, | 103 | .max_speed_hz = 12000000, |
@@ -163,8 +183,14 @@ static void __init u8500_init_machine(void) | |||
163 | 183 | ||
164 | platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs)); | 184 | platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs)); |
165 | 185 | ||
166 | spi_register_board_info(u8500_spi_devices, | 186 | mop500_sdi_init(); |
167 | ARRAY_SIZE(u8500_spi_devices)); | 187 | |
188 | /* If HW is early drop (ED) or V1.0 then use SPI to access AB8500 */ | ||
189 | if (cpu_is_u8500ed() || cpu_is_u8500v10()) | ||
190 | spi_register_board_info(ab8500_spi_devices, | ||
191 | ARRAY_SIZE(ab8500_spi_devices)); | ||
192 | else /* If HW is v.1.1 or later use I2C to access AB8500 */ | ||
193 | platform_device_register(&ab8500_device); | ||
168 | } | 194 | } |
169 | 195 | ||
170 | MACHINE_START(U8500, "ST-Ericsson MOP500 platform") | 196 | MACHINE_START(U8500, "ST-Ericsson MOP500 platform") |
diff --git a/arch/arm/mach-ux500/board-mop500.h b/arch/arm/mach-ux500/board-mop500.h new file mode 100644 index 000000000000..2d240322fa6f --- /dev/null +++ b/arch/arm/mach-ux500/board-mop500.h | |||
@@ -0,0 +1,12 @@ | |||
1 | /* | ||
2 | * Copyright (C) ST-Ericsson SA 2010 | ||
3 | * | ||
4 | * License terms: GNU General Public License (GPL) version 2 | ||
5 | */ | ||
6 | |||
7 | #ifndef __BOARD_MOP500_H | ||
8 | #define __BOARD_MOP500_H | ||
9 | |||
10 | extern void mop500_sdi_init(void); | ||
11 | |||
12 | #endif | ||
diff --git a/arch/arm/mach-ux500/cpu-db5500.c b/arch/arm/mach-ux500/cpu-db5500.c index e9278f6d67aa..2f87075e9d6f 100644 --- a/arch/arm/mach-ux500/cpu-db5500.c +++ b/arch/arm/mach-ux500/cpu-db5500.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <mach/hardware.h> | 14 | #include <mach/hardware.h> |
15 | #include <mach/devices.h> | 15 | #include <mach/devices.h> |
16 | #include <mach/setup.h> | 16 | #include <mach/setup.h> |
17 | #include <mach/irqs.h> | ||
17 | 18 | ||
18 | static struct map_desc u5500_io_desc[] __initdata = { | 19 | static struct map_desc u5500_io_desc[] __initdata = { |
19 | __IO_DEV_DESC(U5500_GPIO0_BASE, SZ_4K), | 20 | __IO_DEV_DESC(U5500_GPIO0_BASE, SZ_4K), |
@@ -24,6 +25,90 @@ static struct map_desc u5500_io_desc[] __initdata = { | |||
24 | __IO_DEV_DESC(U5500_PRCMU_BASE, SZ_4K), | 25 | __IO_DEV_DESC(U5500_PRCMU_BASE, SZ_4K), |
25 | }; | 26 | }; |
26 | 27 | ||
28 | static struct resource mbox0_resources[] = { | ||
29 | { | ||
30 | .name = "mbox_peer", | ||
31 | .start = U5500_MBOX0_PEER_START, | ||
32 | .end = U5500_MBOX0_PEER_END, | ||
33 | .flags = IORESOURCE_MEM, | ||
34 | }, | ||
35 | { | ||
36 | .name = "mbox_local", | ||
37 | .start = U5500_MBOX0_LOCAL_START, | ||
38 | .end = U5500_MBOX0_LOCAL_END, | ||
39 | .flags = IORESOURCE_MEM, | ||
40 | }, | ||
41 | { | ||
42 | .name = "mbox_irq", | ||
43 | .start = MBOX_PAIR0_VIRT_IRQ, | ||
44 | .end = MBOX_PAIR0_VIRT_IRQ, | ||
45 | .flags = IORESOURCE_IRQ, | ||
46 | } | ||
47 | }; | ||
48 | |||
49 | static struct resource mbox1_resources[] = { | ||
50 | { | ||
51 | .name = "mbox_peer", | ||
52 | .start = U5500_MBOX1_PEER_START, | ||
53 | .end = U5500_MBOX1_PEER_END, | ||
54 | .flags = IORESOURCE_MEM, | ||
55 | }, | ||
56 | { | ||
57 | .name = "mbox_local", | ||
58 | .start = U5500_MBOX1_LOCAL_START, | ||
59 | .end = U5500_MBOX1_LOCAL_END, | ||
60 | .flags = IORESOURCE_MEM, | ||
61 | }, | ||
62 | { | ||
63 | .name = "mbox_irq", | ||
64 | .start = MBOX_PAIR1_VIRT_IRQ, | ||
65 | .end = MBOX_PAIR1_VIRT_IRQ, | ||
66 | .flags = IORESOURCE_IRQ, | ||
67 | } | ||
68 | }; | ||
69 | |||
70 | static struct resource mbox2_resources[] = { | ||
71 | { | ||
72 | .name = "mbox_peer", | ||
73 | .start = U5500_MBOX2_PEER_START, | ||
74 | .end = U5500_MBOX2_PEER_END, | ||
75 | .flags = IORESOURCE_MEM, | ||
76 | }, | ||
77 | { | ||
78 | .name = "mbox_local", | ||
79 | .start = U5500_MBOX2_LOCAL_START, | ||
80 | .end = U5500_MBOX2_LOCAL_END, | ||
81 | .flags = IORESOURCE_MEM, | ||
82 | }, | ||
83 | { | ||
84 | .name = "mbox_irq", | ||
85 | .start = MBOX_PAIR2_VIRT_IRQ, | ||
86 | .end = MBOX_PAIR2_VIRT_IRQ, | ||
87 | .flags = IORESOURCE_IRQ, | ||
88 | } | ||
89 | }; | ||
90 | |||
91 | static struct platform_device mbox0_device = { | ||
92 | .id = 0, | ||
93 | .name = "mbox", | ||
94 | .resource = mbox0_resources, | ||
95 | .num_resources = ARRAY_SIZE(mbox0_resources), | ||
96 | }; | ||
97 | |||
98 | static struct platform_device mbox1_device = { | ||
99 | .id = 1, | ||
100 | .name = "mbox", | ||
101 | .resource = mbox1_resources, | ||
102 | .num_resources = ARRAY_SIZE(mbox1_resources), | ||
103 | }; | ||
104 | |||
105 | static struct platform_device mbox2_device = { | ||
106 | .id = 2, | ||
107 | .name = "mbox", | ||
108 | .resource = mbox2_resources, | ||
109 | .num_resources = ARRAY_SIZE(mbox2_resources), | ||
110 | }; | ||
111 | |||
27 | static struct platform_device *u5500_platform_devs[] __initdata = { | 112 | static struct platform_device *u5500_platform_devs[] __initdata = { |
28 | &u5500_gpio_devs[0], | 113 | &u5500_gpio_devs[0], |
29 | &u5500_gpio_devs[1], | 114 | &u5500_gpio_devs[1], |
@@ -33,6 +118,9 @@ static struct platform_device *u5500_platform_devs[] __initdata = { | |||
33 | &u5500_gpio_devs[5], | 118 | &u5500_gpio_devs[5], |
34 | &u5500_gpio_devs[6], | 119 | &u5500_gpio_devs[6], |
35 | &u5500_gpio_devs[7], | 120 | &u5500_gpio_devs[7], |
121 | &mbox0_device, | ||
122 | &mbox1_device, | ||
123 | &mbox2_device, | ||
36 | }; | 124 | }; |
37 | 125 | ||
38 | void __init u5500_map_io(void) | 126 | void __init u5500_map_io(void) |
diff --git a/arch/arm/mach-ux500/cpu-db8500.c b/arch/arm/mach-ux500/cpu-db8500.c index f21c444edd99..4acab7544b3c 100644 --- a/arch/arm/mach-ux500/cpu-db8500.c +++ b/arch/arm/mach-ux500/cpu-db8500.c | |||
@@ -38,10 +38,12 @@ static struct platform_device *platform_devs[] __initdata = { | |||
38 | /* minimum static i/o mapping required to boot U8500 platforms */ | 38 | /* minimum static i/o mapping required to boot U8500 platforms */ |
39 | static struct map_desc u8500_io_desc[] __initdata = { | 39 | static struct map_desc u8500_io_desc[] __initdata = { |
40 | __IO_DEV_DESC(U8500_PRCMU_BASE, SZ_4K), | 40 | __IO_DEV_DESC(U8500_PRCMU_BASE, SZ_4K), |
41 | __IO_DEV_DESC(U8500_PRCMU_TCDM_BASE, SZ_4K), | ||
41 | __IO_DEV_DESC(U8500_GPIO0_BASE, SZ_4K), | 42 | __IO_DEV_DESC(U8500_GPIO0_BASE, SZ_4K), |
42 | __IO_DEV_DESC(U8500_GPIO1_BASE, SZ_4K), | 43 | __IO_DEV_DESC(U8500_GPIO1_BASE, SZ_4K), |
43 | __IO_DEV_DESC(U8500_GPIO2_BASE, SZ_4K), | 44 | __IO_DEV_DESC(U8500_GPIO2_BASE, SZ_4K), |
44 | __IO_DEV_DESC(U8500_GPIO3_BASE, SZ_4K), | 45 | __IO_DEV_DESC(U8500_GPIO3_BASE, SZ_4K), |
46 | __MEM_DEV_DESC(U8500_BOOT_ROM_BASE, SZ_1M), | ||
45 | }; | 47 | }; |
46 | 48 | ||
47 | static struct map_desc u8500ed_io_desc[] __initdata = { | 49 | static struct map_desc u8500ed_io_desc[] __initdata = { |
@@ -53,6 +55,69 @@ static struct map_desc u8500v1_io_desc[] __initdata = { | |||
53 | __IO_DEV_DESC(U8500_MTU0_BASE, SZ_4K), | 55 | __IO_DEV_DESC(U8500_MTU0_BASE, SZ_4K), |
54 | }; | 56 | }; |
55 | 57 | ||
58 | /* | ||
59 | * Functions to differentiate between later ASICs | ||
60 | * We look into the end of the ROM to locate the hardcoded ASIC ID. | ||
61 | * This is only needed to differentiate between minor revisions and | ||
62 | * process variants of an ASIC, the major revisions are encoded in | ||
63 | * the cpuid. | ||
64 | */ | ||
65 | #define U8500_ASIC_ID_LOC_ED_V1 (U8500_BOOT_ROM_BASE + 0x1FFF4) | ||
66 | #define U8500_ASIC_ID_LOC_V2 (U8500_BOOT_ROM_BASE + 0x1DBF4) | ||
67 | #define U8500_ASIC_REV_ED 0x01 | ||
68 | #define U8500_ASIC_REV_V10 0xA0 | ||
69 | #define U8500_ASIC_REV_V11 0xA1 | ||
70 | #define U8500_ASIC_REV_V20 0xB0 | ||
71 | |||
72 | /** | ||
73 | * struct db8500_asic_id - fields of the ASIC ID | ||
74 | * @process: the manufacturing process, 0x40 is 40 nm | ||
75 | * 0x00 is "standard" | ||
76 | * @partnumber: hithereto 0x8500 for DB8500 | ||
77 | * @revision: version code in the series | ||
78 | * This field definion is not formally defined but makes | ||
79 | * sense. | ||
80 | */ | ||
81 | struct db8500_asic_id { | ||
82 | u8 process; | ||
83 | u16 partnumber; | ||
84 | u8 revision; | ||
85 | }; | ||
86 | |||
87 | /* This isn't going to change at runtime */ | ||
88 | static struct db8500_asic_id db8500_id; | ||
89 | |||
90 | static void __init get_db8500_asic_id(void) | ||
91 | { | ||
92 | u32 asicid; | ||
93 | |||
94 | if (cpu_is_u8500v1() || cpu_is_u8500ed()) | ||
95 | asicid = readl(__io_address(U8500_ASIC_ID_LOC_ED_V1)); | ||
96 | else if (cpu_is_u8500v2()) | ||
97 | asicid = readl(__io_address(U8500_ASIC_ID_LOC_V2)); | ||
98 | else | ||
99 | BUG(); | ||
100 | |||
101 | db8500_id.process = (asicid >> 24); | ||
102 | db8500_id.partnumber = (asicid >> 16) & 0xFFFFU; | ||
103 | db8500_id.revision = asicid & 0xFFU; | ||
104 | } | ||
105 | |||
106 | bool cpu_is_u8500v10(void) | ||
107 | { | ||
108 | return (db8500_id.revision == U8500_ASIC_REV_V10); | ||
109 | } | ||
110 | |||
111 | bool cpu_is_u8500v11(void) | ||
112 | { | ||
113 | return (db8500_id.revision == U8500_ASIC_REV_V11); | ||
114 | } | ||
115 | |||
116 | bool cpu_is_u8500v20(void) | ||
117 | { | ||
118 | return (db8500_id.revision == U8500_ASIC_REV_V20); | ||
119 | } | ||
120 | |||
56 | void __init u8500_map_io(void) | 121 | void __init u8500_map_io(void) |
57 | { | 122 | { |
58 | ux500_map_io(); | 123 | ux500_map_io(); |
@@ -63,6 +128,9 @@ void __init u8500_map_io(void) | |||
63 | iotable_init(u8500ed_io_desc, ARRAY_SIZE(u8500ed_io_desc)); | 128 | iotable_init(u8500ed_io_desc, ARRAY_SIZE(u8500ed_io_desc)); |
64 | else | 129 | else |
65 | iotable_init(u8500v1_io_desc, ARRAY_SIZE(u8500v1_io_desc)); | 130 | iotable_init(u8500v1_io_desc, ARRAY_SIZE(u8500v1_io_desc)); |
131 | |||
132 | /* Read out the ASIC ID as early as we can */ | ||
133 | get_db8500_asic_id(); | ||
66 | } | 134 | } |
67 | 135 | ||
68 | /* | 136 | /* |
@@ -70,6 +138,20 @@ void __init u8500_map_io(void) | |||
70 | */ | 138 | */ |
71 | void __init u8500_init_devices(void) | 139 | void __init u8500_init_devices(void) |
72 | { | 140 | { |
141 | /* Display some ASIC boilerplate */ | ||
142 | pr_info("DB8500: process: %02x, revision ID: 0x%02x\n", | ||
143 | db8500_id.process, db8500_id.revision); | ||
144 | if (cpu_is_u8500ed()) | ||
145 | pr_info("DB8500: Early Drop (ED)\n"); | ||
146 | else if (cpu_is_u8500v10()) | ||
147 | pr_info("DB8500: version 1.0\n"); | ||
148 | else if (cpu_is_u8500v11()) | ||
149 | pr_info("DB8500: version 1.1\n"); | ||
150 | else if (cpu_is_u8500v20()) | ||
151 | pr_info("DB8500: version 2.0\n"); | ||
152 | else | ||
153 | pr_warning("ASIC: UNKNOWN SILICON VERSION!\n"); | ||
154 | |||
73 | ux500_init_devices(); | 155 | ux500_init_devices(); |
74 | 156 | ||
75 | if (cpu_is_u8500ed()) | 157 | if (cpu_is_u8500ed()) |
diff --git a/arch/arm/mach-ux500/devices-db8500.c b/arch/arm/mach-ux500/devices-db8500.c index 9280d2561111..40032fecbc16 100644 --- a/arch/arm/mach-ux500/devices-db8500.c +++ b/arch/arm/mach-ux500/devices-db8500.c | |||
@@ -110,6 +110,82 @@ struct platform_device u8500_i2c4_device = { | |||
110 | .num_resources = ARRAY_SIZE(u8500_i2c4_resources), | 110 | .num_resources = ARRAY_SIZE(u8500_i2c4_resources), |
111 | }; | 111 | }; |
112 | 112 | ||
113 | /* | ||
114 | * SD/MMC | ||
115 | */ | ||
116 | |||
117 | struct amba_device u8500_sdi0_device = { | ||
118 | .dev = { | ||
119 | .init_name = "sdi0", | ||
120 | }, | ||
121 | .res = { | ||
122 | .start = U8500_SDI0_BASE, | ||
123 | .end = U8500_SDI0_BASE + SZ_4K - 1, | ||
124 | .flags = IORESOURCE_MEM, | ||
125 | }, | ||
126 | .irq = {IRQ_DB8500_SDMMC0, NO_IRQ}, | ||
127 | }; | ||
128 | |||
129 | struct amba_device u8500_sdi1_device = { | ||
130 | .dev = { | ||
131 | .init_name = "sdi1", | ||
132 | }, | ||
133 | .res = { | ||
134 | .start = U8500_SDI1_BASE, | ||
135 | .end = U8500_SDI1_BASE + SZ_4K - 1, | ||
136 | .flags = IORESOURCE_MEM, | ||
137 | }, | ||
138 | .irq = {IRQ_DB8500_SDMMC1, NO_IRQ}, | ||
139 | }; | ||
140 | |||
141 | struct amba_device u8500_sdi2_device = { | ||
142 | .dev = { | ||
143 | .init_name = "sdi2", | ||
144 | }, | ||
145 | .res = { | ||
146 | .start = U8500_SDI2_BASE, | ||
147 | .end = U8500_SDI2_BASE + SZ_4K - 1, | ||
148 | .flags = IORESOURCE_MEM, | ||
149 | }, | ||
150 | .irq = {IRQ_DB8500_SDMMC2, NO_IRQ}, | ||
151 | }; | ||
152 | |||
153 | struct amba_device u8500_sdi3_device = { | ||
154 | .dev = { | ||
155 | .init_name = "sdi3", | ||
156 | }, | ||
157 | .res = { | ||
158 | .start = U8500_SDI3_BASE, | ||
159 | .end = U8500_SDI3_BASE + SZ_4K - 1, | ||
160 | .flags = IORESOURCE_MEM, | ||
161 | }, | ||
162 | .irq = {IRQ_DB8500_SDMMC3, NO_IRQ}, | ||
163 | }; | ||
164 | |||
165 | struct amba_device u8500_sdi4_device = { | ||
166 | .dev = { | ||
167 | .init_name = "sdi4", | ||
168 | }, | ||
169 | .res = { | ||
170 | .start = U8500_SDI4_BASE, | ||
171 | .end = U8500_SDI4_BASE + SZ_4K - 1, | ||
172 | .flags = IORESOURCE_MEM, | ||
173 | }, | ||
174 | .irq = {IRQ_DB8500_SDMMC4, NO_IRQ}, | ||
175 | }; | ||
176 | |||
177 | struct amba_device u8500_sdi5_device = { | ||
178 | .dev = { | ||
179 | .init_name = "sdi5", | ||
180 | }, | ||
181 | .res = { | ||
182 | .start = U8500_SDI5_BASE, | ||
183 | .end = U8500_SDI5_BASE + SZ_4K - 1, | ||
184 | .flags = IORESOURCE_MEM, | ||
185 | }, | ||
186 | .irq = {IRQ_DB8500_SDMMC5, NO_IRQ}, | ||
187 | }; | ||
188 | |||
113 | static struct resource dma40_resources[] = { | 189 | static struct resource dma40_resources[] = { |
114 | [0] = { | 190 | [0] = { |
115 | .start = U8500_DMA_BASE, | 191 | .start = U8500_DMA_BASE, |
@@ -170,23 +246,23 @@ struct stedma40_chan_cfg dma40_memcpy_conf_log = { | |||
170 | * Mapping between destination event lines and physical device address. | 246 | * Mapping between destination event lines and physical device address. |
171 | * The event line is tied to a device and therefor the address is constant. | 247 | * The event line is tied to a device and therefor the address is constant. |
172 | */ | 248 | */ |
173 | static const dma_addr_t dma40_tx_map[STEDMA40_NR_DEV]; | 249 | static const dma_addr_t dma40_tx_map[DB8500_DMA_NR_DEV]; |
174 | 250 | ||
175 | /* Mapping between source event lines and physical device address */ | 251 | /* Mapping between source event lines and physical device address */ |
176 | static const dma_addr_t dma40_rx_map[STEDMA40_NR_DEV]; | 252 | static const dma_addr_t dma40_rx_map[DB8500_DMA_NR_DEV]; |
177 | 253 | ||
178 | /* Reserved event lines for memcpy only */ | 254 | /* Reserved event lines for memcpy only */ |
179 | static int dma40_memcpy_event[] = { | 255 | static int dma40_memcpy_event[] = { |
180 | STEDMA40_MEMCPY_TX_0, | 256 | DB8500_DMA_MEMCPY_TX_0, |
181 | STEDMA40_MEMCPY_TX_1, | 257 | DB8500_DMA_MEMCPY_TX_1, |
182 | STEDMA40_MEMCPY_TX_2, | 258 | DB8500_DMA_MEMCPY_TX_2, |
183 | STEDMA40_MEMCPY_TX_3, | 259 | DB8500_DMA_MEMCPY_TX_3, |
184 | STEDMA40_MEMCPY_TX_4, | 260 | DB8500_DMA_MEMCPY_TX_4, |
185 | STEDMA40_MEMCPY_TX_5, | 261 | DB8500_DMA_MEMCPY_TX_5, |
186 | }; | 262 | }; |
187 | 263 | ||
188 | static struct stedma40_platform_data dma40_plat_data = { | 264 | static struct stedma40_platform_data dma40_plat_data = { |
189 | .dev_len = STEDMA40_NR_DEV, | 265 | .dev_len = DB8500_DMA_NR_DEV, |
190 | .dev_rx = dma40_rx_map, | 266 | .dev_rx = dma40_rx_map, |
191 | .dev_tx = dma40_tx_map, | 267 | .dev_tx = dma40_tx_map, |
192 | .memcpy = dma40_memcpy_event, | 268 | .memcpy = dma40_memcpy_event, |
diff --git a/arch/arm/mach-ux500/hotplug.c b/arch/arm/mach-ux500/hotplug.c new file mode 100644 index 000000000000..b782a03024be --- /dev/null +++ b/arch/arm/mach-ux500/hotplug.c | |||
@@ -0,0 +1,75 @@ | |||
1 | /* | ||
2 | * Copyright (C) STMicroelectronics 2009 | ||
3 | * Copyright (C) ST-Ericsson SA 2010 | ||
4 | * | ||
5 | * License Terms: GNU General Public License v2 | ||
6 | * Based on ARM realview platform | ||
7 | * | ||
8 | * Author: Sundar Iyer <sundar.iyer@stericsson.com> | ||
9 | * | ||
10 | */ | ||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/errno.h> | ||
13 | #include <linux/smp.h> | ||
14 | #include <linux/completion.h> | ||
15 | |||
16 | #include <asm/cacheflush.h> | ||
17 | |||
18 | extern volatile int pen_release; | ||
19 | |||
20 | static DECLARE_COMPLETION(cpu_killed); | ||
21 | |||
22 | static inline void platform_do_lowpower(unsigned int cpu) | ||
23 | { | ||
24 | flush_cache_all(); | ||
25 | |||
26 | /* we put the platform to just WFI */ | ||
27 | for (;;) { | ||
28 | __asm__ __volatile__("dsb\n\t" "wfi\n\t" | ||
29 | : : : "memory"); | ||
30 | if (pen_release == cpu) { | ||
31 | /* | ||
32 | * OK, proper wakeup, we're done | ||
33 | */ | ||
34 | break; | ||
35 | } | ||
36 | } | ||
37 | } | ||
38 | |||
39 | int platform_cpu_kill(unsigned int cpu) | ||
40 | { | ||
41 | return wait_for_completion_timeout(&cpu_killed, 5000); | ||
42 | } | ||
43 | |||
44 | /* | ||
45 | * platform-specific code to shutdown a CPU | ||
46 | * | ||
47 | * Called with IRQs disabled | ||
48 | */ | ||
49 | void platform_cpu_die(unsigned int cpu) | ||
50 | { | ||
51 | #ifdef DEBUG | ||
52 | unsigned int this_cpu = hard_smp_processor_id(); | ||
53 | |||
54 | if (cpu != this_cpu) { | ||
55 | printk(KERN_CRIT "Eek! platform_cpu_die running on %u, should be %u\n", | ||
56 | this_cpu, cpu); | ||
57 | BUG(); | ||
58 | } | ||
59 | #endif | ||
60 | |||
61 | printk(KERN_NOTICE "CPU%u: shutdown\n", cpu); | ||
62 | complete(&cpu_killed); | ||
63 | |||
64 | /* directly enter low power state, skipping secure registers */ | ||
65 | platform_do_lowpower(cpu); | ||
66 | } | ||
67 | |||
68 | int platform_cpu_disable(unsigned int cpu) | ||
69 | { | ||
70 | /* | ||
71 | * we don't allow CPU 0 to be shutdown (it is still too special | ||
72 | * e.g. clock tick interrupts) | ||
73 | */ | ||
74 | return cpu == 0 ? -EPERM : 0; | ||
75 | } | ||
diff --git a/arch/arm/mach-ux500/include/mach/db5500-regs.h b/arch/arm/mach-ux500/include/mach/db5500-regs.h index 545c80fc8024..3eafc0e24ba5 100644 --- a/arch/arm/mach-ux500/include/mach/db5500-regs.h +++ b/arch/arm/mach-ux500/include/mach/db5500-regs.h | |||
@@ -100,4 +100,18 @@ | |||
100 | #define U5500_GPIOBANK6_BASE (U5500_GPIO4_BASE + 0x80) | 100 | #define U5500_GPIOBANK6_BASE (U5500_GPIO4_BASE + 0x80) |
101 | #define U5500_GPIOBANK7_BASE (U5500_GPIO4_BASE + 0x100) | 101 | #define U5500_GPIOBANK7_BASE (U5500_GPIO4_BASE + 0x100) |
102 | 102 | ||
103 | #define U5500_MBOX_BASE (U5500_MODEM_BASE + 0xFFD1000) | ||
104 | #define U5500_MBOX0_PEER_START (U5500_MBOX_BASE + 0x40) | ||
105 | #define U5500_MBOX0_PEER_END (U5500_MBOX_BASE + 0x5F) | ||
106 | #define U5500_MBOX0_LOCAL_START (U5500_MBOX_BASE + 0x60) | ||
107 | #define U5500_MBOX0_LOCAL_END (U5500_MBOX_BASE + 0x7F) | ||
108 | #define U5500_MBOX1_PEER_START (U5500_MBOX_BASE + 0x80) | ||
109 | #define U5500_MBOX1_PEER_END (U5500_MBOX_BASE + 0x9F) | ||
110 | #define U5500_MBOX1_LOCAL_START (U5500_MBOX_BASE + 0xA0) | ||
111 | #define U5500_MBOX1_LOCAL_END (U5500_MBOX_BASE + 0xBF) | ||
112 | #define U5500_MBOX2_PEER_START (U5500_MBOX_BASE + 0x00) | ||
113 | #define U5500_MBOX2_PEER_END (U5500_MBOX_BASE + 0x1F) | ||
114 | #define U5500_MBOX2_LOCAL_START (U5500_MBOX_BASE + 0x20) | ||
115 | #define U5500_MBOX2_LOCAL_END (U5500_MBOX_BASE + 0x3F) | ||
116 | |||
103 | #endif | 117 | #endif |
diff --git a/arch/arm/mach-ux500/include/mach/db8500-regs.h b/arch/arm/mach-ux500/include/mach/db8500-regs.h index f000218210c9..f07d0986409d 100644 --- a/arch/arm/mach-ux500/include/mach/db8500-regs.h +++ b/arch/arm/mach-ux500/include/mach/db8500-regs.h | |||
@@ -30,8 +30,6 @@ | |||
30 | #define U8500_ICN_BASE 0x81000000 | 30 | #define U8500_ICN_BASE 0x81000000 |
31 | 31 | ||
32 | #define U8500_BOOT_ROM_BASE 0x90000000 | 32 | #define U8500_BOOT_ROM_BASE 0x90000000 |
33 | /* ASIC ID is at 0xff4 offset within this region */ | ||
34 | #define U8500_ASIC_ID_BASE 0x9001F000 | ||
35 | 33 | ||
36 | #define U8500_PER6_BASE 0xa03c0000 | 34 | #define U8500_PER6_BASE 0xa03c0000 |
37 | #define U8500_PER5_BASE 0xa03e0000 | 35 | #define U8500_PER5_BASE 0xa03e0000 |
diff --git a/arch/arm/mach-ux500/include/mach/devices.h b/arch/arm/mach-ux500/include/mach/devices.h index c2b2f2574947..33a120c2e82e 100644 --- a/arch/arm/mach-ux500/include/mach/devices.h +++ b/arch/arm/mach-ux500/include/mach/devices.h | |||
@@ -27,6 +27,13 @@ extern struct platform_device u8500_i2c0_device; | |||
27 | extern struct platform_device u8500_i2c4_device; | 27 | extern struct platform_device u8500_i2c4_device; |
28 | extern struct platform_device u8500_dma40_device; | 28 | extern struct platform_device u8500_dma40_device; |
29 | 29 | ||
30 | extern struct amba_device u8500_sdi0_device; | ||
31 | extern struct amba_device u8500_sdi1_device; | ||
32 | extern struct amba_device u8500_sdi2_device; | ||
33 | extern struct amba_device u8500_sdi3_device; | ||
34 | extern struct amba_device u8500_sdi4_device; | ||
35 | extern struct amba_device u8500_sdi5_device; | ||
36 | |||
30 | void dma40_u8500ed_fixup(void); | 37 | void dma40_u8500ed_fixup(void); |
31 | 38 | ||
32 | #endif | 39 | #endif |
diff --git a/arch/arm/mach-ux500/include/mach/hardware.h b/arch/arm/mach-ux500/include/mach/hardware.h index 8656379a8309..32e883a8f2a2 100644 --- a/arch/arm/mach-ux500/include/mach/hardware.h +++ b/arch/arm/mach-ux500/include/mach/hardware.h | |||
@@ -104,16 +104,35 @@ static inline bool cpu_is_u8500(void) | |||
104 | #endif | 104 | #endif |
105 | } | 105 | } |
106 | 106 | ||
107 | #define CPUID_DB8500ED 0x410fc090 | ||
108 | #define CPUID_DB8500V1 0x411fc091 | ||
109 | #define CPUID_DB8500V2 0x412fc091 | ||
110 | |||
107 | static inline bool cpu_is_u8500ed(void) | 111 | static inline bool cpu_is_u8500ed(void) |
108 | { | 112 | { |
109 | return cpu_is_u8500() && (read_cpuid_id() & 15) == 0; | 113 | return cpu_is_u8500() && (read_cpuid_id() == CPUID_DB8500ED); |
110 | } | 114 | } |
111 | 115 | ||
112 | static inline bool cpu_is_u8500v1(void) | 116 | static inline bool cpu_is_u8500v1(void) |
113 | { | 117 | { |
114 | return cpu_is_u8500() && (read_cpuid_id() & 15) == 1; | 118 | return cpu_is_u8500() && (read_cpuid_id() == CPUID_DB8500V1); |
119 | } | ||
120 | |||
121 | static inline bool cpu_is_u8500v2(void) | ||
122 | { | ||
123 | return cpu_is_u8500() && (read_cpuid_id() == CPUID_DB8500V2); | ||
115 | } | 124 | } |
116 | 125 | ||
126 | #ifdef CONFIG_UX500_SOC_DB8500 | ||
127 | bool cpu_is_u8500v10(void); | ||
128 | bool cpu_is_u8500v11(void); | ||
129 | bool cpu_is_u8500v20(void); | ||
130 | #else | ||
131 | static inline bool cpu_is_u8500v10(void) { return false; } | ||
132 | static inline bool cpu_is_u8500v11(void) { return false; } | ||
133 | static inline bool cpu_is_u8500v20(void) { return false; } | ||
134 | #endif | ||
135 | |||
117 | static inline bool cpu_is_u5500(void) | 136 | static inline bool cpu_is_u5500(void) |
118 | { | 137 | { |
119 | #ifdef CONFIG_UX500_SOC_DB5500 | 138 | #ifdef CONFIG_UX500_SOC_DB5500 |
diff --git a/arch/arm/mach-ux500/include/mach/irqs-db5500.h b/arch/arm/mach-ux500/include/mach/irqs-db5500.h index 6fbfe5e2065a..bfa123dbec3b 100644 --- a/arch/arm/mach-ux500/include/mach/irqs-db5500.h +++ b/arch/arm/mach-ux500/include/mach/irqs-db5500.h | |||
@@ -61,6 +61,7 @@ | |||
61 | #define IRQ_DB5500_SDMMC0 (IRQ_SHPI_START + 60) | 61 | #define IRQ_DB5500_SDMMC0 (IRQ_SHPI_START + 60) |
62 | #define IRQ_DB5500_HSEM (IRQ_SHPI_START + 61) | 62 | #define IRQ_DB5500_HSEM (IRQ_SHPI_START + 61) |
63 | #define IRQ_DB5500_SBAG (IRQ_SHPI_START + 63) | 63 | #define IRQ_DB5500_SBAG (IRQ_SHPI_START + 63) |
64 | #define IRQ_DB5500_MODEM (IRQ_SHPI_START + 65) | ||
64 | #define IRQ_DB5500_SPI1 (IRQ_SHPI_START + 96) | 65 | #define IRQ_DB5500_SPI1 (IRQ_SHPI_START + 96) |
65 | #define IRQ_DB5500_MSP2 (IRQ_SHPI_START + 98) | 66 | #define IRQ_DB5500_MSP2 (IRQ_SHPI_START + 98) |
66 | #define IRQ_DB5500_SRPTIMER (IRQ_SHPI_START + 101) | 67 | #define IRQ_DB5500_SRPTIMER (IRQ_SHPI_START + 101) |
diff --git a/arch/arm/mach-ux500/include/mach/irqs.h b/arch/arm/mach-ux500/include/mach/irqs.h index 10385bdc2b77..693aa57de88d 100644 --- a/arch/arm/mach-ux500/include/mach/irqs.h +++ b/arch/arm/mach-ux500/include/mach/irqs.h | |||
@@ -40,7 +40,8 @@ | |||
40 | #define IRQ_HSIR_CH1_OVRRUN (IRQ_SHPI_START + 33) | 40 | #define IRQ_HSIR_CH1_OVRRUN (IRQ_SHPI_START + 33) |
41 | #define IRQ_HSIR_CH2_OVRRUN (IRQ_SHPI_START + 34) | 41 | #define IRQ_HSIR_CH2_OVRRUN (IRQ_SHPI_START + 34) |
42 | #define IRQ_HSIR_CH3_OVRRUN (IRQ_SHPI_START + 35) | 42 | #define IRQ_HSIR_CH3_OVRRUN (IRQ_SHPI_START + 35) |
43 | #define IRQ_AB4500 (IRQ_SHPI_START + 40) | 43 | #define IRQ_AB8500 (IRQ_SHPI_START + 40) |
44 | #define IRQ_PRCMU (IRQ_SHPI_START + 47) | ||
44 | #define IRQ_DISP (IRQ_SHPI_START + 48) | 45 | #define IRQ_DISP (IRQ_SHPI_START + 48) |
45 | #define IRQ_SiPI3 (IRQ_SHPI_START + 49) | 46 | #define IRQ_SiPI3 (IRQ_SHPI_START + 49) |
46 | #define IRQ_I2C4 (IRQ_SHPI_START + 51) | 47 | #define IRQ_I2C4 (IRQ_SHPI_START + 51) |
@@ -83,6 +84,19 @@ | |||
83 | #include <mach/irqs-board-mop500.h> | 84 | #include <mach/irqs-board-mop500.h> |
84 | #endif | 85 | #endif |
85 | 86 | ||
86 | #define NR_IRQS IRQ_BOARD_END | 87 | /* |
88 | * After the board specific IRQ:s we reserve a range of IRQ:s in which virtual | ||
89 | * IRQ:s representing modem IRQ:s can be allocated | ||
90 | */ | ||
91 | #define IRQ_MODEM_EVENTS_BASE (IRQ_BOARD_END + 1) | ||
92 | #define IRQ_MODEM_EVENTS_NBR 72 | ||
93 | #define IRQ_MODEM_EVENTS_END (IRQ_MODEM_EVENTS_BASE + IRQ_MODEM_EVENTS_NBR) | ||
94 | |||
95 | /* List of virtual IRQ:s that are allocated from the range above */ | ||
96 | #define MBOX_PAIR0_VIRT_IRQ (IRQ_MODEM_EVENTS_BASE + 43) | ||
97 | #define MBOX_PAIR1_VIRT_IRQ (IRQ_MODEM_EVENTS_BASE + 45) | ||
98 | #define MBOX_PAIR2_VIRT_IRQ (IRQ_MODEM_EVENTS_BASE + 41) | ||
99 | |||
100 | #define NR_IRQS IRQ_MODEM_EVENTS_END | ||
87 | 101 | ||
88 | #endif /* ASM_ARCH_IRQS_H */ | 102 | #endif /* ASM_ARCH_IRQS_H */ |
diff --git a/arch/arm/mach-ux500/include/mach/mbox.h b/arch/arm/mach-ux500/include/mach/mbox.h new file mode 100644 index 000000000000..7f9da4d2fbda --- /dev/null +++ b/arch/arm/mach-ux500/include/mach/mbox.h | |||
@@ -0,0 +1,88 @@ | |||
1 | /* | ||
2 | * Copyright (C) ST-Ericsson SA 2010 | ||
3 | * Author: Stefan Nilsson <stefan.xk.nilsson@stericsson.com> for ST-Ericsson. | ||
4 | * Author: Martin Persson <martin.persson@stericsson.com> for ST-Ericsson. | ||
5 | * License terms: GNU General Public License (GPL), version 2. | ||
6 | */ | ||
7 | |||
8 | #ifndef __INC_STE_MBOX_H | ||
9 | #define __INC_STE_MBOX_H | ||
10 | |||
11 | #define MBOX_BUF_SIZE 16 | ||
12 | #define MBOX_NAME_SIZE 8 | ||
13 | |||
14 | /** | ||
15 | * mbox_recv_cb_t - Definition of the mailbox callback. | ||
16 | * @mbox_msg: The mailbox message. | ||
17 | * @priv: The clients private data as specified in the call to mbox_setup. | ||
18 | * | ||
19 | * This function will be called upon reception of new mailbox messages. | ||
20 | */ | ||
21 | typedef void mbox_recv_cb_t (u32 mbox_msg, void *priv); | ||
22 | |||
23 | /** | ||
24 | * struct mbox - Mailbox instance struct | ||
25 | * @list: Linked list head. | ||
26 | * @pdev: Pointer to device struct. | ||
27 | * @cb: Callback function. Will be called | ||
28 | * when new data is received. | ||
29 | * @client_data: Clients private data. Will be sent back | ||
30 | * in the callback function. | ||
31 | * @virtbase_peer: Virtual address for outgoing mailbox. | ||
32 | * @virtbase_local: Virtual address for incoming mailbox. | ||
33 | * @buffer: Then internal queue for outgoing messages. | ||
34 | * @name: Name of this mailbox. | ||
35 | * @buffer_available: Completion variable to achieve "blocking send". | ||
36 | * This variable will be signaled when there is | ||
37 | * internal buffer space available. | ||
38 | * @client_blocked: To keep track if any client is currently | ||
39 | * blocked. | ||
40 | * @lock: Spinlock to protect this mailbox instance. | ||
41 | * @write_index: Index in internal buffer to write to. | ||
42 | * @read_index: Index in internal buffer to read from. | ||
43 | * @allocated: Indicates whether this particular mailbox | ||
44 | * id has been allocated by someone. | ||
45 | */ | ||
46 | struct mbox { | ||
47 | struct list_head list; | ||
48 | struct platform_device *pdev; | ||
49 | mbox_recv_cb_t *cb; | ||
50 | void *client_data; | ||
51 | void __iomem *virtbase_peer; | ||
52 | void __iomem *virtbase_local; | ||
53 | u32 buffer[MBOX_BUF_SIZE]; | ||
54 | char name[MBOX_NAME_SIZE]; | ||
55 | struct completion buffer_available; | ||
56 | u8 client_blocked; | ||
57 | spinlock_t lock; | ||
58 | u8 write_index; | ||
59 | u8 read_index; | ||
60 | bool allocated; | ||
61 | }; | ||
62 | |||
63 | /** | ||
64 | * mbox_setup - Set up a mailbox and return its instance. | ||
65 | * @mbox_id: The ID number of the mailbox. 0 or 1 for modem CPU, | ||
66 | * 2 for modem DSP. | ||
67 | * @mbox_cb: Pointer to the callback function to be called when a new message | ||
68 | * is received. | ||
69 | * @priv: Client user data which will be returned in the callback. | ||
70 | * | ||
71 | * Returns a mailbox instance to be specified in subsequent calls to mbox_send. | ||
72 | */ | ||
73 | struct mbox *mbox_setup(u8 mbox_id, mbox_recv_cb_t *mbox_cb, void *priv); | ||
74 | |||
75 | /** | ||
76 | * mbox_send - Send a mailbox message. | ||
77 | * @mbox: Mailbox instance (returned by mbox_setup) | ||
78 | * @mbox_msg: The mailbox message to send. | ||
79 | * @block: Specifies whether this call will block until send is possible, | ||
80 | * or return an error if the mailbox buffer is full. | ||
81 | * | ||
82 | * Returns 0 on success or a negative error code on error. -ENOMEM indicates | ||
83 | * that the internal buffer is full and you have to try again later (or | ||
84 | * specify "block" in order to block until send is possible). | ||
85 | */ | ||
86 | int mbox_send(struct mbox *mbox, u32 mbox_msg, bool block); | ||
87 | |||
88 | #endif /*INC_STE_MBOX_H*/ | ||
diff --git a/arch/arm/mach-ux500/include/mach/prcmu-regs.h b/arch/arm/mach-ux500/include/mach/prcmu-regs.h new file mode 100644 index 000000000000..8885f39a6421 --- /dev/null +++ b/arch/arm/mach-ux500/include/mach/prcmu-regs.h | |||
@@ -0,0 +1,91 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2009 ST-Ericsson SA | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 | ||
6 | * as published by the Free Software Foundation. | ||
7 | */ | ||
8 | #ifndef __MACH_PRCMU_REGS_H | ||
9 | #define __MACH_PRCMU_REGS_H | ||
10 | |||
11 | #include <mach/hardware.h> | ||
12 | |||
13 | #define _PRCMU_BASE IO_ADDRESS(U8500_PRCMU_BASE) | ||
14 | |||
15 | #define PRCM_ARM_PLLDIVPS (_PRCMU_BASE + 0x118) | ||
16 | #define PRCM_ARM_CHGCLKREQ (_PRCMU_BASE + 0x114) | ||
17 | #define PRCM_PLLARM_ENABLE (_PRCMU_BASE + 0x98) | ||
18 | #define PRCM_ARMCLKFIX_MGT (_PRCMU_BASE + 0x0) | ||
19 | #define PRCM_A9_RESETN_CLR (_PRCMU_BASE + 0x1f4) | ||
20 | #define PRCM_A9_RESETN_SET (_PRCMU_BASE + 0x1f0) | ||
21 | #define PRCM_ARM_LS_CLAMP (_PRCMU_BASE + 0x30c) | ||
22 | #define PRCM_SRAM_A9 (_PRCMU_BASE + 0x308) | ||
23 | |||
24 | /* ARM WFI Standby signal register */ | ||
25 | #define PRCM_ARM_WFI_STANDBY (_PRCMU_BASE + 0x130) | ||
26 | #define PRCMU_IOCR (_PRCMU_BASE + 0x310) | ||
27 | |||
28 | /* CPU mailbox registers */ | ||
29 | #define PRCM_MBOX_CPU_VAL (_PRCMU_BASE + 0x0fc) | ||
30 | #define PRCM_MBOX_CPU_SET (_PRCMU_BASE + 0x100) | ||
31 | #define PRCM_MBOX_CPU_CLR (_PRCMU_BASE + 0x104) | ||
32 | |||
33 | /* Dual A9 core interrupt management unit registers */ | ||
34 | #define PRCM_A9_MASK_REQ (_PRCMU_BASE + 0x328) | ||
35 | #define PRCM_A9_MASK_ACK (_PRCMU_BASE + 0x32c) | ||
36 | #define PRCM_ARMITMSK31TO0 (_PRCMU_BASE + 0x11c) | ||
37 | #define PRCM_ARMITMSK63TO32 (_PRCMU_BASE + 0x120) | ||
38 | #define PRCM_ARMITMSK95TO64 (_PRCMU_BASE + 0x124) | ||
39 | #define PRCM_ARMITMSK127TO96 (_PRCMU_BASE + 0x128) | ||
40 | #define PRCM_POWER_STATE_VAL (_PRCMU_BASE + 0x25C) | ||
41 | #define PRCM_ARMITVAL31TO0 (_PRCMU_BASE + 0x260) | ||
42 | #define PRCM_ARMITVAL63TO32 (_PRCMU_BASE + 0x264) | ||
43 | #define PRCM_ARMITVAL95TO64 (_PRCMU_BASE + 0x268) | ||
44 | #define PRCM_ARMITVAL127TO96 (_PRCMU_BASE + 0x26C) | ||
45 | |||
46 | #define PRCM_HOSTACCESS_REQ (_PRCMU_BASE + 0x334) | ||
47 | #define ARM_WAKEUP_MODEM 0x1 | ||
48 | |||
49 | #define PRCM_ARM_IT1_CLEAR (_PRCMU_BASE + 0x48C) | ||
50 | #define PRCM_ARM_IT1_VAL (_PRCMU_BASE + 0x494) | ||
51 | #define PRCM_HOLD_EVT (_PRCMU_BASE + 0x174) | ||
52 | |||
53 | #define PRCM_ITSTATUS0 (_PRCMU_BASE + 0x148) | ||
54 | #define PRCM_ITSTATUS1 (_PRCMU_BASE + 0x150) | ||
55 | #define PRCM_ITSTATUS2 (_PRCMU_BASE + 0x158) | ||
56 | #define PRCM_ITSTATUS3 (_PRCMU_BASE + 0x160) | ||
57 | #define PRCM_ITSTATUS4 (_PRCMU_BASE + 0x168) | ||
58 | #define PRCM_ITSTATUS5 (_PRCMU_BASE + 0x484) | ||
59 | #define PRCM_ITCLEAR5 (_PRCMU_BASE + 0x488) | ||
60 | #define PRCM_ARMIT_MASKXP70_IT (_PRCMU_BASE + 0x1018) | ||
61 | |||
62 | /* System reset register */ | ||
63 | #define PRCM_APE_SOFTRST (_PRCMU_BASE + 0x228) | ||
64 | |||
65 | /* Level shifter and clamp control registers */ | ||
66 | #define PRCM_MMIP_LS_CLAMP_SET (_PRCMU_BASE + 0x420) | ||
67 | #define PRCM_MMIP_LS_CLAMP_CLR (_PRCMU_BASE + 0x424) | ||
68 | |||
69 | /* PRCMU clock/PLL/reset registers */ | ||
70 | #define PRCM_PLLDSI_FREQ (_PRCMU_BASE + 0x500) | ||
71 | #define PRCM_PLLDSI_ENABLE (_PRCMU_BASE + 0x504) | ||
72 | #define PRCM_LCDCLK_MGT (_PRCMU_BASE + 0x044) | ||
73 | #define PRCM_MCDECLK_MGT (_PRCMU_BASE + 0x064) | ||
74 | #define PRCM_HDMICLK_MGT (_PRCMU_BASE + 0x058) | ||
75 | #define PRCM_TVCLK_MGT (_PRCMU_BASE + 0x07c) | ||
76 | #define PRCM_DSI_PLLOUT_SEL (_PRCMU_BASE + 0x530) | ||
77 | #define PRCM_DSITVCLK_DIV (_PRCMU_BASE + 0x52C) | ||
78 | #define PRCM_APE_RESETN_SET (_PRCMU_BASE + 0x1E4) | ||
79 | #define PRCM_APE_RESETN_CLR (_PRCMU_BASE + 0x1E8) | ||
80 | |||
81 | /* ePOD and memory power signal control registers */ | ||
82 | #define PRCM_EPOD_C_SET (_PRCMU_BASE + 0x410) | ||
83 | #define PRCM_SRAM_LS_SLEEP (_PRCMU_BASE + 0x304) | ||
84 | |||
85 | /* Debug power control unit registers */ | ||
86 | #define PRCM_POWER_STATE_SET (_PRCMU_BASE + 0x254) | ||
87 | |||
88 | /* Miscellaneous unit registers */ | ||
89 | #define PRCM_DSI_SW_RESET (_PRCMU_BASE + 0x324) | ||
90 | |||
91 | #endif /* __MACH_PRCMU__REGS_H */ | ||
diff --git a/arch/arm/mach-ux500/include/mach/prcmu.h b/arch/arm/mach-ux500/include/mach/prcmu.h new file mode 100644 index 000000000000..549843ff6dbe --- /dev/null +++ b/arch/arm/mach-ux500/include/mach/prcmu.h | |||
@@ -0,0 +1,15 @@ | |||
1 | /* | ||
2 | * Copyright (C) STMicroelectronics 2009 | ||
3 | * Copyright (C) ST-Ericsson SA 2010 | ||
4 | * | ||
5 | * License Terms: GNU General Public License v2 | ||
6 | * | ||
7 | * PRCMU f/w APIs | ||
8 | */ | ||
9 | #ifndef __MACH_PRCMU_H | ||
10 | #define __MACH_PRCMU_H | ||
11 | |||
12 | int prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size); | ||
13 | int prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size); | ||
14 | |||
15 | #endif /* __MACH_PRCMU_H */ | ||
diff --git a/arch/arm/mach-ux500/include/mach/setup.h b/arch/arm/mach-ux500/include/mach/setup.h index e978dbd9e210..54bbe648bf58 100644 --- a/arch/arm/mach-ux500/include/mach/setup.h +++ b/arch/arm/mach-ux500/include/mach/setup.h | |||
@@ -38,4 +38,11 @@ extern struct sys_timer ux500_timer; | |||
38 | .type = MT_DEVICE, \ | 38 | .type = MT_DEVICE, \ |
39 | } | 39 | } |
40 | 40 | ||
41 | #define __MEM_DEV_DESC(x, sz) { \ | ||
42 | .virtual = IO_ADDRESS(x), \ | ||
43 | .pfn = __phys_to_pfn(x), \ | ||
44 | .length = sz, \ | ||
45 | .type = MT_MEMORY, \ | ||
46 | } | ||
47 | |||
41 | #endif /* __ASM_ARCH_SETUP_H */ | 48 | #endif /* __ASM_ARCH_SETUP_H */ |
diff --git a/arch/arm/mach-ux500/include/mach/smp.h b/arch/arm/mach-ux500/include/mach/smp.h index b59f7bc9725d..197e8417375e 100644 --- a/arch/arm/mach-ux500/include/mach/smp.h +++ b/arch/arm/mach-ux500/include/mach/smp.h | |||
@@ -10,18 +10,11 @@ | |||
10 | #define ASMARM_ARCH_SMP_H | 10 | #define ASMARM_ARCH_SMP_H |
11 | 11 | ||
12 | #include <asm/hardware/gic.h> | 12 | #include <asm/hardware/gic.h> |
13 | #include <asm/smp_mpidr.h> | ||
13 | 14 | ||
14 | /* This is required to wakeup the secondary core */ | 15 | /* This is required to wakeup the secondary core */ |
15 | extern void u8500_secondary_startup(void); | 16 | extern void u8500_secondary_startup(void); |
16 | 17 | ||
17 | #define hard_smp_processor_id() \ | ||
18 | ({ \ | ||
19 | unsigned int cpunum; \ | ||
20 | __asm__("mrc p15, 0, %0, c0, c0, 5" \ | ||
21 | : "=r" (cpunum)); \ | ||
22 | cpunum &= 0x0F; \ | ||
23 | }) | ||
24 | |||
25 | /* | 18 | /* |
26 | * We use IRQ1 as the IPI | 19 | * We use IRQ1 as the IPI |
27 | */ | 20 | */ |
diff --git a/arch/arm/mach-ux500/mbox.c b/arch/arm/mach-ux500/mbox.c new file mode 100644 index 000000000000..63435389c544 --- /dev/null +++ b/arch/arm/mach-ux500/mbox.c | |||
@@ -0,0 +1,567 @@ | |||
1 | /* | ||
2 | * Copyright (C) ST-Ericsson SA 2010 | ||
3 | * Author: Stefan Nilsson <stefan.xk.nilsson@stericsson.com> for ST-Ericsson. | ||
4 | * Author: Martin Persson <martin.persson@stericsson.com> for ST-Ericsson. | ||
5 | * License terms: GNU General Public License (GPL), version 2. | ||
6 | */ | ||
7 | |||
8 | /* | ||
9 | * Mailbox nomenclature: | ||
10 | * | ||
11 | * APE MODEM | ||
12 | * mbox pairX | ||
13 | * .......................... | ||
14 | * . . | ||
15 | * . peer . | ||
16 | * . send ---- . | ||
17 | * . --> | | . | ||
18 | * . | | . | ||
19 | * . ---- . | ||
20 | * . . | ||
21 | * . local . | ||
22 | * . rec ---- . | ||
23 | * . | | <-- . | ||
24 | * . | | . | ||
25 | * . ---- . | ||
26 | * ......................... | ||
27 | */ | ||
28 | |||
29 | #include <linux/init.h> | ||
30 | #include <linux/module.h> | ||
31 | #include <linux/device.h> | ||
32 | #include <linux/interrupt.h> | ||
33 | #include <linux/spinlock.h> | ||
34 | #include <linux/errno.h> | ||
35 | #include <linux/io.h> | ||
36 | #include <linux/irq.h> | ||
37 | #include <linux/platform_device.h> | ||
38 | #include <linux/debugfs.h> | ||
39 | #include <linux/seq_file.h> | ||
40 | #include <linux/completion.h> | ||
41 | #include <mach/mbox.h> | ||
42 | |||
43 | #define MBOX_NAME "mbox" | ||
44 | |||
45 | #define MBOX_FIFO_DATA 0x000 | ||
46 | #define MBOX_FIFO_ADD 0x004 | ||
47 | #define MBOX_FIFO_REMOVE 0x008 | ||
48 | #define MBOX_FIFO_THRES_FREE 0x00C | ||
49 | #define MBOX_FIFO_THRES_OCCUP 0x010 | ||
50 | #define MBOX_FIFO_STATUS 0x014 | ||
51 | |||
52 | #define MBOX_DISABLE_IRQ 0x4 | ||
53 | #define MBOX_ENABLE_IRQ 0x0 | ||
54 | #define MBOX_LATCH 1 | ||
55 | |||
56 | /* Global list of all mailboxes */ | ||
57 | static struct list_head mboxs = LIST_HEAD_INIT(mboxs); | ||
58 | |||
59 | static struct mbox *get_mbox_with_id(u8 id) | ||
60 | { | ||
61 | u8 i; | ||
62 | struct list_head *pos = &mboxs; | ||
63 | for (i = 0; i <= id; i++) | ||
64 | pos = pos->next; | ||
65 | |||
66 | return (struct mbox *) list_entry(pos, struct mbox, list); | ||
67 | } | ||
68 | |||
69 | int mbox_send(struct mbox *mbox, u32 mbox_msg, bool block) | ||
70 | { | ||
71 | int res = 0; | ||
72 | |||
73 | spin_lock(&mbox->lock); | ||
74 | |||
75 | dev_dbg(&(mbox->pdev->dev), | ||
76 | "About to buffer 0x%X to mailbox 0x%X." | ||
77 | " ri = %d, wi = %d\n", | ||
78 | mbox_msg, (u32)mbox, mbox->read_index, | ||
79 | mbox->write_index); | ||
80 | |||
81 | /* Check if write buffer is full */ | ||
82 | while (((mbox->write_index + 1) % MBOX_BUF_SIZE) == mbox->read_index) { | ||
83 | if (!block) { | ||
84 | dev_dbg(&(mbox->pdev->dev), | ||
85 | "Buffer full in non-blocking call! " | ||
86 | "Returning -ENOMEM!\n"); | ||
87 | res = -ENOMEM; | ||
88 | goto exit; | ||
89 | } | ||
90 | spin_unlock(&mbox->lock); | ||
91 | dev_dbg(&(mbox->pdev->dev), | ||
92 | "Buffer full in blocking call! Sleeping...\n"); | ||
93 | mbox->client_blocked = 1; | ||
94 | wait_for_completion(&mbox->buffer_available); | ||
95 | dev_dbg(&(mbox->pdev->dev), | ||
96 | "Blocking send was woken up! Trying again...\n"); | ||
97 | spin_lock(&mbox->lock); | ||
98 | } | ||
99 | |||
100 | mbox->buffer[mbox->write_index] = mbox_msg; | ||
101 | mbox->write_index = (mbox->write_index + 1) % MBOX_BUF_SIZE; | ||
102 | |||
103 | /* | ||
104 | * Indicate that we want an IRQ as soon as there is a slot | ||
105 | * in the FIFO | ||
106 | */ | ||
107 | writel(MBOX_ENABLE_IRQ, mbox->virtbase_peer + MBOX_FIFO_THRES_FREE); | ||
108 | |||
109 | exit: | ||
110 | spin_unlock(&mbox->lock); | ||
111 | return res; | ||
112 | } | ||
113 | EXPORT_SYMBOL(mbox_send); | ||
114 | |||
115 | #if defined(CONFIG_DEBUG_FS) | ||
116 | /* | ||
117 | * Expected input: <value> <nbr sends> | ||
118 | * Example: "echo 0xdeadbeef 4 > mbox-node" sends 0xdeadbeef 4 times | ||
119 | */ | ||
120 | static ssize_t mbox_write_fifo(struct device *dev, | ||
121 | struct device_attribute *attr, | ||
122 | const char *buf, | ||
123 | size_t count) | ||
124 | { | ||
125 | unsigned long mbox_mess; | ||
126 | unsigned long nbr_sends; | ||
127 | unsigned long i; | ||
128 | char int_buf[16]; | ||
129 | char *token; | ||
130 | char *val; | ||
131 | |||
132 | struct mbox *mbox = (struct mbox *) dev->platform_data; | ||
133 | |||
134 | strncpy((char *) &int_buf, buf, sizeof(int_buf)); | ||
135 | token = (char *) &int_buf; | ||
136 | |||
137 | /* Parse message */ | ||
138 | val = strsep(&token, " "); | ||
139 | if ((val == NULL) || (strict_strtoul(val, 16, &mbox_mess) != 0)) | ||
140 | mbox_mess = 0xDEADBEEF; | ||
141 | |||
142 | val = strsep(&token, " "); | ||
143 | if ((val == NULL) || (strict_strtoul(val, 10, &nbr_sends) != 0)) | ||
144 | nbr_sends = 1; | ||
145 | |||
146 | dev_dbg(dev, "Will write 0x%lX %ld times using data struct at 0x%X\n", | ||
147 | mbox_mess, nbr_sends, (u32) mbox); | ||
148 | |||
149 | for (i = 0; i < nbr_sends; i++) | ||
150 | mbox_send(mbox, mbox_mess, true); | ||
151 | |||
152 | return count; | ||
153 | } | ||
154 | |||
155 | static ssize_t mbox_read_fifo(struct device *dev, | ||
156 | struct device_attribute *attr, | ||
157 | char *buf) | ||
158 | { | ||
159 | int mbox_value; | ||
160 | struct mbox *mbox = (struct mbox *) dev->platform_data; | ||
161 | |||
162 | if ((readl(mbox->virtbase_local + MBOX_FIFO_STATUS) & 0x7) <= 0) | ||
163 | return sprintf(buf, "Mailbox is empty\n"); | ||
164 | |||
165 | mbox_value = readl(mbox->virtbase_local + MBOX_FIFO_DATA); | ||
166 | writel(MBOX_LATCH, (mbox->virtbase_local + MBOX_FIFO_REMOVE)); | ||
167 | |||
168 | return sprintf(buf, "0x%X\n", mbox_value); | ||
169 | } | ||
170 | |||
171 | static DEVICE_ATTR(fifo, S_IWUGO | S_IRUGO, mbox_read_fifo, mbox_write_fifo); | ||
172 | |||
173 | static int mbox_show(struct seq_file *s, void *data) | ||
174 | { | ||
175 | struct list_head *pos; | ||
176 | u8 mbox_index = 0; | ||
177 | |||
178 | list_for_each(pos, &mboxs) { | ||
179 | struct mbox *m = | ||
180 | (struct mbox *) list_entry(pos, struct mbox, list); | ||
181 | if (m == NULL) { | ||
182 | seq_printf(s, | ||
183 | "Unable to retrieve mailbox %d\n", | ||
184 | mbox_index); | ||
185 | continue; | ||
186 | } | ||
187 | |||
188 | spin_lock(&m->lock); | ||
189 | if ((m->virtbase_peer == NULL) || (m->virtbase_local == NULL)) { | ||
190 | seq_printf(s, "MAILBOX %d not setup or corrupt\n", | ||
191 | mbox_index); | ||
192 | spin_unlock(&m->lock); | ||
193 | continue; | ||
194 | } | ||
195 | |||
196 | seq_printf(s, | ||
197 | "===========================\n" | ||
198 | " MAILBOX %d\n" | ||
199 | " PEER MAILBOX DUMP\n" | ||
200 | "---------------------------\n" | ||
201 | "FIFO: 0x%X (%d)\n" | ||
202 | "Free Threshold: 0x%.2X (%d)\n" | ||
203 | "Occupied Threshold: 0x%.2X (%d)\n" | ||
204 | "Status: 0x%.2X (%d)\n" | ||
205 | " Free spaces (ot): %d (%d)\n" | ||
206 | " Occup spaces (ot): %d (%d)\n" | ||
207 | "===========================\n" | ||
208 | " LOCAL MAILBOX DUMP\n" | ||
209 | "---------------------------\n" | ||
210 | "FIFO: 0x%.X (%d)\n" | ||
211 | "Free Threshold: 0x%.2X (%d)\n" | ||
212 | "Occupied Threshold: 0x%.2X (%d)\n" | ||
213 | "Status: 0x%.2X (%d)\n" | ||
214 | " Free spaces (ot): %d (%d)\n" | ||
215 | " Occup spaces (ot): %d (%d)\n" | ||
216 | "===========================\n" | ||
217 | "write_index: %d\n" | ||
218 | "read_index : %d\n" | ||
219 | "===========================\n" | ||
220 | "\n", | ||
221 | mbox_index, | ||
222 | readl(m->virtbase_peer + MBOX_FIFO_DATA), | ||
223 | readl(m->virtbase_peer + MBOX_FIFO_DATA), | ||
224 | readl(m->virtbase_peer + MBOX_FIFO_THRES_FREE), | ||
225 | readl(m->virtbase_peer + MBOX_FIFO_THRES_FREE), | ||
226 | readl(m->virtbase_peer + MBOX_FIFO_THRES_OCCUP), | ||
227 | readl(m->virtbase_peer + MBOX_FIFO_THRES_OCCUP), | ||
228 | readl(m->virtbase_peer + MBOX_FIFO_STATUS), | ||
229 | readl(m->virtbase_peer + MBOX_FIFO_STATUS), | ||
230 | (readl(m->virtbase_peer + MBOX_FIFO_STATUS) >> 4) & 0x7, | ||
231 | (readl(m->virtbase_peer + MBOX_FIFO_STATUS) >> 7) & 0x1, | ||
232 | (readl(m->virtbase_peer + MBOX_FIFO_STATUS) >> 0) & 0x7, | ||
233 | (readl(m->virtbase_peer + MBOX_FIFO_STATUS) >> 3) & 0x1, | ||
234 | readl(m->virtbase_local + MBOX_FIFO_DATA), | ||
235 | readl(m->virtbase_local + MBOX_FIFO_DATA), | ||
236 | readl(m->virtbase_local + MBOX_FIFO_THRES_FREE), | ||
237 | readl(m->virtbase_local + MBOX_FIFO_THRES_FREE), | ||
238 | readl(m->virtbase_local + MBOX_FIFO_THRES_OCCUP), | ||
239 | readl(m->virtbase_local + MBOX_FIFO_THRES_OCCUP), | ||
240 | readl(m->virtbase_local + MBOX_FIFO_STATUS), | ||
241 | readl(m->virtbase_local + MBOX_FIFO_STATUS), | ||
242 | (readl(m->virtbase_local + MBOX_FIFO_STATUS) >> 4) & 0x7, | ||
243 | (readl(m->virtbase_local + MBOX_FIFO_STATUS) >> 7) & 0x1, | ||
244 | (readl(m->virtbase_local + MBOX_FIFO_STATUS) >> 0) & 0x7, | ||
245 | (readl(m->virtbase_local + MBOX_FIFO_STATUS) >> 3) & 0x1, | ||
246 | m->write_index, m->read_index); | ||
247 | mbox_index++; | ||
248 | spin_unlock(&m->lock); | ||
249 | } | ||
250 | |||
251 | return 0; | ||
252 | } | ||
253 | |||
254 | static int mbox_open(struct inode *inode, struct file *file) | ||
255 | { | ||
256 | return single_open(file, mbox_show, NULL); | ||
257 | } | ||
258 | |||
259 | static const struct file_operations mbox_operations = { | ||
260 | .owner = THIS_MODULE, | ||
261 | .open = mbox_open, | ||
262 | .read = seq_read, | ||
263 | .llseek = seq_lseek, | ||
264 | .release = single_release, | ||
265 | }; | ||
266 | #endif | ||
267 | |||
268 | static irqreturn_t mbox_irq(int irq, void *arg) | ||
269 | { | ||
270 | u32 mbox_value; | ||
271 | int nbr_occup; | ||
272 | int nbr_free; | ||
273 | struct mbox *mbox = (struct mbox *) arg; | ||
274 | |||
275 | spin_lock(&mbox->lock); | ||
276 | |||
277 | dev_dbg(&(mbox->pdev->dev), | ||
278 | "mbox IRQ [%d] received. ri = %d, wi = %d\n", | ||
279 | irq, mbox->read_index, mbox->write_index); | ||
280 | |||
281 | /* | ||
282 | * Check if we have any outgoing messages, and if there is space for | ||
283 | * them in the FIFO. | ||
284 | */ | ||
285 | if (mbox->read_index != mbox->write_index) { | ||
286 | /* | ||
287 | * Check by reading FREE for LOCAL since that indicates | ||
288 | * OCCUP for PEER | ||
289 | */ | ||
290 | nbr_free = (readl(mbox->virtbase_local + MBOX_FIFO_STATUS) | ||
291 | >> 4) & 0x7; | ||
292 | dev_dbg(&(mbox->pdev->dev), | ||
293 | "Status indicates %d empty spaces in the FIFO!\n", | ||
294 | nbr_free); | ||
295 | |||
296 | while ((nbr_free > 0) && | ||
297 | (mbox->read_index != mbox->write_index)) { | ||
298 | /* Write the message and latch it into the FIFO */ | ||
299 | writel(mbox->buffer[mbox->read_index], | ||
300 | (mbox->virtbase_peer + MBOX_FIFO_DATA)); | ||
301 | writel(MBOX_LATCH, | ||
302 | (mbox->virtbase_peer + MBOX_FIFO_ADD)); | ||
303 | dev_dbg(&(mbox->pdev->dev), | ||
304 | "Wrote message 0x%X to addr 0x%X\n", | ||
305 | mbox->buffer[mbox->read_index], | ||
306 | (u32) (mbox->virtbase_peer + MBOX_FIFO_DATA)); | ||
307 | |||
308 | nbr_free--; | ||
309 | mbox->read_index = | ||
310 | (mbox->read_index + 1) % MBOX_BUF_SIZE; | ||
311 | } | ||
312 | |||
313 | /* | ||
314 | * Check if we still want IRQ:s when there is free | ||
315 | * space to send | ||
316 | */ | ||
317 | if (mbox->read_index != mbox->write_index) { | ||
318 | dev_dbg(&(mbox->pdev->dev), | ||
319 | "Still have messages to send, but FIFO full. " | ||
320 | "Request IRQ again!\n"); | ||
321 | writel(MBOX_ENABLE_IRQ, | ||
322 | mbox->virtbase_peer + MBOX_FIFO_THRES_FREE); | ||
323 | } else { | ||
324 | dev_dbg(&(mbox->pdev->dev), | ||
325 | "No more messages to send. " | ||
326 | "Do not request IRQ again!\n"); | ||
327 | writel(MBOX_DISABLE_IRQ, | ||
328 | mbox->virtbase_peer + MBOX_FIFO_THRES_FREE); | ||
329 | } | ||
330 | |||
331 | /* | ||
332 | * Check if we can signal any blocked clients that it is OK to | ||
333 | * start buffering again | ||
334 | */ | ||
335 | if (mbox->client_blocked && | ||
336 | (((mbox->write_index + 1) % MBOX_BUF_SIZE) | ||
337 | != mbox->read_index)) { | ||
338 | dev_dbg(&(mbox->pdev->dev), | ||
339 | "Waking up blocked client\n"); | ||
340 | complete(&mbox->buffer_available); | ||
341 | mbox->client_blocked = 0; | ||
342 | } | ||
343 | } | ||
344 | |||
345 | /* Check if we have any incoming messages */ | ||
346 | nbr_occup = readl(mbox->virtbase_local + MBOX_FIFO_STATUS) & 0x7; | ||
347 | if (nbr_occup == 0) | ||
348 | goto exit; | ||
349 | |||
350 | if (mbox->cb == NULL) { | ||
351 | dev_dbg(&(mbox->pdev->dev), "No receive callback registered, " | ||
352 | "leaving %d incoming messages in fifo!\n", nbr_occup); | ||
353 | goto exit; | ||
354 | } | ||
355 | |||
356 | /* Read and acknowledge the message */ | ||
357 | mbox_value = readl(mbox->virtbase_local + MBOX_FIFO_DATA); | ||
358 | writel(MBOX_LATCH, (mbox->virtbase_local + MBOX_FIFO_REMOVE)); | ||
359 | |||
360 | /* Notify consumer of new mailbox message */ | ||
361 | dev_dbg(&(mbox->pdev->dev), "Calling callback for message 0x%X!\n", | ||
362 | mbox_value); | ||
363 | mbox->cb(mbox_value, mbox->client_data); | ||
364 | |||
365 | exit: | ||
366 | dev_dbg(&(mbox->pdev->dev), "Exit mbox IRQ. ri = %d, wi = %d\n", | ||
367 | mbox->read_index, mbox->write_index); | ||
368 | spin_unlock(&mbox->lock); | ||
369 | |||
370 | return IRQ_HANDLED; | ||
371 | } | ||
372 | |||
373 | /* Setup is executed once for each mbox pair */ | ||
374 | struct mbox *mbox_setup(u8 mbox_id, mbox_recv_cb_t *mbox_cb, void *priv) | ||
375 | { | ||
376 | struct resource *resource; | ||
377 | int irq; | ||
378 | int res; | ||
379 | struct mbox *mbox; | ||
380 | |||
381 | mbox = get_mbox_with_id(mbox_id); | ||
382 | if (mbox == NULL) { | ||
383 | dev_err(&(mbox->pdev->dev), "Incorrect mailbox id: %d!\n", | ||
384 | mbox_id); | ||
385 | goto exit; | ||
386 | } | ||
387 | |||
388 | /* | ||
389 | * Check if mailbox has been allocated to someone else, | ||
390 | * otherwise allocate it | ||
391 | */ | ||
392 | if (mbox->allocated) { | ||
393 | dev_err(&(mbox->pdev->dev), "Mailbox number %d is busy!\n", | ||
394 | mbox_id); | ||
395 | mbox = NULL; | ||
396 | goto exit; | ||
397 | } | ||
398 | mbox->allocated = true; | ||
399 | |||
400 | dev_dbg(&(mbox->pdev->dev), "Initiating mailbox number %d: 0x%X...\n", | ||
401 | mbox_id, (u32)mbox); | ||
402 | |||
403 | mbox->client_data = priv; | ||
404 | mbox->cb = mbox_cb; | ||
405 | |||
406 | /* Get addr for peer mailbox and ioremap it */ | ||
407 | resource = platform_get_resource_byname(mbox->pdev, | ||
408 | IORESOURCE_MEM, | ||
409 | "mbox_peer"); | ||
410 | if (resource == NULL) { | ||
411 | dev_err(&(mbox->pdev->dev), | ||
412 | "Unable to retrieve mbox peer resource\n"); | ||
413 | mbox = NULL; | ||
414 | goto exit; | ||
415 | } | ||
416 | dev_dbg(&(mbox->pdev->dev), | ||
417 | "Resource name: %s start: 0x%X, end: 0x%X\n", | ||
418 | resource->name, resource->start, resource->end); | ||
419 | mbox->virtbase_peer = | ||
420 | ioremap(resource->start, resource->end - resource->start); | ||
421 | if (!mbox->virtbase_peer) { | ||
422 | dev_err(&(mbox->pdev->dev), "Unable to ioremap peer mbox\n"); | ||
423 | mbox = NULL; | ||
424 | goto exit; | ||
425 | } | ||
426 | dev_dbg(&(mbox->pdev->dev), | ||
427 | "ioremapped peer physical: (0x%X-0x%X) to virtual: 0x%X\n", | ||
428 | resource->start, resource->end, (u32) mbox->virtbase_peer); | ||
429 | |||
430 | /* Get addr for local mailbox and ioremap it */ | ||
431 | resource = platform_get_resource_byname(mbox->pdev, | ||
432 | IORESOURCE_MEM, | ||
433 | "mbox_local"); | ||
434 | if (resource == NULL) { | ||
435 | dev_err(&(mbox->pdev->dev), | ||
436 | "Unable to retrieve mbox local resource\n"); | ||
437 | mbox = NULL; | ||
438 | goto exit; | ||
439 | } | ||
440 | dev_dbg(&(mbox->pdev->dev), | ||
441 | "Resource name: %s start: 0x%X, end: 0x%X\n", | ||
442 | resource->name, resource->start, resource->end); | ||
443 | mbox->virtbase_local = | ||
444 | ioremap(resource->start, resource->end - resource->start); | ||
445 | if (!mbox->virtbase_local) { | ||
446 | dev_err(&(mbox->pdev->dev), "Unable to ioremap local mbox\n"); | ||
447 | mbox = NULL; | ||
448 | goto exit; | ||
449 | } | ||
450 | dev_dbg(&(mbox->pdev->dev), | ||
451 | "ioremapped local physical: (0x%X-0x%X) to virtual: 0x%X\n", | ||
452 | resource->start, resource->end, (u32) mbox->virtbase_peer); | ||
453 | |||
454 | init_completion(&mbox->buffer_available); | ||
455 | mbox->client_blocked = 0; | ||
456 | |||
457 | /* Get IRQ for mailbox and allocate it */ | ||
458 | irq = platform_get_irq_byname(mbox->pdev, "mbox_irq"); | ||
459 | if (irq < 0) { | ||
460 | dev_err(&(mbox->pdev->dev), | ||
461 | "Unable to retrieve mbox irq resource\n"); | ||
462 | mbox = NULL; | ||
463 | goto exit; | ||
464 | } | ||
465 | |||
466 | dev_dbg(&(mbox->pdev->dev), "Allocating irq %d...\n", irq); | ||
467 | res = request_irq(irq, mbox_irq, 0, mbox->name, (void *) mbox); | ||
468 | if (res < 0) { | ||
469 | dev_err(&(mbox->pdev->dev), | ||
470 | "Unable to allocate mbox irq %d\n", irq); | ||
471 | mbox = NULL; | ||
472 | goto exit; | ||
473 | } | ||
474 | |||
475 | /* Set up mailbox to not launch IRQ on free space in mailbox */ | ||
476 | writel(MBOX_DISABLE_IRQ, mbox->virtbase_peer + MBOX_FIFO_THRES_FREE); | ||
477 | |||
478 | /* | ||
479 | * Set up mailbox to launch IRQ on new message if we have | ||
480 | * a callback set. If not, do not raise IRQ, but keep message | ||
481 | * in FIFO for manual retrieval | ||
482 | */ | ||
483 | if (mbox_cb != NULL) | ||
484 | writel(MBOX_ENABLE_IRQ, | ||
485 | mbox->virtbase_local + MBOX_FIFO_THRES_OCCUP); | ||
486 | else | ||
487 | writel(MBOX_DISABLE_IRQ, | ||
488 | mbox->virtbase_local + MBOX_FIFO_THRES_OCCUP); | ||
489 | |||
490 | #if defined(CONFIG_DEBUG_FS) | ||
491 | res = device_create_file(&(mbox->pdev->dev), &dev_attr_fifo); | ||
492 | if (res != 0) | ||
493 | dev_warn(&(mbox->pdev->dev), | ||
494 | "Unable to create mbox sysfs entry"); | ||
495 | |||
496 | (void) debugfs_create_file("mbox", S_IFREG | S_IRUGO, NULL, | ||
497 | NULL, &mbox_operations); | ||
498 | #endif | ||
499 | |||
500 | dev_info(&(mbox->pdev->dev), | ||
501 | "Mailbox driver with index %d initated!\n", mbox_id); | ||
502 | |||
503 | exit: | ||
504 | return mbox; | ||
505 | } | ||
506 | EXPORT_SYMBOL(mbox_setup); | ||
507 | |||
508 | |||
509 | int __init mbox_probe(struct platform_device *pdev) | ||
510 | { | ||
511 | struct mbox local_mbox; | ||
512 | struct mbox *mbox; | ||
513 | int res = 0; | ||
514 | dev_dbg(&(pdev->dev), "Probing mailbox (pdev = 0x%X)...\n", (u32) pdev); | ||
515 | |||
516 | memset(&local_mbox, 0x0, sizeof(struct mbox)); | ||
517 | |||
518 | /* Associate our mbox data with the platform device */ | ||
519 | res = platform_device_add_data(pdev, | ||
520 | (void *) &local_mbox, | ||
521 | sizeof(struct mbox)); | ||
522 | if (res != 0) { | ||
523 | dev_err(&(pdev->dev), | ||
524 | "Unable to allocate driver platform data!\n"); | ||
525 | goto exit; | ||
526 | } | ||
527 | |||
528 | mbox = (struct mbox *) pdev->dev.platform_data; | ||
529 | mbox->pdev = pdev; | ||
530 | mbox->write_index = 0; | ||
531 | mbox->read_index = 0; | ||
532 | |||
533 | INIT_LIST_HEAD(&(mbox->list)); | ||
534 | list_add_tail(&(mbox->list), &mboxs); | ||
535 | |||
536 | sprintf(mbox->name, "%s", MBOX_NAME); | ||
537 | spin_lock_init(&mbox->lock); | ||
538 | |||
539 | dev_info(&(pdev->dev), "Mailbox driver loaded\n"); | ||
540 | |||
541 | exit: | ||
542 | return res; | ||
543 | } | ||
544 | |||
545 | static struct platform_driver mbox_driver = { | ||
546 | .driver = { | ||
547 | .name = MBOX_NAME, | ||
548 | .owner = THIS_MODULE, | ||
549 | }, | ||
550 | }; | ||
551 | |||
552 | static int __init mbox_init(void) | ||
553 | { | ||
554 | return platform_driver_probe(&mbox_driver, mbox_probe); | ||
555 | } | ||
556 | |||
557 | module_init(mbox_init); | ||
558 | |||
559 | void __exit mbox_exit(void) | ||
560 | { | ||
561 | platform_driver_unregister(&mbox_driver); | ||
562 | } | ||
563 | |||
564 | module_exit(mbox_exit); | ||
565 | |||
566 | MODULE_LICENSE("GPL"); | ||
567 | MODULE_DESCRIPTION("MBOX driver"); | ||
diff --git a/arch/arm/mach-ux500/modem_irq.c b/arch/arm/mach-ux500/modem_irq.c new file mode 100644 index 000000000000..3187f8871169 --- /dev/null +++ b/arch/arm/mach-ux500/modem_irq.c | |||
@@ -0,0 +1,139 @@ | |||
1 | /* | ||
2 | * Copyright (C) ST-Ericsson SA 2010 | ||
3 | * Author: Stefan Nilsson <stefan.xk.nilsson@stericsson.com> for ST-Ericsson. | ||
4 | * Author: Martin Persson <martin.persson@stericsson.com> for ST-Ericsson. | ||
5 | * License terms: GNU General Public License (GPL), version 2. | ||
6 | */ | ||
7 | |||
8 | #include <linux/module.h> | ||
9 | #include <linux/kernel.h> | ||
10 | #include <linux/irq.h> | ||
11 | #include <linux/interrupt.h> | ||
12 | #include <linux/io.h> | ||
13 | #include <linux/slab.h> | ||
14 | |||
15 | #define MODEM_INTCON_BASE_ADDR 0xBFFD3000 | ||
16 | #define MODEM_INTCON_SIZE 0xFFF | ||
17 | |||
18 | #define DEST_IRQ41_OFFSET 0x2A4 | ||
19 | #define DEST_IRQ43_OFFSET 0x2AC | ||
20 | #define DEST_IRQ45_OFFSET 0x2B4 | ||
21 | |||
22 | #define PRIO_IRQ41_OFFSET 0x6A4 | ||
23 | #define PRIO_IRQ43_OFFSET 0x6AC | ||
24 | #define PRIO_IRQ45_OFFSET 0x6B4 | ||
25 | |||
26 | #define ALLOW_IRQ_OFFSET 0x104 | ||
27 | |||
28 | #define MODEM_INTCON_CPU_NBR 0x1 | ||
29 | #define MODEM_INTCON_PRIO_HIGH 0x0 | ||
30 | |||
31 | #define MODEM_INTCON_ALLOW_IRQ41 0x0200 | ||
32 | #define MODEM_INTCON_ALLOW_IRQ43 0x0800 | ||
33 | #define MODEM_INTCON_ALLOW_IRQ45 0x2000 | ||
34 | |||
35 | #define MODEM_IRQ_REG_OFFSET 0x4 | ||
36 | |||
37 | struct modem_irq { | ||
38 | void __iomem *modem_intcon_base; | ||
39 | }; | ||
40 | |||
41 | |||
42 | static void setup_modem_intcon(void __iomem *modem_intcon_base) | ||
43 | { | ||
44 | /* IC_DESTINATION_BASE_ARRAY - Which CPU to receive the IRQ */ | ||
45 | writel(MODEM_INTCON_CPU_NBR, modem_intcon_base + DEST_IRQ41_OFFSET); | ||
46 | writel(MODEM_INTCON_CPU_NBR, modem_intcon_base + DEST_IRQ43_OFFSET); | ||
47 | writel(MODEM_INTCON_CPU_NBR, modem_intcon_base + DEST_IRQ45_OFFSET); | ||
48 | |||
49 | /* IC_PRIORITY_BASE_ARRAY - IRQ priority in modem IRQ controller */ | ||
50 | writel(MODEM_INTCON_PRIO_HIGH, modem_intcon_base + PRIO_IRQ41_OFFSET); | ||
51 | writel(MODEM_INTCON_PRIO_HIGH, modem_intcon_base + PRIO_IRQ43_OFFSET); | ||
52 | writel(MODEM_INTCON_PRIO_HIGH, modem_intcon_base + PRIO_IRQ45_OFFSET); | ||
53 | |||
54 | /* IC_ALLOW_ARRAY - IRQ enable */ | ||
55 | writel(MODEM_INTCON_ALLOW_IRQ41 | | ||
56 | MODEM_INTCON_ALLOW_IRQ43 | | ||
57 | MODEM_INTCON_ALLOW_IRQ45, | ||
58 | modem_intcon_base + ALLOW_IRQ_OFFSET); | ||
59 | } | ||
60 | |||
61 | static irqreturn_t modem_cpu_irq_handler(int irq, void *data) | ||
62 | { | ||
63 | int real_irq; | ||
64 | int virt_irq; | ||
65 | struct modem_irq *mi = (struct modem_irq *)data; | ||
66 | |||
67 | /* Read modem side IRQ number from modem IRQ controller */ | ||
68 | real_irq = readl(mi->modem_intcon_base + MODEM_IRQ_REG_OFFSET) & 0xFF; | ||
69 | virt_irq = IRQ_MODEM_EVENTS_BASE + real_irq; | ||
70 | |||
71 | pr_debug("modem_irq: Worker read addr 0x%X and got value 0x%X " | ||
72 | "which will be 0x%X (%d) which translates to " | ||
73 | "virtual IRQ 0x%X (%d)!\n", | ||
74 | (u32)mi->modem_intcon_base + MODEM_IRQ_REG_OFFSET, | ||
75 | real_irq, | ||
76 | real_irq & 0xFF, | ||
77 | real_irq & 0xFF, | ||
78 | virt_irq, | ||
79 | virt_irq); | ||
80 | |||
81 | if (virt_irq != 0) | ||
82 | generic_handle_irq(virt_irq); | ||
83 | |||
84 | pr_debug("modem_irq: Done handling virtual IRQ %d!\n", virt_irq); | ||
85 | |||
86 | return IRQ_HANDLED; | ||
87 | } | ||
88 | |||
89 | static void create_virtual_irq(int irq, struct irq_chip *modem_irq_chip) | ||
90 | { | ||
91 | set_irq_chip(irq, modem_irq_chip); | ||
92 | set_irq_handler(irq, handle_simple_irq); | ||
93 | set_irq_flags(irq, IRQF_VALID); | ||
94 | |||
95 | pr_debug("modem_irq: Created virtual IRQ %d\n", irq); | ||
96 | } | ||
97 | |||
98 | static int modem_irq_init(void) | ||
99 | { | ||
100 | int err; | ||
101 | static struct irq_chip modem_irq_chip; | ||
102 | struct modem_irq *mi; | ||
103 | |||
104 | pr_info("modem_irq: Set up IRQ handler for incoming modem IRQ %d\n", | ||
105 | IRQ_DB5500_MODEM); | ||
106 | |||
107 | mi = kmalloc(sizeof(struct modem_irq), GFP_KERNEL); | ||
108 | if (!mi) { | ||
109 | pr_err("modem_irq: Could not allocate device\n"); | ||
110 | return -ENOMEM; | ||
111 | } | ||
112 | |||
113 | mi->modem_intcon_base = | ||
114 | ioremap(MODEM_INTCON_BASE_ADDR, MODEM_INTCON_SIZE); | ||
115 | pr_debug("modem_irq: ioremapped modem_intcon_base from " | ||
116 | "phy 0x%x to virt 0x%x\n", MODEM_INTCON_BASE_ADDR, | ||
117 | (u32)mi->modem_intcon_base); | ||
118 | |||
119 | setup_modem_intcon(mi->modem_intcon_base); | ||
120 | |||
121 | modem_irq_chip = dummy_irq_chip; | ||
122 | modem_irq_chip.name = "modem_irq"; | ||
123 | |||
124 | /* Create the virtual IRQ:s needed */ | ||
125 | create_virtual_irq(MBOX_PAIR0_VIRT_IRQ, &modem_irq_chip); | ||
126 | create_virtual_irq(MBOX_PAIR1_VIRT_IRQ, &modem_irq_chip); | ||
127 | create_virtual_irq(MBOX_PAIR2_VIRT_IRQ, &modem_irq_chip); | ||
128 | |||
129 | err = request_threaded_irq(IRQ_DB5500_MODEM, NULL, | ||
130 | modem_cpu_irq_handler, IRQF_ONESHOT, | ||
131 | "modem_irq", mi); | ||
132 | if (err) | ||
133 | pr_err("modem_irq: Could not register IRQ %d\n", | ||
134 | IRQ_DB5500_MODEM); | ||
135 | |||
136 | return 0; | ||
137 | } | ||
138 | |||
139 | arch_initcall(modem_irq_init); | ||
diff --git a/arch/arm/mach-ux500/pins-db5500.h b/arch/arm/mach-ux500/pins-db5500.h new file mode 100644 index 000000000000..bf50c21fe69d --- /dev/null +++ b/arch/arm/mach-ux500/pins-db5500.h | |||
@@ -0,0 +1,620 @@ | |||
1 | /* | ||
2 | * Copyright (C) ST-Ericsson SA 2010 | ||
3 | * | ||
4 | * License terms: GNU General Public License, version 2 | ||
5 | * Author: Rabin Vincent <rabin.vincent@stericsson.com> | ||
6 | */ | ||
7 | |||
8 | #ifndef __MACH_DB5500_PINS_H | ||
9 | #define __MACH_DB5500_PINS_H | ||
10 | |||
11 | #define GPIO0_GPIO PIN_CFG(0, GPIO) | ||
12 | #define GPIO0_SM_CS3n PIN_CFG(0, ALT_A) | ||
13 | |||
14 | #define GPIO1_GPIO PIN_CFG(1, GPIO) | ||
15 | #define GPIO1_SM_A3 PIN_CFG(1, ALT_A) | ||
16 | |||
17 | #define GPIO2_GPIO PIN_CFG(2, GPIO) | ||
18 | #define GPIO2_SM_A4 PIN_CFG(2, ALT_A) | ||
19 | #define GPIO2_SM_AVD PIN_CFG(2, ALT_B) | ||
20 | |||
21 | #define GPIO3_GPIO PIN_CFG(3, GPIO) | ||
22 | #define GPIO3_I2C1_SCL PIN_CFG(3, ALT_A) | ||
23 | |||
24 | #define GPIO4_GPIO PIN_CFG(4, GPIO) | ||
25 | #define GPIO4_I2C1_SDA PIN_CFG(4, ALT_A) | ||
26 | |||
27 | #define GPIO5_GPIO PIN_CFG(5, GPIO) | ||
28 | #define GPIO5_MC0_DAT0 PIN_CFG(5, ALT_A) | ||
29 | #define GPIO5_SM_ADQ8 PIN_CFG(5, ALT_B) | ||
30 | |||
31 | #define GPIO6_GPIO PIN_CFG(6, GPIO) | ||
32 | #define GPIO6_MC0_DAT1 PIN_CFG(6, ALT_A) | ||
33 | #define GPIO6_SM_ADQ0 PIN_CFG(6, ALT_B) | ||
34 | |||
35 | #define GPIO7_GPIO PIN_CFG(7, GPIO) | ||
36 | #define GPIO7_MC0_DAT2 PIN_CFG(7, ALT_A) | ||
37 | #define GPIO7_SM_ADQ9 PIN_CFG(7, ALT_B) | ||
38 | |||
39 | #define GPIO8_GPIO PIN_CFG(8, GPIO) | ||
40 | #define GPIO8_MC0_DAT3 PIN_CFG(8, ALT_A) | ||
41 | #define GPIO8_SM_ADQ1 PIN_CFG(8, ALT_B) | ||
42 | |||
43 | #define GPIO9_GPIO PIN_CFG(9, GPIO) | ||
44 | #define GPIO9_MC0_DAT4 PIN_CFG(9, ALT_A) | ||
45 | #define GPIO9_SM_ADQ10 PIN_CFG(9, ALT_B) | ||
46 | |||
47 | #define GPIO10_GPIO PIN_CFG(10, GPIO) | ||
48 | #define GPIO10_MC0_DAT5 PIN_CFG(10, ALT_A) | ||
49 | #define GPIO10_SM_ADQ2 PIN_CFG(10, ALT_B) | ||
50 | |||
51 | #define GPIO11_GPIO PIN_CFG(11, GPIO) | ||
52 | #define GPIO11_MC0_DAT6 PIN_CFG(11, ALT_A) | ||
53 | #define GPIO11_SM_ADQ11 PIN_CFG(11, ALT_B) | ||
54 | |||
55 | #define GPIO12_GPIO PIN_CFG(12, GPIO) | ||
56 | #define GPIO12_MC0_DAT7 PIN_CFG(12, ALT_A) | ||
57 | #define GPIO12_SM_ADQ3 PIN_CFG(12, ALT_B) | ||
58 | |||
59 | #define GPIO13_GPIO PIN_CFG(13, GPIO) | ||
60 | #define GPIO13_MC0_CMD PIN_CFG(13, ALT_A) | ||
61 | #define GPIO13_SM_BUSY0n PIN_CFG(13, ALT_B) | ||
62 | #define GPIO13_SM_WAIT0n PIN_CFG(13, ALT_C) | ||
63 | |||
64 | #define GPIO14_GPIO PIN_CFG(14, GPIO) | ||
65 | #define GPIO14_MC0_CLK PIN_CFG(14, ALT_A) | ||
66 | #define GPIO14_SM_CS1n PIN_CFG(14, ALT_B) | ||
67 | #define GPIO14_SM_CKO PIN_CFG(14, ALT_C) | ||
68 | |||
69 | #define GPIO15_GPIO PIN_CFG(15, GPIO) | ||
70 | #define GPIO15_SM_A5 PIN_CFG(15, ALT_A) | ||
71 | #define GPIO15_SM_CLE PIN_CFG(15, ALT_B) | ||
72 | |||
73 | #define GPIO16_GPIO PIN_CFG(16, GPIO) | ||
74 | #define GPIO16_MC2_CMD PIN_CFG(16, ALT_A) | ||
75 | #define GPIO16_SM_OEn PIN_CFG(16, ALT_B) | ||
76 | |||
77 | #define GPIO17_GPIO PIN_CFG(17, GPIO) | ||
78 | #define GPIO17_MC2_CLK PIN_CFG(17, ALT_A) | ||
79 | #define GPIO17_SM_WEn PIN_CFG(17, ALT_B) | ||
80 | |||
81 | #define GPIO18_GPIO PIN_CFG(18, GPIO) | ||
82 | #define GPIO18_SM_A6 PIN_CFG(18, ALT_A) | ||
83 | #define GPIO18_SM_ALE PIN_CFG(18, ALT_B) | ||
84 | #define GPIO18_SM_AVDn PIN_CFG(18, ALT_C) | ||
85 | |||
86 | #define GPIO19_GPIO PIN_CFG(19, GPIO) | ||
87 | #define GPIO19_MC2_DAT1 PIN_CFG(19, ALT_A) | ||
88 | #define GPIO19_SM_ADQ4 PIN_CFG(19, ALT_B) | ||
89 | |||
90 | #define GPIO20_GPIO PIN_CFG(20, GPIO) | ||
91 | #define GPIO20_MC2_DAT3 PIN_CFG(20, ALT_A) | ||
92 | #define GPIO20_SM_ADQ5 PIN_CFG(20, ALT_B) | ||
93 | |||
94 | #define GPIO21_GPIO PIN_CFG(21, GPIO) | ||
95 | #define GPIO21_MC2_DAT5 PIN_CFG(21, ALT_A) | ||
96 | #define GPIO21_SM_ADQ6 PIN_CFG(21, ALT_B) | ||
97 | |||
98 | #define GPIO22_GPIO PIN_CFG(22, GPIO) | ||
99 | #define GPIO22_MC2_DAT7 PIN_CFG(22, ALT_A) | ||
100 | #define GPIO22_SM_ADQ7 PIN_CFG(22, ALT_B) | ||
101 | |||
102 | #define GPIO23_GPIO PIN_CFG(23, GPIO) | ||
103 | #define GPIO23_MC2_DAT0 PIN_CFG(23, ALT_A) | ||
104 | #define GPIO23_SM_ADQ12 PIN_CFG(23, ALT_B) | ||
105 | #define GPIO23_MC0_DAT1 PIN_CFG(23, ALT_C) | ||
106 | |||
107 | #define GPIO24_GPIO PIN_CFG(24, GPIO) | ||
108 | #define GPIO24_MC2_DAT2 PIN_CFG(24, ALT_A) | ||
109 | #define GPIO24_SM_ADQ13 PIN_CFG(24, ALT_B) | ||
110 | #define GPIO24_MC0_DAT3 PIN_CFG(24, ALT_C) | ||
111 | |||
112 | #define GPIO25_GPIO PIN_CFG(25, GPIO) | ||
113 | #define GPIO25_MC2_DAT4 PIN_CFG(25, ALT_A) | ||
114 | #define GPIO25_SM_ADQ14 PIN_CFG(25, ALT_B) | ||
115 | #define GPIO25_MC0_CMD PIN_CFG(25, ALT_C) | ||
116 | |||
117 | #define GPIO26_GPIO PIN_CFG(26, GPIO) | ||
118 | #define GPIO26_MC2_DAT6 PIN_CFG(26, ALT_A) | ||
119 | #define GPIO26_SM_ADQ15 PIN_CFG(26, ALT_B) | ||
120 | |||
121 | #define GPIO27_GPIO PIN_CFG(27, GPIO) | ||
122 | #define GPIO27_SM_CS0n PIN_CFG(27, ALT_A) | ||
123 | #define GPIO27_SM_PS0n PIN_CFG(27, ALT_B) | ||
124 | |||
125 | #define GPIO28_GPIO PIN_CFG(28, GPIO) | ||
126 | #define GPIO28_U0_TXD PIN_CFG(28, ALT_A) | ||
127 | #define GPIO28_SM_A0 PIN_CFG(28, ALT_B) | ||
128 | |||
129 | #define GPIO29_GPIO PIN_CFG(29, GPIO) | ||
130 | #define GPIO29_U0_RXD PIN_CFG(29, ALT_A) | ||
131 | #define GPIO29_SM_A1 PIN_CFG(29, ALT_B) | ||
132 | #define GPIO29_PWM_0 PIN_CFG(29, ALT_C) | ||
133 | |||
134 | #define GPIO30_GPIO PIN_CFG(30, GPIO) | ||
135 | #define GPIO30_MC0_DAT5 PIN_CFG(30, ALT_A) | ||
136 | #define GPIO30_SM_A2 PIN_CFG(30, ALT_B) | ||
137 | #define GPIO30_PWM_1 PIN_CFG(30, ALT_C) | ||
138 | |||
139 | #define GPIO31_GPIO PIN_CFG(31, GPIO) | ||
140 | #define GPIO31_MC0_DAT7 PIN_CFG(31, ALT_A) | ||
141 | #define GPIO31_SM_CS2n PIN_CFG(31, ALT_B) | ||
142 | #define GPIO31_PWM_2 PIN_CFG(31, ALT_C) | ||
143 | |||
144 | #define GPIO32_GPIO PIN_CFG(32, GPIO) | ||
145 | #define GPIO32_MSP0_TCK PIN_CFG(32, ALT_A) | ||
146 | #define GPIO32_ACCI2S0_SCK PIN_CFG(32, ALT_B) | ||
147 | |||
148 | #define GPIO33_GPIO PIN_CFG(33, GPIO) | ||
149 | #define GPIO33_MSP0_TFS PIN_CFG(33, ALT_A) | ||
150 | #define GPIO33_ACCI2S0_WS PIN_CFG(33, ALT_B) | ||
151 | |||
152 | #define GPIO34_GPIO PIN_CFG(34, GPIO) | ||
153 | #define GPIO34_MSP0_TXD PIN_CFG(34, ALT_A) | ||
154 | #define GPIO34_ACCI2S0_DLD PIN_CFG(34, ALT_B) | ||
155 | |||
156 | #define GPIO35_GPIO PIN_CFG(35, GPIO) | ||
157 | #define GPIO35_MSP0_RXD PIN_CFG(35, ALT_A) | ||
158 | #define GPIO35_ACCI2S0_ULD PIN_CFG(35, ALT_B) | ||
159 | |||
160 | #define GPIO64_GPIO PIN_CFG(64, GPIO) | ||
161 | #define GPIO64_USB_DAT0 PIN_CFG(64, ALT_A) | ||
162 | #define GPIO64_U0_TXD PIN_CFG(64, ALT_B) | ||
163 | |||
164 | #define GPIO65_GPIO PIN_CFG(65, GPIO) | ||
165 | #define GPIO65_USB_DAT1 PIN_CFG(65, ALT_A) | ||
166 | #define GPIO65_U0_RXD PIN_CFG(65, ALT_B) | ||
167 | |||
168 | #define GPIO66_GPIO PIN_CFG(66, GPIO) | ||
169 | #define GPIO66_USB_DAT2 PIN_CFG(66, ALT_A) | ||
170 | |||
171 | #define GPIO67_GPIO PIN_CFG(67, GPIO) | ||
172 | #define GPIO67_USB_DAT3 PIN_CFG(67, ALT_A) | ||
173 | |||
174 | #define GPIO68_GPIO PIN_CFG(68, GPIO) | ||
175 | #define GPIO68_USB_DAT4 PIN_CFG(68, ALT_A) | ||
176 | |||
177 | #define GPIO69_GPIO PIN_CFG(69, GPIO) | ||
178 | #define GPIO69_USB_DAT5 PIN_CFG(69, ALT_A) | ||
179 | |||
180 | #define GPIO70_GPIO PIN_CFG(70, GPIO) | ||
181 | #define GPIO70_USB_DAT6 PIN_CFG(70, ALT_A) | ||
182 | |||
183 | #define GPIO71_GPIO PIN_CFG(71, GPIO) | ||
184 | #define GPIO71_USB_DAT7 PIN_CFG(71, ALT_A) | ||
185 | |||
186 | #define GPIO72_GPIO PIN_CFG(72, GPIO) | ||
187 | #define GPIO72_USB_STP PIN_CFG(72, ALT_A) | ||
188 | |||
189 | #define GPIO73_GPIO PIN_CFG(73, GPIO) | ||
190 | #define GPIO73_USB_DIR PIN_CFG(73, ALT_A) | ||
191 | |||
192 | #define GPIO74_GPIO PIN_CFG(74, GPIO) | ||
193 | #define GPIO74_USB_NXT PIN_CFG(74, ALT_A) | ||
194 | |||
195 | #define GPIO75_GPIO PIN_CFG(75, GPIO) | ||
196 | #define GPIO75_USB_XCLK PIN_CFG(75, ALT_A) | ||
197 | |||
198 | #define GPIO76_GPIO PIN_CFG(76, GPIO) | ||
199 | |||
200 | #define GPIO77_GPIO PIN_CFG(77, GPIO) | ||
201 | #define GPIO77_ACCTX_ON PIN_CFG(77, ALT_A) | ||
202 | |||
203 | #define GPIO78_GPIO PIN_CFG(78, GPIO) | ||
204 | #define GPIO78_IRQn PIN_CFG(78, ALT_A) | ||
205 | |||
206 | #define GPIO79_GPIO PIN_CFG(79, GPIO) | ||
207 | #define GPIO79_ACCSIM_Clk PIN_CFG(79, ALT_A) | ||
208 | |||
209 | #define GPIO80_GPIO PIN_CFG(80, GPIO) | ||
210 | #define GPIO80_ACCSIM_Da PIN_CFG(80, ALT_A) | ||
211 | |||
212 | #define GPIO81_GPIO PIN_CFG(81, GPIO) | ||
213 | #define GPIO81_ACCSIM_Reset PIN_CFG(81, ALT_A) | ||
214 | |||
215 | #define GPIO82_GPIO PIN_CFG(82, GPIO) | ||
216 | #define GPIO82_ACCSIM_DDir PIN_CFG(82, ALT_A) | ||
217 | |||
218 | #define GPIO96_GPIO PIN_CFG(96, GPIO) | ||
219 | #define GPIO96_MSP1_TCK PIN_CFG(96, ALT_A) | ||
220 | #define GPIO96_PRCMU_DEBUG3 PIN_CFG(96, ALT_B) | ||
221 | #define GPIO96_PRCMU_DEBUG7 PIN_CFG(96, ALT_C) | ||
222 | |||
223 | #define GPIO97_GPIO PIN_CFG(97, GPIO) | ||
224 | #define GPIO97_MSP1_TFS PIN_CFG(97, ALT_A) | ||
225 | #define GPIO97_PRCMU_DEBUG2 PIN_CFG(97, ALT_B) | ||
226 | #define GPIO97_PRCMU_DEBUG6 PIN_CFG(97, ALT_C) | ||
227 | |||
228 | #define GPIO98_GPIO PIN_CFG(98, GPIO) | ||
229 | #define GPIO98_MSP1_TXD PIN_CFG(98, ALT_A) | ||
230 | #define GPIO98_PRCMU_DEBUG1 PIN_CFG(98, ALT_B) | ||
231 | #define GPIO98_PRCMU_DEBUG5 PIN_CFG(98, ALT_C) | ||
232 | |||
233 | #define GPIO99_GPIO PIN_CFG(99, GPIO) | ||
234 | #define GPIO99_MSP1_RXD PIN_CFG(99, ALT_A) | ||
235 | #define GPIO99_PRCMU_DEBUG0 PIN_CFG(99, ALT_B) | ||
236 | #define GPIO99_PRCMU_DEBUG4 PIN_CFG(99, ALT_C) | ||
237 | |||
238 | #define GPIO100_GPIO PIN_CFG(100, GPIO) | ||
239 | #define GPIO100_I2C0_SCL PIN_CFG(100, ALT_A) | ||
240 | |||
241 | #define GPIO101_GPIO PIN_CFG(101, GPIO) | ||
242 | #define GPIO101_I2C0_SDA PIN_CFG(101, ALT_A) | ||
243 | |||
244 | #define GPIO128_GPIO PIN_CFG(128, GPIO) | ||
245 | #define GPIO128_KP_I0 PIN_CFG(128, ALT_A) | ||
246 | #define GPIO128_BUSMON_D0 PIN_CFG(128, ALT_B) | ||
247 | |||
248 | #define GPIO129_GPIO PIN_CFG(129, GPIO) | ||
249 | #define GPIO129_KP_O0 PIN_CFG(129, ALT_A) | ||
250 | #define GPIO129_BUSMON_D1 PIN_CFG(129, ALT_B) | ||
251 | |||
252 | #define GPIO130_GPIO PIN_CFG(130, GPIO) | ||
253 | #define GPIO130_KP_I1 PIN_CFG(130, ALT_A) | ||
254 | #define GPIO130_BUSMON_D2 PIN_CFG(130, ALT_B) | ||
255 | |||
256 | #define GPIO131_GPIO PIN_CFG(131, GPIO) | ||
257 | #define GPIO131_KP_O1 PIN_CFG(131, ALT_A) | ||
258 | #define GPIO131_BUSMON_D3 PIN_CFG(131, ALT_B) | ||
259 | |||
260 | #define GPIO132_GPIO PIN_CFG(132, GPIO) | ||
261 | #define GPIO132_KP_I2 PIN_CFG(132, ALT_A) | ||
262 | #define GPIO132_ETM_D15 PIN_CFG(132, ALT_B) | ||
263 | #define GPIO132_STMAPE_CLK PIN_CFG(132, ALT_C) | ||
264 | |||
265 | #define GPIO133_GPIO PIN_CFG(133, GPIO) | ||
266 | #define GPIO133_KP_O2 PIN_CFG(133, ALT_A) | ||
267 | #define GPIO133_ETM_D14 PIN_CFG(133, ALT_B) | ||
268 | #define GPIO133_U0_RXD PIN_CFG(133, ALT_C) | ||
269 | |||
270 | #define GPIO134_GPIO PIN_CFG(134, GPIO) | ||
271 | #define GPIO134_KP_I3 PIN_CFG(134, ALT_A) | ||
272 | #define GPIO134_ETM_D13 PIN_CFG(134, ALT_B) | ||
273 | #define GPIO134_STMAPE_DAT0 PIN_CFG(134, ALT_C) | ||
274 | |||
275 | #define GPIO135_GPIO PIN_CFG(135, GPIO) | ||
276 | #define GPIO135_KP_O3 PIN_CFG(135, ALT_A) | ||
277 | #define GPIO135_ETM_D12 PIN_CFG(135, ALT_B) | ||
278 | #define GPIO135_STMAPE_DAT1 PIN_CFG(135, ALT_C) | ||
279 | |||
280 | #define GPIO136_GPIO PIN_CFG(136, GPIO) | ||
281 | #define GPIO136_KP_I4 PIN_CFG(136, ALT_A) | ||
282 | #define GPIO136_ETM_D11 PIN_CFG(136, ALT_B) | ||
283 | #define GPIO136_STMAPE_DAT2 PIN_CFG(136, ALT_C) | ||
284 | |||
285 | #define GPIO137_GPIO PIN_CFG(137, GPIO) | ||
286 | #define GPIO137_KP_O4 PIN_CFG(137, ALT_A) | ||
287 | #define GPIO137_ETM_D10 PIN_CFG(137, ALT_B) | ||
288 | #define GPIO137_STMAPE_DAT3 PIN_CFG(137, ALT_C) | ||
289 | |||
290 | #define GPIO138_GPIO PIN_CFG(138, GPIO) | ||
291 | #define GPIO138_KP_I5 PIN_CFG(138, ALT_A) | ||
292 | #define GPIO138_ETM_D9 PIN_CFG(138, ALT_B) | ||
293 | #define GPIO138_U0_TXD PIN_CFG(138, ALT_C) | ||
294 | |||
295 | #define GPIO139_GPIO PIN_CFG(139, GPIO) | ||
296 | #define GPIO139_KP_O5 PIN_CFG(139, ALT_A) | ||
297 | #define GPIO139_ETM_D8 PIN_CFG(139, ALT_B) | ||
298 | #define GPIO139_BUSMON_D11 PIN_CFG(139, ALT_C) | ||
299 | |||
300 | #define GPIO140_GPIO PIN_CFG(140, GPIO) | ||
301 | #define GPIO140_KP_I6 PIN_CFG(140, ALT_A) | ||
302 | #define GPIO140_ETM_D7 PIN_CFG(140, ALT_B) | ||
303 | #define GPIO140_STMAPE_CLK PIN_CFG(140, ALT_C) | ||
304 | |||
305 | #define GPIO141_GPIO PIN_CFG(141, GPIO) | ||
306 | #define GPIO141_KP_O6 PIN_CFG(141, ALT_A) | ||
307 | #define GPIO141_ETM_D6 PIN_CFG(141, ALT_B) | ||
308 | #define GPIO141_U0_RXD PIN_CFG(141, ALT_C) | ||
309 | |||
310 | #define GPIO142_GPIO PIN_CFG(142, GPIO) | ||
311 | #define GPIO142_KP_I7 PIN_CFG(142, ALT_A) | ||
312 | #define GPIO142_ETM_D5 PIN_CFG(142, ALT_B) | ||
313 | #define GPIO142_STMAPE_DAT0 PIN_CFG(142, ALT_C) | ||
314 | |||
315 | #define GPIO143_GPIO PIN_CFG(143, GPIO) | ||
316 | #define GPIO143_KP_O7 PIN_CFG(143, ALT_A) | ||
317 | #define GPIO143_ETM_D4 PIN_CFG(143, ALT_B) | ||
318 | #define GPIO143_STMAPE_DAT1 PIN_CFG(143, ALT_C) | ||
319 | |||
320 | #define GPIO144_GPIO PIN_CFG(144, GPIO) | ||
321 | #define GPIO144_I2C3_SCL PIN_CFG(144, ALT_A) | ||
322 | #define GPIO144_ETM_D3 PIN_CFG(144, ALT_B) | ||
323 | #define GPIO144_STMAPE_DAT2 PIN_CFG(144, ALT_C) | ||
324 | |||
325 | #define GPIO145_GPIO PIN_CFG(145, GPIO) | ||
326 | #define GPIO145_I2C3_SDA PIN_CFG(145, ALT_A) | ||
327 | #define GPIO145_ETM_D2 PIN_CFG(145, ALT_B) | ||
328 | #define GPIO145_STMAPE_DAT3 PIN_CFG(145, ALT_C) | ||
329 | |||
330 | #define GPIO146_GPIO PIN_CFG(146, GPIO) | ||
331 | #define GPIO146_PWM_0 PIN_CFG(146, ALT_A) | ||
332 | #define GPIO146_ETM_D1 PIN_CFG(146, ALT_B) | ||
333 | |||
334 | #define GPIO147_GPIO PIN_CFG(147, GPIO) | ||
335 | #define GPIO147_PWM_1 PIN_CFG(147, ALT_A) | ||
336 | #define GPIO147_ETM_D0 PIN_CFG(147, ALT_B) | ||
337 | |||
338 | #define GPIO148_GPIO PIN_CFG(148, GPIO) | ||
339 | #define GPIO148_PWM_2 PIN_CFG(148, ALT_A) | ||
340 | #define GPIO148_ETM_CLK PIN_CFG(148, ALT_B) | ||
341 | |||
342 | #define GPIO160_GPIO PIN_CFG(160, GPIO) | ||
343 | #define GPIO160_CLKOUT_REQn PIN_CFG(160, ALT_A) | ||
344 | |||
345 | #define GPIO161_GPIO PIN_CFG(161, GPIO) | ||
346 | #define GPIO161_CLKOUT_0 PIN_CFG(161, ALT_A) | ||
347 | |||
348 | #define GPIO162_GPIO PIN_CFG(162, GPIO) | ||
349 | #define GPIO162_CLKOUT_1 PIN_CFG(162, ALT_A) | ||
350 | |||
351 | #define GPIO163_GPIO PIN_CFG(163, GPIO) | ||
352 | |||
353 | #define GPIO164_GPIO PIN_CFG(164, GPIO) | ||
354 | #define GPIO164_GPS_START PIN_CFG(164, ALT_A) | ||
355 | |||
356 | #define GPIO165_GPIO PIN_CFG(165, GPIO) | ||
357 | #define GPIO165_SPI1_CS2n PIN_CFG(165, ALT_A) | ||
358 | #define GPIO165_U3_RXD PIN_CFG(165, ALT_B) | ||
359 | #define GPIO165_BUSMON_D20 PIN_CFG(165, ALT_C) | ||
360 | |||
361 | #define GPIO166_GPIO PIN_CFG(166, GPIO) | ||
362 | #define GPIO166_SPI1_CS1n PIN_CFG(166, ALT_A) | ||
363 | #define GPIO166_U3_TXD PIN_CFG(166, ALT_B) | ||
364 | #define GPIO166_BUSMON_D21 PIN_CFG(166, ALT_C) | ||
365 | |||
366 | #define GPIO167_GPIO PIN_CFG(167, GPIO) | ||
367 | #define GPIO167_SPI1_CS0n PIN_CFG(167, ALT_A) | ||
368 | #define GPIO167_U3_RTSn PIN_CFG(167, ALT_B) | ||
369 | #define GPIO167_BUSMON_D22 PIN_CFG(167, ALT_C) | ||
370 | |||
371 | #define GPIO168_GPIO PIN_CFG(168, GPIO) | ||
372 | #define GPIO168_SPI1_RXD PIN_CFG(168, ALT_A) | ||
373 | #define GPIO168_U3_CTSn PIN_CFG(168, ALT_B) | ||
374 | #define GPIO168_BUSMON_D23 PIN_CFG(168, ALT_C) | ||
375 | |||
376 | #define GPIO169_GPIO PIN_CFG(169, GPIO) | ||
377 | #define GPIO169_SPI1_TXD PIN_CFG(169, ALT_A) | ||
378 | #define GPIO169_DDR_RC PIN_CFG(169, ALT_B) | ||
379 | #define GPIO169_BUSMON_D24 PIN_CFG(169, ALT_C) | ||
380 | |||
381 | #define GPIO170_GPIO PIN_CFG(170, GPIO) | ||
382 | #define GPIO170_SPI1_CLK PIN_CFG(170, ALT_A) | ||
383 | |||
384 | #define GPIO171_GPIO PIN_CFG(171, GPIO) | ||
385 | #define GPIO171_MC3_DAT0 PIN_CFG(171, ALT_A) | ||
386 | #define GPIO171_SPI3_RXD PIN_CFG(171, ALT_B) | ||
387 | #define GPIO171_BUSMON_D25 PIN_CFG(171, ALT_C) | ||
388 | |||
389 | #define GPIO172_GPIO PIN_CFG(172, GPIO) | ||
390 | #define GPIO172_MC3_DAT1 PIN_CFG(172, ALT_A) | ||
391 | #define GPIO172_SPI3_CS1n PIN_CFG(172, ALT_B) | ||
392 | #define GPIO172_BUSMON_D26 PIN_CFG(172, ALT_C) | ||
393 | |||
394 | #define GPIO173_GPIO PIN_CFG(173, GPIO) | ||
395 | #define GPIO173_MC3_DAT2 PIN_CFG(173, ALT_A) | ||
396 | #define GPIO173_SPI3_CS2n PIN_CFG(173, ALT_B) | ||
397 | #define GPIO173_BUSMON_D27 PIN_CFG(173, ALT_C) | ||
398 | |||
399 | #define GPIO174_GPIO PIN_CFG(174, GPIO) | ||
400 | #define GPIO174_MC3_DAT3 PIN_CFG(174, ALT_A) | ||
401 | #define GPIO174_SPI3_CS0n PIN_CFG(174, ALT_B) | ||
402 | #define GPIO174_BUSMON_D28 PIN_CFG(174, ALT_C) | ||
403 | |||
404 | #define GPIO175_GPIO PIN_CFG(175, GPIO) | ||
405 | #define GPIO175_MC3_CMD PIN_CFG(175, ALT_A) | ||
406 | #define GPIO175_SPI3_TXD PIN_CFG(175, ALT_B) | ||
407 | #define GPIO175_BUSMON_D29 PIN_CFG(175, ALT_C) | ||
408 | |||
409 | #define GPIO176_GPIO PIN_CFG(176, GPIO) | ||
410 | #define GPIO176_MC3_CLK PIN_CFG(176, ALT_A) | ||
411 | #define GPIO176_SPI3_CLK PIN_CFG(176, ALT_B) | ||
412 | |||
413 | #define GPIO177_GPIO PIN_CFG(177, GPIO) | ||
414 | #define GPIO177_U2_RXD PIN_CFG(177, ALT_A) | ||
415 | #define GPIO177_I2C3_SCL PIN_CFG(177, ALT_B) | ||
416 | #define GPIO177_BUSMON_D30 PIN_CFG(177, ALT_C) | ||
417 | |||
418 | #define GPIO178_GPIO PIN_CFG(178, GPIO) | ||
419 | #define GPIO178_U2_TXD PIN_CFG(178, ALT_A) | ||
420 | #define GPIO178_I2C3_SDA PIN_CFG(178, ALT_B) | ||
421 | #define GPIO178_BUSMON_D31 PIN_CFG(178, ALT_C) | ||
422 | |||
423 | #define GPIO179_GPIO PIN_CFG(179, GPIO) | ||
424 | #define GPIO179_U2_CTSn PIN_CFG(179, ALT_A) | ||
425 | #define GPIO179_U3_RXD PIN_CFG(179, ALT_B) | ||
426 | #define GPIO179_BUSMON_D32 PIN_CFG(179, ALT_C) | ||
427 | |||
428 | #define GPIO180_GPIO PIN_CFG(180, GPIO) | ||
429 | #define GPIO180_U2_RTSn PIN_CFG(180, ALT_A) | ||
430 | #define GPIO180_U3_TXD PIN_CFG(180, ALT_B) | ||
431 | #define GPIO180_BUSMON_D33 PIN_CFG(180, ALT_C) | ||
432 | |||
433 | #define GPIO185_GPIO PIN_CFG(185, GPIO) | ||
434 | #define GPIO185_SPI3_CS2n PIN_CFG(185, ALT_A) | ||
435 | #define GPIO185_MC4_DAT0 PIN_CFG(185, ALT_B) | ||
436 | |||
437 | #define GPIO186_GPIO PIN_CFG(186, GPIO) | ||
438 | #define GPIO186_SPI3_CS1n PIN_CFG(186, ALT_A) | ||
439 | #define GPIO186_MC4_DAT1 PIN_CFG(186, ALT_B) | ||
440 | |||
441 | #define GPIO187_GPIO PIN_CFG(187, GPIO) | ||
442 | #define GPIO187_SPI3_CS0n PIN_CFG(187, ALT_A) | ||
443 | #define GPIO187_MC4_DAT2 PIN_CFG(187, ALT_B) | ||
444 | |||
445 | #define GPIO188_GPIO PIN_CFG(188, GPIO) | ||
446 | #define GPIO188_SPI3_RXD PIN_CFG(188, ALT_A) | ||
447 | #define GPIO188_MC4_DAT3 PIN_CFG(188, ALT_B) | ||
448 | |||
449 | #define GPIO189_GPIO PIN_CFG(189, GPIO) | ||
450 | #define GPIO189_SPI3_TXD PIN_CFG(189, ALT_A) | ||
451 | #define GPIO189_MC4_CMD PIN_CFG(189, ALT_B) | ||
452 | |||
453 | #define GPIO190_GPIO PIN_CFG(190, GPIO) | ||
454 | #define GPIO190_SPI3_CLK PIN_CFG(190, ALT_A) | ||
455 | #define GPIO190_MC4_CLK PIN_CFG(190, ALT_B) | ||
456 | |||
457 | #define GPIO191_GPIO PIN_CFG(191, GPIO) | ||
458 | #define GPIO191_MC1_DAT0 PIN_CFG(191, ALT_A) | ||
459 | #define GPIO191_MC4_DAT4 PIN_CFG(191, ALT_B) | ||
460 | #define GPIO191_STMAPE_DAT0 PIN_CFG(191, ALT_C) | ||
461 | |||
462 | #define GPIO192_GPIO PIN_CFG(192, GPIO) | ||
463 | #define GPIO192_MC1_DAT1 PIN_CFG(192, ALT_A) | ||
464 | #define GPIO192_MC4_DAT5 PIN_CFG(192, ALT_B) | ||
465 | #define GPIO192_STMAPE_DAT1 PIN_CFG(192, ALT_C) | ||
466 | |||
467 | #define GPIO193_GPIO PIN_CFG(193, GPIO) | ||
468 | #define GPIO193_MC1_DAT2 PIN_CFG(193, ALT_A) | ||
469 | #define GPIO193_MC4_DAT6 PIN_CFG(193, ALT_B) | ||
470 | #define GPIO193_STMAPE_DAT2 PIN_CFG(193, ALT_C) | ||
471 | |||
472 | #define GPIO194_GPIO PIN_CFG(194, GPIO) | ||
473 | #define GPIO194_MC1_DAT3 PIN_CFG(194, ALT_A) | ||
474 | #define GPIO194_MC4_DAT7 PIN_CFG(194, ALT_B) | ||
475 | #define GPIO194_STMAPE_DAT3 PIN_CFG(194, ALT_C) | ||
476 | |||
477 | #define GPIO195_GPIO PIN_CFG(195, GPIO) | ||
478 | #define GPIO195_MC1_CLK PIN_CFG(195, ALT_A) | ||
479 | #define GPIO195_STMAPE_CLK PIN_CFG(195, ALT_B) | ||
480 | #define GPIO195_BUSMON_CLK PIN_CFG(195, ALT_C) | ||
481 | |||
482 | #define GPIO196_GPIO PIN_CFG(196, GPIO) | ||
483 | #define GPIO196_MC1_CMD PIN_CFG(196, ALT_A) | ||
484 | #define GPIO196_U0_RXD PIN_CFG(196, ALT_B) | ||
485 | #define GPIO196_BUSMON_D38 PIN_CFG(196, ALT_C) | ||
486 | |||
487 | #define GPIO197_GPIO PIN_CFG(197, GPIO) | ||
488 | #define GPIO197_MC1_CMDDIR PIN_CFG(197, ALT_A) | ||
489 | #define GPIO197_BUSMON_D39 PIN_CFG(197, ALT_B) | ||
490 | |||
491 | #define GPIO198_GPIO PIN_CFG(198, GPIO) | ||
492 | #define GPIO198_MC1_FBCLK PIN_CFG(198, ALT_A) | ||
493 | |||
494 | #define GPIO199_GPIO PIN_CFG(199, GPIO) | ||
495 | #define GPIO199_MC1_DAT0DIR PIN_CFG(199, ALT_A) | ||
496 | #define GPIO199_BUSMON_D40 PIN_CFG(199, ALT_B) | ||
497 | |||
498 | #define GPIO200_GPIO PIN_CFG(200, GPIO) | ||
499 | #define GPIO200_U1_TXD PIN_CFG(200, ALT_A) | ||
500 | #define GPIO200_ACCU0_RTSn PIN_CFG(200, ALT_B) | ||
501 | |||
502 | #define GPIO201_GPIO PIN_CFG(201, GPIO) | ||
503 | #define GPIO201_U1_RXD PIN_CFG(201, ALT_A) | ||
504 | #define GPIO201_ACCU0_CTSn PIN_CFG(201, ALT_B) | ||
505 | |||
506 | #define GPIO202_GPIO PIN_CFG(202, GPIO) | ||
507 | #define GPIO202_U1_CTSn PIN_CFG(202, ALT_A) | ||
508 | #define GPIO202_ACCU0_RXD PIN_CFG(202, ALT_B) | ||
509 | |||
510 | #define GPIO203_GPIO PIN_CFG(203, GPIO) | ||
511 | #define GPIO203_U1_RTSn PIN_CFG(203, ALT_A) | ||
512 | #define GPIO203_ACCU0_TXD PIN_CFG(203, ALT_B) | ||
513 | |||
514 | #define GPIO204_GPIO PIN_CFG(204, GPIO) | ||
515 | #define GPIO204_SPI0_CS2n PIN_CFG(204, ALT_A) | ||
516 | #define GPIO204_ACCGPIO_000 PIN_CFG(204, ALT_B) | ||
517 | #define GPIO204_LCD_VSI1 PIN_CFG(204, ALT_C) | ||
518 | |||
519 | #define GPIO205_GPIO PIN_CFG(205, GPIO) | ||
520 | #define GPIO205_SPI0_CS1n PIN_CFG(205, ALT_A) | ||
521 | #define GPIO205_ACCGPIO_001 PIN_CFG(205, ALT_B) | ||
522 | #define GPIO205_LCD_D3 PIN_CFG(205, ALT_C) | ||
523 | |||
524 | #define GPIO206_GPIO PIN_CFG(206, GPIO) | ||
525 | #define GPIO206_SPI0_CS0n PIN_CFG(206, ALT_A) | ||
526 | #define GPIO206_ACCGPIO_002 PIN_CFG(206, ALT_B) | ||
527 | #define GPIO206_LCD_D2 PIN_CFG(206, ALT_C) | ||
528 | |||
529 | #define GPIO207_GPIO PIN_CFG(207, GPIO) | ||
530 | #define GPIO207_SPI0_RXD PIN_CFG(207, ALT_A) | ||
531 | #define GPIO207_ACCGPIO_003 PIN_CFG(207, ALT_B) | ||
532 | #define GPIO207_LCD_D1 PIN_CFG(207, ALT_C) | ||
533 | |||
534 | #define GPIO208_GPIO PIN_CFG(208, GPIO) | ||
535 | #define GPIO208_SPI0_TXD PIN_CFG(208, ALT_A) | ||
536 | #define GPIO208_ACCGPIO_004 PIN_CFG(208, ALT_B) | ||
537 | #define GPIO208_LCD_D0 PIN_CFG(208, ALT_C) | ||
538 | |||
539 | #define GPIO209_GPIO PIN_CFG(209, GPIO) | ||
540 | #define GPIO209_SPI0_CLK PIN_CFG(209, ALT_A) | ||
541 | #define GPIO209_ACCGPIO_005 PIN_CFG(209, ALT_B) | ||
542 | #define GPIO209_LCD_CLK PIN_CFG(209, ALT_C) | ||
543 | |||
544 | #define GPIO210_GPIO PIN_CFG(210, GPIO) | ||
545 | #define GPIO210_LCD_VSO PIN_CFG(210, ALT_A) | ||
546 | #define GPIO210_PRCMU_PWRCTRL1 PIN_CFG(210, ALT_B) | ||
547 | |||
548 | #define GPIO211_GPIO PIN_CFG(211, GPIO) | ||
549 | #define GPIO211_LCD_VSI0 PIN_CFG(211, ALT_A) | ||
550 | #define GPIO211_PRCMU_PWRCTRL2 PIN_CFG(211, ALT_B) | ||
551 | |||
552 | #define GPIO212_GPIO PIN_CFG(212, GPIO) | ||
553 | #define GPIO212_SPI2_CS2n PIN_CFG(212, ALT_A) | ||
554 | #define GPIO212_LCD_HSO PIN_CFG(212, ALT_B) | ||
555 | |||
556 | #define GPIO213_GPIO PIN_CFG(213, GPIO) | ||
557 | #define GPIO213_SPI2_CS1n PIN_CFG(213, ALT_A) | ||
558 | #define GPIO213_LCD_DE PIN_CFG(213, ALT_B) | ||
559 | #define GPIO213_BUSMON_D16 PIN_CFG(213, ALT_C) | ||
560 | |||
561 | #define GPIO214_GPIO PIN_CFG(214, GPIO) | ||
562 | #define GPIO214_SPI2_CS0n PIN_CFG(214, ALT_A) | ||
563 | #define GPIO214_LCD_D7 PIN_CFG(214, ALT_B) | ||
564 | #define GPIO214_BUSMON_D17 PIN_CFG(214, ALT_C) | ||
565 | |||
566 | #define GPIO215_GPIO PIN_CFG(215, GPIO) | ||
567 | #define GPIO215_SPI2_RXD PIN_CFG(215, ALT_A) | ||
568 | #define GPIO215_LCD_D6 PIN_CFG(215, ALT_B) | ||
569 | #define GPIO215_BUSMON_D18 PIN_CFG(215, ALT_C) | ||
570 | |||
571 | #define GPIO216_GPIO PIN_CFG(216, GPIO) | ||
572 | #define GPIO216_SPI2_CLK PIN_CFG(216, ALT_A) | ||
573 | #define GPIO216_LCD_D5 PIN_CFG(216, ALT_B) | ||
574 | |||
575 | #define GPIO217_GPIO PIN_CFG(217, GPIO) | ||
576 | #define GPIO217_SPI2_TXD PIN_CFG(217, ALT_A) | ||
577 | #define GPIO217_LCD_D4 PIN_CFG(217, ALT_B) | ||
578 | #define GPIO217_BUSMON_D19 PIN_CFG(217, ALT_C) | ||
579 | |||
580 | #define GPIO218_GPIO PIN_CFG(218, GPIO) | ||
581 | #define GPIO218_I2C2_SCL PIN_CFG(218, ALT_A) | ||
582 | #define GPIO218_LCD_VSO PIN_CFG(218, ALT_B) | ||
583 | |||
584 | #define GPIO219_GPIO PIN_CFG(219, GPIO) | ||
585 | #define GPIO219_I2C2_SDA PIN_CFG(219, ALT_A) | ||
586 | #define GPIO219_LCD_D3 PIN_CFG(219, ALT_B) | ||
587 | |||
588 | #define GPIO220_GPIO PIN_CFG(220, GPIO) | ||
589 | #define GPIO220_MSP2_TCK PIN_CFG(220, ALT_A) | ||
590 | #define GPIO220_LCD_D2 PIN_CFG(220, ALT_B) | ||
591 | |||
592 | #define GPIO221_GPIO PIN_CFG(221, GPIO) | ||
593 | #define GPIO221_MSP2_TFS PIN_CFG(221, ALT_A) | ||
594 | #define GPIO221_LCD_D1 PIN_CFG(221, ALT_B) | ||
595 | |||
596 | #define GPIO222_GPIO PIN_CFG(222, GPIO) | ||
597 | #define GPIO222_MSP2_TXD PIN_CFG(222, ALT_A) | ||
598 | #define GPIO222_LCD_D0 PIN_CFG(222, ALT_B) | ||
599 | |||
600 | #define GPIO223_GPIO PIN_CFG(223, GPIO) | ||
601 | #define GPIO223_MSP2_RXD PIN_CFG(223, ALT_A) | ||
602 | #define GPIO223_LCD_CLK PIN_CFG(223, ALT_B) | ||
603 | |||
604 | #define GPIO224_GPIO PIN_CFG(224, GPIO) | ||
605 | #define GPIO224_PRCMU_PWRCTRL0 PIN_CFG(224, ALT_A) | ||
606 | #define GPIO224_LCD_VSI1 PIN_CFG(224, ALT_B) | ||
607 | |||
608 | #define GPIO225_GPIO PIN_CFG(225, GPIO) | ||
609 | #define GPIO225_PRCMU_PWRCTRL1 PIN_CFG(225, ALT_A) | ||
610 | #define GPIO225_IRDA_RXD PIN_CFG(225, ALT_B) | ||
611 | |||
612 | #define GPIO226_GPIO PIN_CFG(226, GPIO) | ||
613 | #define GPIO226_PRCMU_PWRCTRL2 PIN_CFG(226, ALT_A) | ||
614 | #define GPIO226_IRRC_DAT PIN_CFG(226, ALT_B) | ||
615 | |||
616 | #define GPIO227_GPIO PIN_CFG(227, GPIO) | ||
617 | #define GPIO227_IRRC_DAT PIN_CFG(227, ALT_A) | ||
618 | #define GPIO227_IRDA_TXD PIN_CFG(227, ALT_B) | ||
619 | |||
620 | #endif | ||
diff --git a/arch/arm/mach-ux500/pins-db8500.h b/arch/arm/mach-ux500/pins-db8500.h index 9055d5d3233c..66f8761cc823 100644 --- a/arch/arm/mach-ux500/pins-db8500.h +++ b/arch/arm/mach-ux500/pins-db8500.h | |||
@@ -96,57 +96,57 @@ | |||
96 | #define GPIO17_SLIM0_CLK PIN_CFG(17, ALT_C) | 96 | #define GPIO17_SLIM0_CLK PIN_CFG(17, ALT_C) |
97 | 97 | ||
98 | #define GPIO18_GPIO PIN_CFG(18, GPIO) | 98 | #define GPIO18_GPIO PIN_CFG(18, GPIO) |
99 | #define GPIO18_MC0_CMDDIR PIN_CFG(18, ALT_A) | 99 | #define GPIO18_MC0_CMDDIR PIN_CFG_PULL(18, ALT_A, UP) |
100 | #define GPIO18_U2_RXD PIN_CFG(18, ALT_B) | 100 | #define GPIO18_U2_RXD PIN_CFG(18, ALT_B) |
101 | #define GPIO18_MS_IEP PIN_CFG(18, ALT_C) | 101 | #define GPIO18_MS_IEP PIN_CFG(18, ALT_C) |
102 | 102 | ||
103 | #define GPIO19_GPIO PIN_CFG(19, GPIO) | 103 | #define GPIO19_GPIO PIN_CFG(19, GPIO) |
104 | #define GPIO19_MC0_DAT0DIR PIN_CFG(19, ALT_A) | 104 | #define GPIO19_MC0_DAT0DIR PIN_CFG_PULL(19, ALT_A, UP) |
105 | #define GPIO19_U2_TXD PIN_CFG(19, ALT_B) | 105 | #define GPIO19_U2_TXD PIN_CFG(19, ALT_B) |
106 | #define GPIO19_MS_DAT0DIR PIN_CFG(19, ALT_C) | 106 | #define GPIO19_MS_DAT0DIR PIN_CFG(19, ALT_C) |
107 | 107 | ||
108 | #define GPIO20_GPIO PIN_CFG(20, GPIO) | 108 | #define GPIO20_GPIO PIN_CFG(20, GPIO) |
109 | #define GPIO20_MC0_DAT2DIR PIN_CFG(20, ALT_A) | 109 | #define GPIO20_MC0_DAT2DIR PIN_CFG_PULL(20, ALT_A, UP) |
110 | #define GPIO20_UARTMOD_TXD PIN_CFG(20, ALT_B) | 110 | #define GPIO20_UARTMOD_TXD PIN_CFG(20, ALT_B) |
111 | #define GPIO20_IP_TRIGOUT PIN_CFG(20, ALT_C) | 111 | #define GPIO20_IP_TRIGOUT PIN_CFG(20, ALT_C) |
112 | 112 | ||
113 | #define GPIO21_GPIO PIN_CFG(21, GPIO) | 113 | #define GPIO21_GPIO PIN_CFG(21, GPIO) |
114 | #define GPIO21_MC0_DAT31DIR PIN_CFG(21, ALT_A) | 114 | #define GPIO21_MC0_DAT31DIR PIN_CFG_PULL(21, ALT_A, UP) |
115 | #define GPIO21_MSP0_SCK PIN_CFG(21, ALT_B) | 115 | #define GPIO21_MSP0_SCK PIN_CFG(21, ALT_B) |
116 | #define GPIO21_MS_DAT31DIR PIN_CFG(21, ALT_C) | 116 | #define GPIO21_MS_DAT31DIR PIN_CFG(21, ALT_C) |
117 | 117 | ||
118 | #define GPIO22_GPIO PIN_CFG(22, GPIO) | 118 | #define GPIO22_GPIO PIN_CFG(22, GPIO) |
119 | #define GPIO22_MC0_FBCLK PIN_CFG(22, ALT_A) | 119 | #define GPIO22_MC0_FBCLK PIN_CFG_PULL(22, ALT_A, UP) |
120 | #define GPIO22_UARTMOD_RXD PIN_CFG(22, ALT_B) | 120 | #define GPIO22_UARTMOD_RXD PIN_CFG(22, ALT_B) |
121 | #define GPIO22_MS_FBCLK PIN_CFG(22, ALT_C) | 121 | #define GPIO22_MS_FBCLK PIN_CFG(22, ALT_C) |
122 | 122 | ||
123 | #define GPIO23_GPIO PIN_CFG(23, GPIO) | 123 | #define GPIO23_GPIO PIN_CFG(23, GPIO) |
124 | #define GPIO23_MC0_CLK PIN_CFG(23, ALT_A) | 124 | #define GPIO23_MC0_CLK PIN_CFG_PULL(23, ALT_A, UP) |
125 | #define GPIO23_STMMOD_CLK PIN_CFG(23, ALT_B) | 125 | #define GPIO23_STMMOD_CLK PIN_CFG(23, ALT_B) |
126 | #define GPIO23_MS_CLK PIN_CFG(23, ALT_C) | 126 | #define GPIO23_MS_CLK PIN_CFG(23, ALT_C) |
127 | 127 | ||
128 | #define GPIO24_GPIO PIN_CFG(24, GPIO) | 128 | #define GPIO24_GPIO PIN_CFG(24, GPIO) |
129 | #define GPIO24_MC0_CMD PIN_CFG(24, ALT_A) | 129 | #define GPIO24_MC0_CMD PIN_CFG_PULL(24, ALT_A, UP) |
130 | #define GPIO24_UARTMOD_RXD PIN_CFG(24, ALT_B) | 130 | #define GPIO24_UARTMOD_RXD PIN_CFG(24, ALT_B) |
131 | #define GPIO24_MS_BS PIN_CFG(24, ALT_C) | 131 | #define GPIO24_MS_BS PIN_CFG(24, ALT_C) |
132 | 132 | ||
133 | #define GPIO25_GPIO PIN_CFG(25, GPIO) | 133 | #define GPIO25_GPIO PIN_CFG(25, GPIO) |
134 | #define GPIO25_MC0_DAT0 PIN_CFG(25, ALT_A) | 134 | #define GPIO25_MC0_DAT0 PIN_CFG_PULL(25, ALT_A, UP) |
135 | #define GPIO25_STMMOD_DAT0 PIN_CFG(25, ALT_B) | 135 | #define GPIO25_STMMOD_DAT0 PIN_CFG(25, ALT_B) |
136 | #define GPIO25_MS_DAT0 PIN_CFG(25, ALT_C) | 136 | #define GPIO25_MS_DAT0 PIN_CFG(25, ALT_C) |
137 | 137 | ||
138 | #define GPIO26_GPIO PIN_CFG(26, GPIO) | 138 | #define GPIO26_GPIO PIN_CFG(26, GPIO) |
139 | #define GPIO26_MC0_DAT1 PIN_CFG(26, ALT_A) | 139 | #define GPIO26_MC0_DAT1 PIN_CFG_PULL(26, ALT_A, UP) |
140 | #define GPIO26_STMMOD_DAT1 PIN_CFG(26, ALT_B) | 140 | #define GPIO26_STMMOD_DAT1 PIN_CFG(26, ALT_B) |
141 | #define GPIO26_MS_DAT1 PIN_CFG(26, ALT_C) | 141 | #define GPIO26_MS_DAT1 PIN_CFG(26, ALT_C) |
142 | 142 | ||
143 | #define GPIO27_GPIO PIN_CFG(27, GPIO) | 143 | #define GPIO27_GPIO PIN_CFG(27, GPIO) |
144 | #define GPIO27_MC0_DAT2 PIN_CFG(27, ALT_A) | 144 | #define GPIO27_MC0_DAT2 PIN_CFG_PULL(27, ALT_A, UP) |
145 | #define GPIO27_STMMOD_DAT2 PIN_CFG(27, ALT_B) | 145 | #define GPIO27_STMMOD_DAT2 PIN_CFG(27, ALT_B) |
146 | #define GPIO27_MS_DAT2 PIN_CFG(27, ALT_C) | 146 | #define GPIO27_MS_DAT2 PIN_CFG(27, ALT_C) |
147 | 147 | ||
148 | #define GPIO28_GPIO PIN_CFG(28, GPIO) | 148 | #define GPIO28_GPIO PIN_CFG(28, GPIO) |
149 | #define GPIO28_MC0_DAT3 PIN_CFG(28, ALT_A) | 149 | #define GPIO28_MC0_DAT3 PIN_CFG_PULL(28, ALT_A, UP) |
150 | #define GPIO28_STMMOD_DAT3 PIN_CFG(28, ALT_B) | 150 | #define GPIO28_STMMOD_DAT3 PIN_CFG(28, ALT_B) |
151 | #define GPIO28_MS_DAT3 PIN_CFG(28, ALT_C) | 151 | #define GPIO28_MS_DAT3 PIN_CFG(28, ALT_C) |
152 | 152 | ||
@@ -357,48 +357,48 @@ | |||
357 | #define GPIO97_MC5_DAT7 PIN_CFG(97, ALT_C) | 357 | #define GPIO97_MC5_DAT7 PIN_CFG(97, ALT_C) |
358 | 358 | ||
359 | #define GPIO128_GPIO PIN_CFG(128, GPIO) | 359 | #define GPIO128_GPIO PIN_CFG(128, GPIO) |
360 | #define GPIO128_MC2_CLK PIN_CFG(128, ALT_A) | 360 | #define GPIO128_MC2_CLK PIN_CFG_PULL(128, ALT_A, UP) |
361 | #define GPIO128_SM_CKO PIN_CFG(128, ALT_B) | 361 | #define GPIO128_SM_CKO PIN_CFG(128, ALT_B) |
362 | 362 | ||
363 | #define GPIO129_GPIO PIN_CFG(129, GPIO) | 363 | #define GPIO129_GPIO PIN_CFG(129, GPIO) |
364 | #define GPIO129_MC2_CMD PIN_CFG(129, ALT_A) | 364 | #define GPIO129_MC2_CMD PIN_CFG_PULL(129, ALT_A, UP) |
365 | #define GPIO129_SM_WAIT0n PIN_CFG(129, ALT_B) | 365 | #define GPIO129_SM_WAIT0n PIN_CFG(129, ALT_B) |
366 | 366 | ||
367 | #define GPIO130_GPIO PIN_CFG(130, GPIO) | 367 | #define GPIO130_GPIO PIN_CFG(130, GPIO) |
368 | #define GPIO130_MC2_FBCLK PIN_CFG(130, ALT_A) | 368 | #define GPIO130_MC2_FBCLK PIN_CFG_PULL(130, ALT_A, UP) |
369 | #define GPIO130_SM_FBCLK PIN_CFG(130, ALT_B) | 369 | #define GPIO130_SM_FBCLK PIN_CFG(130, ALT_B) |
370 | #define GPIO130_MC2_RSTN PIN_CFG(130, ALT_C) | 370 | #define GPIO130_MC2_RSTN PIN_CFG(130, ALT_C) |
371 | 371 | ||
372 | #define GPIO131_GPIO PIN_CFG(131, GPIO) | 372 | #define GPIO131_GPIO PIN_CFG(131, GPIO) |
373 | #define GPIO131_MC2_DAT0 PIN_CFG(131, ALT_A) | 373 | #define GPIO131_MC2_DAT0 PIN_CFG_PULL(131, ALT_A, UP) |
374 | #define GPIO131_SM_ADQ8 PIN_CFG(131, ALT_B) | 374 | #define GPIO131_SM_ADQ8 PIN_CFG(131, ALT_B) |
375 | 375 | ||
376 | #define GPIO132_GPIO PIN_CFG(132, GPIO) | 376 | #define GPIO132_GPIO PIN_CFG(132, GPIO) |
377 | #define GPIO132_MC2_DAT1 PIN_CFG(132, ALT_A) | 377 | #define GPIO132_MC2_DAT1 PIN_CFG_PULL(132, ALT_A, UP) |
378 | #define GPIO132_SM_ADQ9 PIN_CFG(132, ALT_B) | 378 | #define GPIO132_SM_ADQ9 PIN_CFG(132, ALT_B) |
379 | 379 | ||
380 | #define GPIO133_GPIO PIN_CFG(133, GPIO) | 380 | #define GPIO133_GPIO PIN_CFG(133, GPIO) |
381 | #define GPIO133_MC2_DAT2 PIN_CFG(133, ALT_A) | 381 | #define GPIO133_MC2_DAT2 PIN_CFG_PULL(133, ALT_A, UP) |
382 | #define GPIO133_SM_ADQ10 PIN_CFG(133, ALT_B) | 382 | #define GPIO133_SM_ADQ10 PIN_CFG(133, ALT_B) |
383 | 383 | ||
384 | #define GPIO134_GPIO PIN_CFG(134, GPIO) | 384 | #define GPIO134_GPIO PIN_CFG(134, GPIO) |
385 | #define GPIO134_MC2_DAT3 PIN_CFG(134, ALT_A) | 385 | #define GPIO134_MC2_DAT3 PIN_CFG_PULL(134, ALT_A, UP) |
386 | #define GPIO134_SM_ADQ11 PIN_CFG(134, ALT_B) | 386 | #define GPIO134_SM_ADQ11 PIN_CFG(134, ALT_B) |
387 | 387 | ||
388 | #define GPIO135_GPIO PIN_CFG(135, GPIO) | 388 | #define GPIO135_GPIO PIN_CFG(135, GPIO) |
389 | #define GPIO135_MC2_DAT4 PIN_CFG(135, ALT_A) | 389 | #define GPIO135_MC2_DAT4 PIN_CFG_PULL(135, ALT_A, UP) |
390 | #define GPIO135_SM_ADQ12 PIN_CFG(135, ALT_B) | 390 | #define GPIO135_SM_ADQ12 PIN_CFG(135, ALT_B) |
391 | 391 | ||
392 | #define GPIO136_GPIO PIN_CFG(136, GPIO) | 392 | #define GPIO136_GPIO PIN_CFG(136, GPIO) |
393 | #define GPIO136_MC2_DAT5 PIN_CFG(136, ALT_A) | 393 | #define GPIO136_MC2_DAT5 PIN_CFG_PULL(136, ALT_A, UP) |
394 | #define GPIO136_SM_ADQ13 PIN_CFG(136, ALT_B) | 394 | #define GPIO136_SM_ADQ13 PIN_CFG(136, ALT_B) |
395 | 395 | ||
396 | #define GPIO137_GPIO PIN_CFG(137, GPIO) | 396 | #define GPIO137_GPIO PIN_CFG(137, GPIO) |
397 | #define GPIO137_MC2_DAT6 PIN_CFG(137, ALT_A) | 397 | #define GPIO137_MC2_DAT6 PIN_CFG_PULL(137, ALT_A, UP) |
398 | #define GPIO137_SM_ADQ14 PIN_CFG(137, ALT_B) | 398 | #define GPIO137_SM_ADQ14 PIN_CFG(137, ALT_B) |
399 | 399 | ||
400 | #define GPIO138_GPIO PIN_CFG(138, GPIO) | 400 | #define GPIO138_GPIO PIN_CFG(138, GPIO) |
401 | #define GPIO138_MC2_DAT7 PIN_CFG(138, ALT_A) | 401 | #define GPIO138_MC2_DAT7 PIN_CFG_PULL(138, ALT_A, UP) |
402 | #define GPIO138_SM_ADQ15 PIN_CFG(138, ALT_B) | 402 | #define GPIO138_SM_ADQ15 PIN_CFG(138, ALT_B) |
403 | 403 | ||
404 | #define GPIO139_GPIO PIN_CFG(139, GPIO) | 404 | #define GPIO139_GPIO PIN_CFG(139, GPIO) |
@@ -569,39 +569,39 @@ | |||
569 | #define GPIO196_MSP2_RXD PIN_CFG(196, ALT_A) | 569 | #define GPIO196_MSP2_RXD PIN_CFG(196, ALT_A) |
570 | 570 | ||
571 | #define GPIO197_GPIO PIN_CFG(197, GPIO) | 571 | #define GPIO197_GPIO PIN_CFG(197, GPIO) |
572 | #define GPIO197_MC4_DAT3 PIN_CFG(197, ALT_A) | 572 | #define GPIO197_MC4_DAT3 PIN_CFG_PULL(197, ALT_A, UP) |
573 | 573 | ||
574 | #define GPIO198_GPIO PIN_CFG(198, GPIO) | 574 | #define GPIO198_GPIO PIN_CFG(198, GPIO) |
575 | #define GPIO198_MC4_DAT2 PIN_CFG(198, ALT_A) | 575 | #define GPIO198_MC4_DAT2 PIN_CFG_PULL(198, ALT_A, UP) |
576 | 576 | ||
577 | #define GPIO199_GPIO PIN_CFG(199, GPIO) | 577 | #define GPIO199_GPIO PIN_CFG(199, GPIO) |
578 | #define GPIO199_MC4_DAT1 PIN_CFG(199, ALT_A) | 578 | #define GPIO199_MC4_DAT1 PIN_CFG_PULL(199, ALT_A, UP) |
579 | 579 | ||
580 | #define GPIO200_GPIO PIN_CFG(200, GPIO) | 580 | #define GPIO200_GPIO PIN_CFG(200, GPIO) |
581 | #define GPIO200_MC4_DAT0 PIN_CFG(200, ALT_A) | 581 | #define GPIO200_MC4_DAT0 PIN_CFG_PULL(200, ALT_A, UP) |
582 | 582 | ||
583 | #define GPIO201_GPIO PIN_CFG(201, GPIO) | 583 | #define GPIO201_GPIO PIN_CFG(201, GPIO) |
584 | #define GPIO201_MC4_CMD PIN_CFG(201, ALT_A) | 584 | #define GPIO201_MC4_CMD PIN_CFG_PULL(201, ALT_A, UP) |
585 | 585 | ||
586 | #define GPIO202_GPIO PIN_CFG(202, GPIO) | 586 | #define GPIO202_GPIO PIN_CFG(202, GPIO) |
587 | #define GPIO202_MC4_FBCLK PIN_CFG(202, ALT_A) | 587 | #define GPIO202_MC4_FBCLK PIN_CFG_PULL(202, ALT_A, UP) |
588 | #define GPIO202_PWL PIN_CFG(202, ALT_B) | 588 | #define GPIO202_PWL PIN_CFG(202, ALT_B) |
589 | #define GPIO202_MC4_RSTN PIN_CFG(202, ALT_C) | 589 | #define GPIO202_MC4_RSTN PIN_CFG(202, ALT_C) |
590 | 590 | ||
591 | #define GPIO203_GPIO PIN_CFG(203, GPIO) | 591 | #define GPIO203_GPIO PIN_CFG(203, GPIO) |
592 | #define GPIO203_MC4_CLK PIN_CFG(203, ALT_A) | 592 | #define GPIO203_MC4_CLK PIN_CFG_PULL(203, ALT_A, UP) |
593 | 593 | ||
594 | #define GPIO204_GPIO PIN_CFG(204, GPIO) | 594 | #define GPIO204_GPIO PIN_CFG(204, GPIO) |
595 | #define GPIO204_MC4_DAT7 PIN_CFG(204, ALT_A) | 595 | #define GPIO204_MC4_DAT7 PIN_CFG_PULL(204, ALT_A, UP) |
596 | 596 | ||
597 | #define GPIO205_GPIO PIN_CFG(205, GPIO) | 597 | #define GPIO205_GPIO PIN_CFG(205, GPIO) |
598 | #define GPIO205_MC4_DAT6 PIN_CFG(205, ALT_A) | 598 | #define GPIO205_MC4_DAT6 PIN_CFG_PULL(205, ALT_A, UP) |
599 | 599 | ||
600 | #define GPIO206_GPIO PIN_CFG(206, GPIO) | 600 | #define GPIO206_GPIO PIN_CFG(206, GPIO) |
601 | #define GPIO206_MC4_DAT5 PIN_CFG(206, ALT_A) | 601 | #define GPIO206_MC4_DAT5 PIN_CFG_PULL(206, ALT_A, UP) |
602 | 602 | ||
603 | #define GPIO207_GPIO PIN_CFG(207, GPIO) | 603 | #define GPIO207_GPIO PIN_CFG(207, GPIO) |
604 | #define GPIO207_MC4_DAT4 PIN_CFG(207, ALT_A) | 604 | #define GPIO207_MC4_DAT4 PIN_CFG_PULL(207, ALT_A, UP) |
605 | 605 | ||
606 | #define GPIO208_GPIO PIN_CFG(208, GPIO) | 606 | #define GPIO208_GPIO PIN_CFG(208, GPIO) |
607 | #define GPIO208_MC1_CLK PIN_CFG(208, ALT_A) | 607 | #define GPIO208_MC1_CLK PIN_CFG(208, ALT_A) |
diff --git a/arch/arm/mach-ux500/platsmp.c b/arch/arm/mach-ux500/platsmp.c index 438ef16aec90..9e4c678de785 100644 --- a/arch/arm/mach-ux500/platsmp.c +++ b/arch/arm/mach-ux500/platsmp.c | |||
@@ -78,6 +78,8 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) | |||
78 | __cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release)); | 78 | __cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release)); |
79 | outer_clean_range(__pa(&pen_release), __pa(&pen_release) + 1); | 79 | outer_clean_range(__pa(&pen_release), __pa(&pen_release) + 1); |
80 | 80 | ||
81 | smp_cross_call(cpumask_of(cpu)); | ||
82 | |||
81 | timeout = jiffies + (1 * HZ); | 83 | timeout = jiffies + (1 * HZ); |
82 | while (time_before(jiffies, timeout)) { | 84 | while (time_before(jiffies, timeout)) { |
83 | if (pen_release == -1) | 85 | if (pen_release == -1) |
diff --git a/arch/arm/mach-ux500/prcmu.c b/arch/arm/mach-ux500/prcmu.c new file mode 100644 index 000000000000..293274d1342a --- /dev/null +++ b/arch/arm/mach-ux500/prcmu.c | |||
@@ -0,0 +1,231 @@ | |||
1 | /* | ||
2 | * Copyright (C) ST Ericsson SA 2010 | ||
3 | * | ||
4 | * License Terms: GNU General Public License v2 | ||
5 | * Author: Mattias Nilsson <mattias.i.nilsson@stericsson.com> | ||
6 | * | ||
7 | * U8500 PRCMU driver. | ||
8 | */ | ||
9 | #include <linux/kernel.h> | ||
10 | #include <linux/module.h> | ||
11 | #include <linux/errno.h> | ||
12 | #include <linux/err.h> | ||
13 | #include <linux/io.h> | ||
14 | #include <linux/mutex.h> | ||
15 | #include <linux/completion.h> | ||
16 | #include <linux/jiffies.h> | ||
17 | #include <linux/bitops.h> | ||
18 | #include <linux/interrupt.h> | ||
19 | |||
20 | #include <mach/hardware.h> | ||
21 | #include <mach/prcmu-regs.h> | ||
22 | |||
23 | #define PRCMU_TCDM_BASE __io_address(U8500_PRCMU_TCDM_BASE) | ||
24 | |||
25 | #define REQ_MB5 (PRCMU_TCDM_BASE + 0xE44) | ||
26 | #define ACK_MB5 (PRCMU_TCDM_BASE + 0xDF4) | ||
27 | |||
28 | #define REQ_MB5_I2C_SLAVE_OP (REQ_MB5) | ||
29 | #define REQ_MB5_I2C_HW_BITS (REQ_MB5 + 1) | ||
30 | #define REQ_MB5_I2C_REG (REQ_MB5 + 2) | ||
31 | #define REQ_MB5_I2C_VAL (REQ_MB5 + 3) | ||
32 | |||
33 | #define ACK_MB5_I2C_STATUS (ACK_MB5 + 1) | ||
34 | #define ACK_MB5_I2C_VAL (ACK_MB5 + 3) | ||
35 | |||
36 | #define I2C_WRITE(slave) ((slave) << 1) | ||
37 | #define I2C_READ(slave) (((slave) << 1) | BIT(0)) | ||
38 | #define I2C_STOP_EN BIT(3) | ||
39 | |||
40 | enum ack_mb5_status { | ||
41 | I2C_WR_OK = 0x01, | ||
42 | I2C_RD_OK = 0x02, | ||
43 | }; | ||
44 | |||
45 | #define MBOX_BIT BIT | ||
46 | #define NUM_MBOX 8 | ||
47 | |||
48 | static struct { | ||
49 | struct mutex lock; | ||
50 | struct completion work; | ||
51 | bool failed; | ||
52 | struct { | ||
53 | u8 status; | ||
54 | u8 value; | ||
55 | } ack; | ||
56 | } mb5_transfer; | ||
57 | |||
58 | /** | ||
59 | * prcmu_abb_read() - Read register value(s) from the ABB. | ||
60 | * @slave: The I2C slave address. | ||
61 | * @reg: The (start) register address. | ||
62 | * @value: The read out value(s). | ||
63 | * @size: The number of registers to read. | ||
64 | * | ||
65 | * Reads register value(s) from the ABB. | ||
66 | * @size has to be 1 for the current firmware version. | ||
67 | */ | ||
68 | int prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size) | ||
69 | { | ||
70 | int r; | ||
71 | |||
72 | if (size != 1) | ||
73 | return -EINVAL; | ||
74 | |||
75 | r = mutex_lock_interruptible(&mb5_transfer.lock); | ||
76 | if (r) | ||
77 | return r; | ||
78 | |||
79 | while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(5)) | ||
80 | cpu_relax(); | ||
81 | |||
82 | writeb(I2C_READ(slave), REQ_MB5_I2C_SLAVE_OP); | ||
83 | writeb(I2C_STOP_EN, REQ_MB5_I2C_HW_BITS); | ||
84 | writeb(reg, REQ_MB5_I2C_REG); | ||
85 | |||
86 | writel(MBOX_BIT(5), PRCM_MBOX_CPU_SET); | ||
87 | if (!wait_for_completion_timeout(&mb5_transfer.work, | ||
88 | msecs_to_jiffies(500))) { | ||
89 | pr_err("prcmu: prcmu_abb_read timed out.\n"); | ||
90 | r = -EIO; | ||
91 | goto unlock_and_return; | ||
92 | } | ||
93 | r = ((mb5_transfer.ack.status == I2C_RD_OK) ? 0 : -EIO); | ||
94 | if (!r) | ||
95 | *value = mb5_transfer.ack.value; | ||
96 | |||
97 | unlock_and_return: | ||
98 | mutex_unlock(&mb5_transfer.lock); | ||
99 | return r; | ||
100 | } | ||
101 | EXPORT_SYMBOL(prcmu_abb_read); | ||
102 | |||
103 | /** | ||
104 | * prcmu_abb_write() - Write register value(s) to the ABB. | ||
105 | * @slave: The I2C slave address. | ||
106 | * @reg: The (start) register address. | ||
107 | * @value: The value(s) to write. | ||
108 | * @size: The number of registers to write. | ||
109 | * | ||
110 | * Reads register value(s) from the ABB. | ||
111 | * @size has to be 1 for the current firmware version. | ||
112 | */ | ||
113 | int prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size) | ||
114 | { | ||
115 | int r; | ||
116 | |||
117 | if (size != 1) | ||
118 | return -EINVAL; | ||
119 | |||
120 | r = mutex_lock_interruptible(&mb5_transfer.lock); | ||
121 | if (r) | ||
122 | return r; | ||
123 | |||
124 | |||
125 | while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(5)) | ||
126 | cpu_relax(); | ||
127 | |||
128 | writeb(I2C_WRITE(slave), REQ_MB5_I2C_SLAVE_OP); | ||
129 | writeb(I2C_STOP_EN, REQ_MB5_I2C_HW_BITS); | ||
130 | writeb(reg, REQ_MB5_I2C_REG); | ||
131 | writeb(*value, REQ_MB5_I2C_VAL); | ||
132 | |||
133 | writel(MBOX_BIT(5), PRCM_MBOX_CPU_SET); | ||
134 | if (!wait_for_completion_timeout(&mb5_transfer.work, | ||
135 | msecs_to_jiffies(500))) { | ||
136 | pr_err("prcmu: prcmu_abb_write timed out.\n"); | ||
137 | r = -EIO; | ||
138 | goto unlock_and_return; | ||
139 | } | ||
140 | r = ((mb5_transfer.ack.status == I2C_WR_OK) ? 0 : -EIO); | ||
141 | |||
142 | unlock_and_return: | ||
143 | mutex_unlock(&mb5_transfer.lock); | ||
144 | return r; | ||
145 | } | ||
146 | EXPORT_SYMBOL(prcmu_abb_write); | ||
147 | |||
148 | static void read_mailbox_0(void) | ||
149 | { | ||
150 | writel(MBOX_BIT(0), PRCM_ARM_IT1_CLEAR); | ||
151 | } | ||
152 | |||
153 | static void read_mailbox_1(void) | ||
154 | { | ||
155 | writel(MBOX_BIT(1), PRCM_ARM_IT1_CLEAR); | ||
156 | } | ||
157 | |||
158 | static void read_mailbox_2(void) | ||
159 | { | ||
160 | writel(MBOX_BIT(2), PRCM_ARM_IT1_CLEAR); | ||
161 | } | ||
162 | |||
163 | static void read_mailbox_3(void) | ||
164 | { | ||
165 | writel(MBOX_BIT(3), PRCM_ARM_IT1_CLEAR); | ||
166 | } | ||
167 | |||
168 | static void read_mailbox_4(void) | ||
169 | { | ||
170 | writel(MBOX_BIT(4), PRCM_ARM_IT1_CLEAR); | ||
171 | } | ||
172 | |||
173 | static void read_mailbox_5(void) | ||
174 | { | ||
175 | mb5_transfer.ack.status = readb(ACK_MB5_I2C_STATUS); | ||
176 | mb5_transfer.ack.value = readb(ACK_MB5_I2C_VAL); | ||
177 | complete(&mb5_transfer.work); | ||
178 | writel(MBOX_BIT(5), PRCM_ARM_IT1_CLEAR); | ||
179 | } | ||
180 | |||
181 | static void read_mailbox_6(void) | ||
182 | { | ||
183 | writel(MBOX_BIT(6), PRCM_ARM_IT1_CLEAR); | ||
184 | } | ||
185 | |||
186 | static void read_mailbox_7(void) | ||
187 | { | ||
188 | writel(MBOX_BIT(7), PRCM_ARM_IT1_CLEAR); | ||
189 | } | ||
190 | |||
191 | static void (* const read_mailbox[NUM_MBOX])(void) = { | ||
192 | read_mailbox_0, | ||
193 | read_mailbox_1, | ||
194 | read_mailbox_2, | ||
195 | read_mailbox_3, | ||
196 | read_mailbox_4, | ||
197 | read_mailbox_5, | ||
198 | read_mailbox_6, | ||
199 | read_mailbox_7 | ||
200 | }; | ||
201 | |||
202 | static irqreturn_t prcmu_irq_handler(int irq, void *data) | ||
203 | { | ||
204 | u32 bits; | ||
205 | u8 n; | ||
206 | |||
207 | bits = (readl(PRCM_ARM_IT1_VAL) & (MBOX_BIT(NUM_MBOX) - 1)); | ||
208 | if (unlikely(!bits)) | ||
209 | return IRQ_NONE; | ||
210 | |||
211 | for (n = 0; bits; n++) { | ||
212 | if (bits & MBOX_BIT(n)) { | ||
213 | bits -= MBOX_BIT(n); | ||
214 | read_mailbox[n](); | ||
215 | } | ||
216 | } | ||
217 | return IRQ_HANDLED; | ||
218 | } | ||
219 | |||
220 | static int __init prcmu_init(void) | ||
221 | { | ||
222 | mutex_init(&mb5_transfer.lock); | ||
223 | init_completion(&mb5_transfer.work); | ||
224 | |||
225 | /* Clean up the mailbox interrupts after pre-kernel code. */ | ||
226 | writel((MBOX_BIT(NUM_MBOX) - 1), PRCM_ARM_IT1_CLEAR); | ||
227 | |||
228 | return request_irq(IRQ_PRCMU, prcmu_irq_handler, 0, "prcmu", NULL); | ||
229 | } | ||
230 | |||
231 | arch_initcall(prcmu_init); | ||
diff --git a/arch/arm/mach-ux500/ste-dma40-db5500.h b/arch/arm/mach-ux500/ste-dma40-db5500.h new file mode 100644 index 000000000000..cb2110c32858 --- /dev/null +++ b/arch/arm/mach-ux500/ste-dma40-db5500.h | |||
@@ -0,0 +1,135 @@ | |||
1 | /* | ||
2 | * Copyright (C) ST-Ericsson SA 2010 | ||
3 | * | ||
4 | * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson | ||
5 | * License terms: GNU General Public License (GPL) version 2 | ||
6 | * | ||
7 | * DB5500-SoC-specific configuration for DMA40 | ||
8 | */ | ||
9 | |||
10 | #ifndef STE_DMA40_DB5500_H | ||
11 | #define STE_DMA40_DB5500_H | ||
12 | |||
13 | #define DB5500_DMA_NR_DEV 64 | ||
14 | |||
15 | enum dma_src_dev_type { | ||
16 | DB5500_DMA_DEV0_SPI0_RX = 0, | ||
17 | DB5500_DMA_DEV1_SPI1_RX = 1, | ||
18 | DB5500_DMA_DEV2_SPI2_RX = 2, | ||
19 | DB5500_DMA_DEV3_SPI3_RX = 3, | ||
20 | DB5500_DMA_DEV4_USB_OTG_IEP_1_9 = 4, | ||
21 | DB5500_DMA_DEV5_USB_OTG_IEP_2_10 = 5, | ||
22 | DB5500_DMA_DEV6_USB_OTG_IEP_3_11 = 6, | ||
23 | DB5500_DMA_DEV7_IRDA_RFS = 7, | ||
24 | DB5500_DMA_DEV8_IRDA_FIFO_RX = 8, | ||
25 | DB5500_DMA_DEV9_MSP0_RX = 9, | ||
26 | DB5500_DMA_DEV10_MSP1_RX = 10, | ||
27 | DB5500_DMA_DEV11_MSP2_RX = 11, | ||
28 | DB5500_DMA_DEV12_UART0_RX = 12, | ||
29 | DB5500_DMA_DEV13_UART1_RX = 13, | ||
30 | DB5500_DMA_DEV14_UART2_RX = 14, | ||
31 | DB5500_DMA_DEV15_UART3_RX = 15, | ||
32 | DB5500_DMA_DEV16_USB_OTG_IEP_8 = 16, | ||
33 | DB5500_DMA_DEV17_USB_OTG_IEP_1_9 = 17, | ||
34 | DB5500_DMA_DEV18_USB_OTG_IEP_2_10 = 18, | ||
35 | DB5500_DMA_DEV19_USB_OTG_IEP_3_11 = 19, | ||
36 | DB5500_DMA_DEV20_USB_OTG_IEP_4_12 = 20, | ||
37 | DB5500_DMA_DEV21_USB_OTG_IEP_5_13 = 21, | ||
38 | DB5500_DMA_DEV22_USB_OTG_IEP_6_14 = 22, | ||
39 | DB5500_DMA_DEV23_USB_OTG_IEP_7_15 = 23, | ||
40 | DB5500_DMA_DEV24_SDMMC0_RX = 24, | ||
41 | DB5500_DMA_DEV25_SDMMC1_RX = 25, | ||
42 | DB5500_DMA_DEV26_SDMMC2_RX = 26, | ||
43 | DB5500_DMA_DEV27_SDMMC3_RX = 27, | ||
44 | DB5500_DMA_DEV28_SDMMC4_RX = 28, | ||
45 | /* 29 - 32 not used */ | ||
46 | DB5500_DMA_DEV33_SDMMC0_RX = 33, | ||
47 | DB5500_DMA_DEV34_SDMMC1_RX = 34, | ||
48 | DB5500_DMA_DEV35_SDMMC2_RX = 35, | ||
49 | DB5500_DMA_DEV36_SDMMC3_RX = 36, | ||
50 | DB5500_DMA_DEV37_SDMMC4_RX = 37, | ||
51 | DB5500_DMA_DEV38_USB_OTG_IEP_8 = 38, | ||
52 | DB5500_DMA_DEV39_USB_OTG_IEP_1_9 = 39, | ||
53 | DB5500_DMA_DEV40_USB_OTG_IEP_2_10 = 40, | ||
54 | DB5500_DMA_DEV41_USB_OTG_IEP_3_11 = 41, | ||
55 | DB5500_DMA_DEV42_USB_OTG_IEP_4_12 = 42, | ||
56 | DB5500_DMA_DEV43_USB_OTG_IEP_5_13 = 43, | ||
57 | DB5500_DMA_DEV44_USB_OTG_IEP_6_14 = 44, | ||
58 | DB5500_DMA_DEV45_USB_OTG_IEP_7_15 = 45, | ||
59 | /* 46 not used */ | ||
60 | DB5500_DMA_DEV47_MCDE_RX = 47, | ||
61 | DB5500_DMA_DEV48_CRYPTO1_RX = 48, | ||
62 | /* 49, 50 not used */ | ||
63 | DB5500_DMA_DEV49_I2C1_RX = 51, | ||
64 | DB5500_DMA_DEV50_I2C3_RX = 52, | ||
65 | DB5500_DMA_DEV51_I2C2_RX = 53, | ||
66 | /* 54 - 60 not used */ | ||
67 | DB5500_DMA_DEV61_CRYPTO0_RX = 61, | ||
68 | /* 62, 63 not used */ | ||
69 | }; | ||
70 | |||
71 | enum dma_dest_dev_type { | ||
72 | DB5500_DMA_DEV0_SPI0_TX = 0, | ||
73 | DB5500_DMA_DEV1_SPI1_TX = 1, | ||
74 | DB5500_DMA_DEV2_SPI2_TX = 2, | ||
75 | DB5500_DMA_DEV3_SPI3_TX = 3, | ||
76 | DB5500_DMA_DEV4_USB_OTG_OEP_1_9 = 4, | ||
77 | DB5500_DMA_DEV5_USB_OTG_OEP_2_10 = 5, | ||
78 | DB5500_DMA_DEV6_USB_OTG_OEP_3_11 = 6, | ||
79 | DB5500_DMA_DEV7_IRRC_TX = 7, | ||
80 | DB5500_DMA_DEV8_IRDA_FIFO_TX = 8, | ||
81 | DB5500_DMA_DEV9_MSP0_TX = 9, | ||
82 | DB5500_DMA_DEV10_MSP1_TX = 10, | ||
83 | DB5500_DMA_DEV11_MSP2_TX = 11, | ||
84 | DB5500_DMA_DEV12_UART0_TX = 12, | ||
85 | DB5500_DMA_DEV13_UART1_TX = 13, | ||
86 | DB5500_DMA_DEV14_UART2_TX = 14, | ||
87 | DB5500_DMA_DEV15_UART3_TX = 15, | ||
88 | DB5500_DMA_DEV16_USB_OTG_OEP_8 = 16, | ||
89 | DB5500_DMA_DEV17_USB_OTG_OEP_1_9 = 17, | ||
90 | DB5500_DMA_DEV18_USB_OTG_OEP_2_10 = 18, | ||
91 | DB5500_DMA_DEV19_USB_OTG_OEP_3_11 = 19, | ||
92 | DB5500_DMA_DEV20_USB_OTG_OEP_4_12 = 20, | ||
93 | DB5500_DMA_DEV21_USB_OTG_OEP_5_13 = 21, | ||
94 | DB5500_DMA_DEV22_USB_OTG_OEP_6_14 = 22, | ||
95 | DB5500_DMA_DEV23_USB_OTG_OEP_7_15 = 23, | ||
96 | DB5500_DMA_DEV24_SDMMC0_TX = 24, | ||
97 | DB5500_DMA_DEV25_SDMMC1_TX = 25, | ||
98 | DB5500_DMA_DEV26_SDMMC2_TX = 26, | ||
99 | DB5500_DMA_DEV27_SDMMC3_TX = 27, | ||
100 | DB5500_DMA_DEV28_SDMMC4_TX = 28, | ||
101 | /* 29 - 31 not used */ | ||
102 | DB5500_DMA_DEV32_FSMC_TX = 32, | ||
103 | DB5500_DMA_DEV33_SDMMC0_TX = 33, | ||
104 | DB5500_DMA_DEV34_SDMMC1_TX = 34, | ||
105 | DB5500_DMA_DEV35_SDMMC2_TX = 35, | ||
106 | DB5500_DMA_DEV36_SDMMC3_TX = 36, | ||
107 | DB5500_DMA_DEV37_SDMMC4_TX = 37, | ||
108 | DB5500_DMA_DEV38_USB_OTG_OEP_8 = 38, | ||
109 | DB5500_DMA_DEV39_USB_OTG_OEP_1_9 = 39, | ||
110 | DB5500_DMA_DEV40_USB_OTG_OEP_2_10 = 40, | ||
111 | DB5500_DMA_DEV41_USB_OTG_OEP_3_11 = 41, | ||
112 | DB5500_DMA_DEV42_USB_OTG_OEP_4_12 = 42, | ||
113 | DB5500_DMA_DEV43_USB_OTG_OEP_5_13 = 43, | ||
114 | DB5500_DMA_DEV44_USB_OTG_OEP_6_14 = 44, | ||
115 | DB5500_DMA_DEV45_USB_OTG_OEP_7_15 = 45, | ||
116 | /* 46 not used */ | ||
117 | DB5500_DMA_DEV47_STM_TX = 47, | ||
118 | DB5500_DMA_DEV48_CRYPTO1_TX = 48, | ||
119 | DB5500_DMA_DEV49_CRYPTO1_TX_HASH1_TX = 49, | ||
120 | DB5500_DMA_DEV50_HASH1_TX = 50, | ||
121 | DB5500_DMA_DEV51_I2C1_TX = 51, | ||
122 | DB5500_DMA_DEV52_I2C3_TX = 52, | ||
123 | DB5500_DMA_DEV53_I2C2_TX = 53, | ||
124 | /* 54, 55 not used */ | ||
125 | DB5500_DMA_MEMCPY_TX_1 = 56, | ||
126 | DB5500_DMA_MEMCPY_TX_2 = 57, | ||
127 | DB5500_DMA_MEMCPY_TX_3 = 58, | ||
128 | DB5500_DMA_MEMCPY_TX_4 = 59, | ||
129 | DB5500_DMA_MEMCPY_TX_5 = 60, | ||
130 | DB5500_DMA_DEV61_CRYPTO0_TX = 61, | ||
131 | DB5500_DMA_DEV62_CRYPTO0_TX_HASH0_TX = 62, | ||
132 | DB5500_DMA_DEV63_HASH0_TX = 63, | ||
133 | }; | ||
134 | |||
135 | #endif | ||
diff --git a/arch/arm/mach-ux500/ste-dma40-db8500.h b/arch/arm/mach-ux500/ste-dma40-db8500.h index 9d9d3797b3b0..a616419bea76 100644 --- a/arch/arm/mach-ux500/ste-dma40-db8500.h +++ b/arch/arm/mach-ux500/ste-dma40-db8500.h | |||
@@ -10,145 +10,135 @@ | |||
10 | #ifndef STE_DMA40_DB8500_H | 10 | #ifndef STE_DMA40_DB8500_H |
11 | #define STE_DMA40_DB8500_H | 11 | #define STE_DMA40_DB8500_H |
12 | 12 | ||
13 | #define STEDMA40_NR_DEV 64 | 13 | #define DB8500_DMA_NR_DEV 64 |
14 | 14 | ||
15 | enum dma_src_dev_type { | 15 | enum dma_src_dev_type { |
16 | STEDMA40_DEV_SPI0_RX = 0, | 16 | DB8500_DMA_DEV0_SPI0_RX = 0, |
17 | STEDMA40_DEV_SD_MMC0_RX = 1, | 17 | DB8500_DMA_DEV1_SD_MMC0_RX = 1, |
18 | STEDMA40_DEV_SD_MMC1_RX = 2, | 18 | DB8500_DMA_DEV2_SD_MMC1_RX = 2, |
19 | STEDMA40_DEV_SD_MMC2_RX = 3, | 19 | DB8500_DMA_DEV3_SD_MMC2_RX = 3, |
20 | STEDMA40_DEV_I2C1_RX = 4, | 20 | DB8500_DMA_DEV4_I2C1_RX = 4, |
21 | STEDMA40_DEV_I2C3_RX = 5, | 21 | DB8500_DMA_DEV5_I2C3_RX = 5, |
22 | STEDMA40_DEV_I2C2_RX = 6, | 22 | DB8500_DMA_DEV6_I2C2_RX = 6, |
23 | STEDMA40_DEV_I2C4_RX = 7, /* Only on V1 */ | 23 | DB8500_DMA_DEV7_I2C4_RX = 7, /* Only on V1 and later */ |
24 | STEDMA40_DEV_SSP0_RX = 8, | 24 | DB8500_DMA_DEV8_SSP0_RX = 8, |
25 | STEDMA40_DEV_SSP1_RX = 9, | 25 | DB8500_DMA_DEV9_SSP1_RX = 9, |
26 | STEDMA40_DEV_MCDE_RX = 10, | 26 | DB8500_DMA_DEV10_MCDE_RX = 10, |
27 | STEDMA40_DEV_UART2_RX = 11, | 27 | DB8500_DMA_DEV11_UART2_RX = 11, |
28 | STEDMA40_DEV_UART1_RX = 12, | 28 | DB8500_DMA_DEV12_UART1_RX = 12, |
29 | STEDMA40_DEV_UART0_RX = 13, | 29 | DB8500_DMA_DEV13_UART0_RX = 13, |
30 | STEDMA40_DEV_MSP2_RX = 14, | 30 | DB8500_DMA_DEV14_MSP2_RX = 14, |
31 | STEDMA40_DEV_I2C0_RX = 15, | 31 | DB8500_DMA_DEV15_I2C0_RX = 15, |
32 | STEDMA40_DEV_USB_OTG_IEP_8 = 16, | 32 | DB8500_DMA_DEV16_USB_OTG_IEP_7_15 = 16, |
33 | STEDMA40_DEV_USB_OTG_IEP_1_9 = 17, | 33 | DB8500_DMA_DEV17_USB_OTG_IEP_6_14 = 17, |
34 | STEDMA40_DEV_USB_OTG_IEP_2_10 = 18, | 34 | DB8500_DMA_DEV18_USB_OTG_IEP_5_13 = 18, |
35 | STEDMA40_DEV_USB_OTG_IEP_3_11 = 19, | 35 | DB8500_DMA_DEV19_USB_OTG_IEP_4_12 = 19, |
36 | STEDMA40_DEV_SLIM0_CH0_RX_HSI_RX_CH0 = 20, | 36 | DB8500_DMA_DEV20_SLIM0_CH0_RX_HSI_RX_CH0 = 20, |
37 | STEDMA40_DEV_SLIM0_CH1_RX_HSI_RX_CH1 = 21, | 37 | DB8500_DMA_DEV21_SLIM0_CH1_RX_HSI_RX_CH1 = 21, |
38 | STEDMA40_DEV_SLIM0_CH2_RX_HSI_RX_CH2 = 22, | 38 | DB8500_DMA_DEV22_SLIM0_CH2_RX_HSI_RX_CH2 = 22, |
39 | STEDMA40_DEV_SLIM0_CH3_RX_HSI_RX_CH3 = 23, | 39 | DB8500_DMA_DEV23_SLIM0_CH3_RX_HSI_RX_CH3 = 23, |
40 | STEDMA40_DEV_SRC_SXA0_RX_TX = 24, | 40 | DB8500_DMA_DEV24_SRC_SXA0_RX_TX = 24, |
41 | STEDMA40_DEV_SRC_SXA1_RX_TX = 25, | 41 | DB8500_DMA_DEV25_SRC_SXA1_RX_TX = 25, |
42 | STEDMA40_DEV_SRC_SXA2_RX_TX = 26, | 42 | DB8500_DMA_DEV26_SRC_SXA2_RX_TX = 26, |
43 | STEDMA40_DEV_SRC_SXA3_RX_TX = 27, | 43 | DB8500_DMA_DEV27_SRC_SXA3_RX_TX = 27, |
44 | STEDMA40_DEV_SD_MM2_RX = 28, | 44 | DB8500_DMA_DEV28_SD_MM2_RX = 28, |
45 | STEDMA40_DEV_SD_MM0_RX = 29, | 45 | DB8500_DMA_DEV29_SD_MM0_RX = 29, |
46 | STEDMA40_DEV_MSP1_RX = 30, | 46 | DB8500_DMA_DEV30_MSP1_RX = 30, |
47 | /* | 47 | /* On DB8500v2, MSP3 RX replaces MSP1 RX */ |
48 | * This channel is either SlimBus or MSP, | 48 | DB8500_DMA_DEV30_MSP3_RX = 30, |
49 | * never both at the same time. | 49 | DB8500_DMA_DEV31_MSP0_RX_SLIM0_CH0_RX = 31, |
50 | */ | 50 | DB8500_DMA_DEV32_SD_MM1_RX = 32, |
51 | STEDMA40_SLIM0_CH0_RX = 31, | 51 | DB8500_DMA_DEV33_SPI2_RX = 33, |
52 | STEDMA40_DEV_MSP0_RX = 31, | 52 | DB8500_DMA_DEV34_I2C3_RX2 = 34, |
53 | STEDMA40_DEV_SD_MM1_RX = 32, | 53 | DB8500_DMA_DEV35_SPI1_RX = 35, |
54 | STEDMA40_DEV_SPI2_RX = 33, | 54 | DB8500_DMA_DEV36_USB_OTG_IEP_3_11 = 36, |
55 | STEDMA40_DEV_I2C3_RX2 = 34, | 55 | DB8500_DMA_DEV37_USB_OTG_IEP_2_10 = 37, |
56 | STEDMA40_DEV_SPI1_RX = 35, | 56 | DB8500_DMA_DEV38_USB_OTG_IEP_1_9 = 38, |
57 | STEDMA40_DEV_USB_OTG_IEP_4_12 = 36, | 57 | DB8500_DMA_DEV39_USB_OTG_IEP_8 = 39, |
58 | STEDMA40_DEV_USB_OTG_IEP_5_13 = 37, | 58 | DB8500_DMA_DEV40_SPI3_RX = 40, |
59 | STEDMA40_DEV_USB_OTG_IEP_6_14 = 38, | 59 | DB8500_DMA_DEV41_SD_MM3_RX = 41, |
60 | STEDMA40_DEV_USB_OTG_IEP_7_15 = 39, | 60 | DB8500_DMA_DEV42_SD_MM4_RX = 42, |
61 | STEDMA40_DEV_SPI3_RX = 40, | 61 | DB8500_DMA_DEV43_SD_MM5_RX = 43, |
62 | STEDMA40_DEV_SD_MM3_RX = 41, | 62 | DB8500_DMA_DEV44_SRC_SXA4_RX_TX = 44, |
63 | STEDMA40_DEV_SD_MM4_RX = 42, | 63 | DB8500_DMA_DEV45_SRC_SXA5_RX_TX = 45, |
64 | STEDMA40_DEV_SD_MM5_RX = 43, | 64 | DB8500_DMA_DEV46_SLIM0_CH8_RX_SRC_SXA6_RX_TX = 46, |
65 | STEDMA40_DEV_SRC_SXA4_RX_TX = 44, | 65 | DB8500_DMA_DEV47_SLIM0_CH9_RX_SRC_SXA7_RX_TX = 47, |
66 | STEDMA40_DEV_SRC_SXA5_RX_TX = 45, | 66 | DB8500_DMA_DEV48_CAC1_RX = 48, |
67 | STEDMA40_DEV_SRC_SXA6_RX_TX = 46, | 67 | /* 49, 50 and 51 are not used */ |
68 | STEDMA40_DEV_SRC_SXA7_RX_TX = 47, | 68 | DB8500_DMA_DEV52_SLIM0_CH4_RX_HSI_RX_CH4 = 52, |
69 | STEDMA40_DEV_CAC1_RX = 48, | 69 | DB8500_DMA_DEV53_SLIM0_CH5_RX_HSI_RX_CH5 = 53, |
70 | /* RX channels 49 and 50 are unused */ | 70 | DB8500_DMA_DEV54_SLIM0_CH6_RX_HSI_RX_CH6 = 54, |
71 | STEDMA40_DEV_MSHC_RX = 51, | 71 | DB8500_DMA_DEV55_SLIM0_CH7_RX_HSI_RX_CH7 = 55, |
72 | STEDMA40_DEV_SLIM1_CH0_RX_HSI_RX_CH4 = 52, | 72 | /* 56, 57, 58, 59 and 60 are not used */ |
73 | STEDMA40_DEV_SLIM1_CH1_RX_HSI_RX_CH5 = 53, | 73 | DB8500_DMA_DEV61_CAC0_RX = 61, |
74 | STEDMA40_DEV_SLIM1_CH2_RX_HSI_RX_CH6 = 54, | 74 | /* 62 and 63 are not used */ |
75 | STEDMA40_DEV_SLIM1_CH3_RX_HSI_RX_CH7 = 55, | ||
76 | /* RX channels 56 thru 60 are unused */ | ||
77 | STEDMA40_DEV_CAC0_RX = 61, | ||
78 | /* RX channels 62 and 63 are unused */ | ||
79 | }; | 75 | }; |
80 | 76 | ||
81 | enum dma_dest_dev_type { | 77 | enum dma_dest_dev_type { |
82 | STEDMA40_DEV_SPI0_TX = 0, | 78 | DB8500_DMA_DEV0_SPI0_TX = 0, |
83 | STEDMA40_DEV_SD_MMC0_TX = 1, | 79 | DB8500_DMA_DEV1_SD_MMC0_TX = 1, |
84 | STEDMA40_DEV_SD_MMC1_TX = 2, | 80 | DB8500_DMA_DEV2_SD_MMC1_TX = 2, |
85 | STEDMA40_DEV_SD_MMC2_TX = 3, | 81 | DB8500_DMA_DEV3_SD_MMC2_TX = 3, |
86 | STEDMA40_DEV_I2C1_TX = 4, | 82 | DB8500_DMA_DEV4_I2C1_TX = 4, |
87 | STEDMA40_DEV_I2C3_TX = 5, | 83 | DB8500_DMA_DEV5_I2C3_TX = 5, |
88 | STEDMA40_DEV_I2C2_TX = 6, | 84 | DB8500_DMA_DEV6_I2C2_TX = 6, |
89 | STEDMA50_DEV_I2C4_TX = 7, /* Only on V1 */ | 85 | DB8500_DMA_DEV7_I2C4_TX = 7, /* Only on V1 and later */ |
90 | STEDMA40_DEV_SSP0_TX = 8, | 86 | DB8500_DMA_DEV8_SSP0_TX = 8, |
91 | STEDMA40_DEV_SSP1_TX = 9, | 87 | DB8500_DMA_DEV9_SSP1_TX = 9, |
92 | /* TX channel 10 is unused */ | 88 | /* 10 is not used*/ |
93 | STEDMA40_DEV_UART2_TX = 11, | 89 | DB8500_DMA_DEV11_UART2_TX = 11, |
94 | STEDMA40_DEV_UART1_TX = 12, | 90 | DB8500_DMA_DEV12_UART1_TX = 12, |
95 | STEDMA40_DEV_UART0_TX= 13, | 91 | DB8500_DMA_DEV13_UART0_TX = 13, |
96 | STEDMA40_DEV_MSP2_TX = 14, | 92 | DB8500_DMA_DEV14_MSP2_TX = 14, |
97 | STEDMA40_DEV_I2C0_TX = 15, | 93 | DB8500_DMA_DEV15_I2C0_TX = 15, |
98 | STEDMA40_DEV_USB_OTG_OEP_8 = 16, | 94 | DB8500_DMA_DEV16_USB_OTG_OEP_7_15 = 16, |
99 | STEDMA40_DEV_USB_OTG_OEP_1_9 = 17, | 95 | DB8500_DMA_DEV17_USB_OTG_OEP_6_14 = 17, |
100 | STEDMA40_DEV_USB_OTG_OEP_2_10= 18, | 96 | DB8500_DMA_DEV18_USB_OTG_OEP_5_13 = 18, |
101 | STEDMA40_DEV_USB_OTG_OEP_3_11 = 19, | 97 | DB8500_DMA_DEV19_USB_OTG_OEP_4_12 = 19, |
102 | STEDMA40_DEV_SLIM0_CH0_TX_HSI_TX_CH0 = 20, | 98 | DB8500_DMA_DEV20_SLIM0_CH0_TX_HSI_TX_CH0 = 20, |
103 | STEDMA40_DEV_SLIM0_CH1_TX_HSI_TX_CH1 = 21, | 99 | DB8500_DMA_DEV21_SLIM0_CH1_TX_HSI_TX_CH1 = 21, |
104 | STEDMA40_DEV_SLIM0_CH2_TX_HSI_TX_CH2 = 22, | 100 | DB8500_DMA_DEV22_SLIM0_CH2_TX_HSI_TX_CH2 = 22, |
105 | STEDMA40_DEV_SLIM0_CH3_TX_HSI_TX_CH3 = 23, | 101 | DB8500_DMA_DEV23_SLIM0_CH3_TX_HSI_TX_CH3 = 23, |
106 | STEDMA40_DEV_DST_SXA0_RX_TX = 24, | 102 | DB8500_DMA_DEV24_DST_SXA0_RX_TX = 24, |
107 | STEDMA40_DEV_DST_SXA1_RX_TX = 25, | 103 | DB8500_DMA_DEV25_DST_SXA1_RX_TX = 25, |
108 | STEDMA40_DEV_DST_SXA2_RX_TX = 26, | 104 | DB8500_DMA_DEV26_DST_SXA2_RX_TX = 26, |
109 | STEDMA40_DEV_DST_SXA3_RX_TX = 27, | 105 | DB8500_DMA_DEV27_DST_SXA3_RX_TX = 27, |
110 | STEDMA40_DEV_SD_MM2_TX = 28, | 106 | DB8500_DMA_DEV28_SD_MM2_TX = 28, |
111 | STEDMA40_DEV_SD_MM0_TX = 29, | 107 | DB8500_DMA_DEV29_SD_MM0_TX = 29, |
112 | STEDMA40_DEV_MSP1_TX = 30, | 108 | DB8500_DMA_DEV30_MSP1_TX = 30, |
113 | /* | 109 | DB8500_DMA_DEV31_MSP0_TX_SLIM0_CH0_TX = 31, |
114 | * This channel is either SlimBus or MSP, | 110 | DB8500_DMA_DEV32_SD_MM1_TX = 32, |
115 | * never both at the same time. | 111 | DB8500_DMA_DEV33_SPI2_TX = 33, |
116 | */ | 112 | DB8500_DMA_DEV34_I2C3_TX2 = 34, |
117 | STEDMA40_SLIM0_CH0_TX = 31, | 113 | DB8500_DMA_DEV35_SPI1_TX = 35, |
118 | STEDMA40_DEV_MSP0_TX = 31, | 114 | DB8500_DMA_DEV36_USB_OTG_OEP_3_11 = 36, |
119 | STEDMA40_DEV_SD_MM1_TX = 32, | 115 | DB8500_DMA_DEV37_USB_OTG_OEP_2_10 = 37, |
120 | STEDMA40_DEV_SPI2_TX = 33, | 116 | DB8500_DMA_DEV38_USB_OTG_OEP_1_9 = 38, |
121 | /* Secondary I2C3 channel */ | 117 | DB8500_DMA_DEV39_USB_OTG_OEP_8 = 39, |
122 | STEDMA40_DEV_I2C3_TX2 = 34, | 118 | DB8500_DMA_DEV40_SPI3_TX = 40, |
123 | STEDMA40_DEV_SPI1_TX = 35, | 119 | DB8500_DMA_DEV41_SD_MM3_TX = 41, |
124 | STEDMA40_DEV_USB_OTG_OEP_4_12 = 36, | 120 | DB8500_DMA_DEV42_SD_MM4_TX = 42, |
125 | STEDMA40_DEV_USB_OTG_OEP_5_13 = 37, | 121 | DB8500_DMA_DEV43_SD_MM5_TX = 43, |
126 | STEDMA40_DEV_USB_OTG_OEP_6_14 = 38, | 122 | DB8500_DMA_DEV44_DST_SXA4_RX_TX = 44, |
127 | STEDMA40_DEV_USB_OTG_OEP_7_15 = 39, | 123 | DB8500_DMA_DEV45_DST_SXA5_RX_TX = 45, |
128 | STEDMA40_DEV_SPI3_TX = 40, | 124 | DB8500_DMA_DEV46_SLIM0_CH8_TX_DST_SXA6_RX_TX = 46, |
129 | STEDMA40_DEV_SD_MM3_TX = 41, | 125 | DB8500_DMA_DEV47_SLIM0_CH9_TX_DST_SXA7_RX_TX = 47, |
130 | STEDMA40_DEV_SD_MM4_TX = 42, | 126 | DB8500_DMA_DEV48_CAC1_TX = 48, |
131 | STEDMA40_DEV_SD_MM5_TX = 43, | 127 | DB8500_DMA_DEV49_CAC1_TX_HAC1_TX = 49, |
132 | STEDMA40_DEV_DST_SXA4_RX_TX = 44, | 128 | DB8500_DMA_DEV50_HAC1_TX = 50, |
133 | STEDMA40_DEV_DST_SXA5_RX_TX = 45, | 129 | DB8500_DMA_MEMCPY_TX_0 = 51, |
134 | STEDMA40_DEV_DST_SXA6_RX_TX = 46, | 130 | DB8500_DMA_DEV52_SLIM1_CH4_TX_HSI_TX_CH4 = 52, |
135 | STEDMA40_DEV_DST_SXA7_RX_TX = 47, | 131 | DB8500_DMA_DEV53_SLIM1_CH5_TX_HSI_TX_CH5 = 53, |
136 | STEDMA40_DEV_CAC1_TX = 48, | 132 | DB8500_DMA_DEV54_SLIM1_CH6_TX_HSI_TX_CH6 = 54, |
137 | STEDMA40_DEV_CAC1_TX_HAC1_TX = 49, | 133 | DB8500_DMA_DEV55_SLIM1_CH7_TX_HSI_TX_CH7 = 55, |
138 | STEDMA40_DEV_HAC1_TX = 50, | 134 | DB8500_DMA_MEMCPY_TX_1 = 56, |
139 | STEDMA40_MEMCPY_TX_0 = 51, | 135 | DB8500_DMA_MEMCPY_TX_2 = 57, |
140 | STEDMA40_DEV_SLIM1_CH0_TX_HSI_TX_CH4 = 52, | 136 | DB8500_DMA_MEMCPY_TX_3 = 58, |
141 | STEDMA40_DEV_SLIM1_CH1_TX_HSI_TX_CH5 = 53, | 137 | DB8500_DMA_MEMCPY_TX_4 = 59, |
142 | STEDMA40_DEV_SLIM1_CH2_TX_HSI_TX_CH6 = 54, | 138 | DB8500_DMA_MEMCPY_TX_5 = 60, |
143 | STEDMA40_DEV_SLIM1_CH3_TX_HSI_TX_CH7 = 55, | 139 | DB8500_DMA_DEV61_CAC0_TX = 61, |
144 | STEDMA40_MEMCPY_TX_1 = 56, | 140 | DB8500_DMA_DEV62_CAC0_TX_HAC0_TX = 62, |
145 | STEDMA40_MEMCPY_TX_2 = 57, | 141 | DB8500_DMA_DEV63_HAC0_TX = 63, |
146 | STEDMA40_MEMCPY_TX_3 = 58, | ||
147 | STEDMA40_MEMCPY_TX_4 = 59, | ||
148 | STEDMA40_MEMCPY_TX_5 = 60, | ||
149 | STEDMA40_DEV_CAC0_TX = 61, | ||
150 | STEDMA40_DEV_CAC0_TX_HAC0_TX = 62, | ||
151 | STEDMA40_DEV_HAC0_TX = 63, | ||
152 | }; | 142 | }; |
153 | 143 | ||
154 | #endif | 144 | #endif |
diff --git a/arch/arm/mach-vexpress/ct-ca9x4.c b/arch/arm/mach-vexpress/ct-ca9x4.c index 577df6cccb08..efb127022d42 100644 --- a/arch/arm/mach-vexpress/ct-ca9x4.c +++ b/arch/arm/mach-vexpress/ct-ca9x4.c | |||
@@ -227,7 +227,13 @@ static void ct_ca9x4_init(void) | |||
227 | int i; | 227 | int i; |
228 | 228 | ||
229 | #ifdef CONFIG_CACHE_L2X0 | 229 | #ifdef CONFIG_CACHE_L2X0 |
230 | l2x0_init(MMIO_P2V(CT_CA9X4_L2CC), 0x00000000, 0xfe0fffff); | 230 | void __iomem *l2x0_base = MMIO_P2V(CT_CA9X4_L2CC); |
231 | |||
232 | /* set RAM latencies to 1 cycle for this core tile. */ | ||
233 | writel(0, l2x0_base + L2X0_TAG_LATENCY_CTRL); | ||
234 | writel(0, l2x0_base + L2X0_DATA_LATENCY_CTRL); | ||
235 | |||
236 | l2x0_init(l2x0_base, 0x00400000, 0xfe0fffff); | ||
231 | #endif | 237 | #endif |
232 | 238 | ||
233 | clkdev_add_table(lookups, ARRAY_SIZE(lookups)); | 239 | clkdev_add_table(lookups, ARRAY_SIZE(lookups)); |
diff --git a/arch/arm/mach-vexpress/include/mach/smp.h b/arch/arm/mach-vexpress/include/mach/smp.h index 72a9621ed087..5a6da4fd247e 100644 --- a/arch/arm/mach-vexpress/include/mach/smp.h +++ b/arch/arm/mach-vexpress/include/mach/smp.h | |||
@@ -2,14 +2,7 @@ | |||
2 | #define __MACH_SMP_H | 2 | #define __MACH_SMP_H |
3 | 3 | ||
4 | #include <asm/hardware/gic.h> | 4 | #include <asm/hardware/gic.h> |
5 | 5 | #include <asm/smp_mpidr.h> | |
6 | #define hard_smp_processor_id() \ | ||
7 | ({ \ | ||
8 | unsigned int cpunum; \ | ||
9 | __asm__("mrc p15, 0, %0, c0, c0, 5" \ | ||
10 | : "=r" (cpunum)); \ | ||
11 | cpunum &= 0x0F; \ | ||
12 | }) | ||
13 | 6 | ||
14 | /* | 7 | /* |
15 | * We use IRQ1 as the IPI | 8 | * We use IRQ1 as the IPI |
diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c index d073b64ae87e..724ba3bce72c 100644 --- a/arch/arm/mm/alignment.c +++ b/arch/arm/mm/alignment.c | |||
@@ -885,8 +885,23 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs) | |||
885 | 885 | ||
886 | if (ai_usermode & UM_SIGNAL) | 886 | if (ai_usermode & UM_SIGNAL) |
887 | force_sig(SIGBUS, current); | 887 | force_sig(SIGBUS, current); |
888 | else | 888 | else { |
889 | set_cr(cr_no_alignment); | 889 | /* |
890 | * We're about to disable the alignment trap and return to | ||
891 | * user space. But if an interrupt occurs before actually | ||
892 | * reaching user space, then the IRQ vector entry code will | ||
893 | * notice that we were still in kernel space and therefore | ||
894 | * the alignment trap won't be re-enabled in that case as it | ||
895 | * is presumed to be always on from kernel space. | ||
896 | * Let's prevent that race by disabling interrupts here (they | ||
897 | * are disabled on the way back to user space anyway in | ||
898 | * entry-common.S) and disable the alignment trap only if | ||
899 | * there is no work pending for this thread. | ||
900 | */ | ||
901 | raw_local_irq_disable(); | ||
902 | if (!(current_thread_info()->flags & _TIF_WORK_MASK)) | ||
903 | set_cr(cr_no_alignment); | ||
904 | } | ||
890 | 905 | ||
891 | return 0; | 906 | return 0; |
892 | } | 907 | } |
diff --git a/arch/arm/mm/cache-v6.S b/arch/arm/mm/cache-v6.S index 86aa689ef1aa..99fa688dfadd 100644 --- a/arch/arm/mm/cache-v6.S +++ b/arch/arm/mm/cache-v6.S | |||
@@ -21,18 +21,22 @@ | |||
21 | #define D_CACHE_LINE_SIZE 32 | 21 | #define D_CACHE_LINE_SIZE 32 |
22 | #define BTB_FLUSH_SIZE 8 | 22 | #define BTB_FLUSH_SIZE 8 |
23 | 23 | ||
24 | #ifdef CONFIG_ARM_ERRATA_411920 | ||
25 | /* | 24 | /* |
26 | * Invalidate the entire I cache (this code is a workaround for the ARM1136 | 25 | * v6_flush_icache_all() |
27 | * erratum 411920 - Invalidate Instruction Cache operation can fail. This | 26 | * |
28 | * erratum is present in 1136, 1156 and 1176. It does not affect the MPCore. | 27 | * Flush the whole I-cache. |
29 | * | 28 | * |
30 | * Registers: | 29 | * ARM1136 erratum 411920 - Invalidate Instruction Cache operation can fail. |
31 | * r0 - set to 0 | 30 | * This erratum is present in 1136, 1156 and 1176. It does not affect the |
32 | * r1 - corrupted | 31 | * MPCore. |
32 | * | ||
33 | * Registers: | ||
34 | * r0 - set to 0 | ||
35 | * r1 - corrupted | ||
33 | */ | 36 | */ |
34 | ENTRY(v6_icache_inval_all) | 37 | ENTRY(v6_flush_icache_all) |
35 | mov r0, #0 | 38 | mov r0, #0 |
39 | #ifdef CONFIG_ARM_ERRATA_411920 | ||
36 | mrs r1, cpsr | 40 | mrs r1, cpsr |
37 | cpsid ifa @ disable interrupts | 41 | cpsid ifa @ disable interrupts |
38 | mcr p15, 0, r0, c7, c5, 0 @ invalidate entire I-cache | 42 | mcr p15, 0, r0, c7, c5, 0 @ invalidate entire I-cache |
@@ -43,8 +47,11 @@ ENTRY(v6_icache_inval_all) | |||
43 | .rept 11 @ ARM Ltd recommends at least | 47 | .rept 11 @ ARM Ltd recommends at least |
44 | nop @ 11 NOPs | 48 | nop @ 11 NOPs |
45 | .endr | 49 | .endr |
46 | mov pc, lr | 50 | #else |
51 | mcr p15, 0, r0, c7, c5, 0 @ invalidate I-cache | ||
47 | #endif | 52 | #endif |
53 | mov pc, lr | ||
54 | ENDPROC(v6_flush_icache_all) | ||
48 | 55 | ||
49 | /* | 56 | /* |
50 | * v6_flush_cache_all() | 57 | * v6_flush_cache_all() |
@@ -60,7 +67,7 @@ ENTRY(v6_flush_kern_cache_all) | |||
60 | #ifndef CONFIG_ARM_ERRATA_411920 | 67 | #ifndef CONFIG_ARM_ERRATA_411920 |
61 | mcr p15, 0, r0, c7, c5, 0 @ I+BTB cache invalidate | 68 | mcr p15, 0, r0, c7, c5, 0 @ I+BTB cache invalidate |
62 | #else | 69 | #else |
63 | b v6_icache_inval_all | 70 | b v6_flush_icache_all |
64 | #endif | 71 | #endif |
65 | #else | 72 | #else |
66 | mcr p15, 0, r0, c7, c15, 0 @ Cache clean+invalidate | 73 | mcr p15, 0, r0, c7, c15, 0 @ Cache clean+invalidate |
@@ -138,7 +145,7 @@ ENTRY(v6_coherent_user_range) | |||
138 | #ifndef CONFIG_ARM_ERRATA_411920 | 145 | #ifndef CONFIG_ARM_ERRATA_411920 |
139 | mcr p15, 0, r0, c7, c5, 0 @ I+BTB cache invalidate | 146 | mcr p15, 0, r0, c7, c5, 0 @ I+BTB cache invalidate |
140 | #else | 147 | #else |
141 | b v6_icache_inval_all | 148 | b v6_flush_icache_all |
142 | #endif | 149 | #endif |
143 | #else | 150 | #else |
144 | mcr p15, 0, r0, c7, c5, 6 @ invalidate BTB | 151 | mcr p15, 0, r0, c7, c5, 6 @ invalidate BTB |
@@ -312,6 +319,7 @@ ENDPROC(v6_dma_unmap_area) | |||
312 | 319 | ||
313 | .type v6_cache_fns, #object | 320 | .type v6_cache_fns, #object |
314 | ENTRY(v6_cache_fns) | 321 | ENTRY(v6_cache_fns) |
322 | .long v6_flush_icache_all | ||
315 | .long v6_flush_kern_cache_all | 323 | .long v6_flush_kern_cache_all |
316 | .long v6_flush_user_cache_all | 324 | .long v6_flush_user_cache_all |
317 | .long v6_flush_user_cache_range | 325 | .long v6_flush_user_cache_range |
diff --git a/arch/arm/mm/cache-v7.S b/arch/arm/mm/cache-v7.S index 37c8157e116e..a3ebf7a4f49b 100644 --- a/arch/arm/mm/cache-v7.S +++ b/arch/arm/mm/cache-v7.S | |||
@@ -18,6 +18,21 @@ | |||
18 | #include "proc-macros.S" | 18 | #include "proc-macros.S" |
19 | 19 | ||
20 | /* | 20 | /* |
21 | * v7_flush_icache_all() | ||
22 | * | ||
23 | * Flush the whole I-cache. | ||
24 | * | ||
25 | * Registers: | ||
26 | * r0 - set to 0 | ||
27 | */ | ||
28 | ENTRY(v7_flush_icache_all) | ||
29 | mov r0, #0 | ||
30 | ALT_SMP(mcr p15, 0, r0, c7, c1, 0) @ invalidate I-cache inner shareable | ||
31 | ALT_UP(mcr p15, 0, r0, c7, c5, 0) @ I+BTB cache invalidate | ||
32 | mov pc, lr | ||
33 | ENDPROC(v7_flush_icache_all) | ||
34 | |||
35 | /* | ||
21 | * v7_flush_dcache_all() | 36 | * v7_flush_dcache_all() |
22 | * | 37 | * |
23 | * Flush the whole D-cache. | 38 | * Flush the whole D-cache. |
@@ -91,11 +106,8 @@ ENTRY(v7_flush_kern_cache_all) | |||
91 | THUMB( stmfd sp!, {r4-r7, r9-r11, lr} ) | 106 | THUMB( stmfd sp!, {r4-r7, r9-r11, lr} ) |
92 | bl v7_flush_dcache_all | 107 | bl v7_flush_dcache_all |
93 | mov r0, #0 | 108 | mov r0, #0 |
94 | #ifdef CONFIG_SMP | 109 | ALT_SMP(mcr p15, 0, r0, c7, c1, 0) @ invalidate I-cache inner shareable |
95 | mcr p15, 0, r0, c7, c1, 0 @ invalidate I-cache inner shareable | 110 | ALT_UP(mcr p15, 0, r0, c7, c5, 0) @ I+BTB cache invalidate |
96 | #else | ||
97 | mcr p15, 0, r0, c7, c5, 0 @ I+BTB cache invalidate | ||
98 | #endif | ||
99 | ARM( ldmfd sp!, {r4-r5, r7, r9-r11, lr} ) | 111 | ARM( ldmfd sp!, {r4-r5, r7, r9-r11, lr} ) |
100 | THUMB( ldmfd sp!, {r4-r7, r9-r11, lr} ) | 112 | THUMB( ldmfd sp!, {r4-r7, r9-r11, lr} ) |
101 | mov pc, lr | 113 | mov pc, lr |
@@ -171,11 +183,8 @@ ENTRY(v7_coherent_user_range) | |||
171 | cmp r0, r1 | 183 | cmp r0, r1 |
172 | blo 1b | 184 | blo 1b |
173 | mov r0, #0 | 185 | mov r0, #0 |
174 | #ifdef CONFIG_SMP | 186 | ALT_SMP(mcr p15, 0, r0, c7, c1, 6) @ invalidate BTB Inner Shareable |
175 | mcr p15, 0, r0, c7, c1, 6 @ invalidate BTB Inner Shareable | 187 | ALT_UP(mcr p15, 0, r0, c7, c5, 6) @ invalidate BTB |
176 | #else | ||
177 | mcr p15, 0, r0, c7, c5, 6 @ invalidate BTB | ||
178 | #endif | ||
179 | dsb | 188 | dsb |
180 | isb | 189 | isb |
181 | mov pc, lr | 190 | mov pc, lr |
@@ -309,6 +318,7 @@ ENDPROC(v7_dma_unmap_area) | |||
309 | 318 | ||
310 | .type v7_cache_fns, #object | 319 | .type v7_cache_fns, #object |
311 | ENTRY(v7_cache_fns) | 320 | ENTRY(v7_cache_fns) |
321 | .long v7_flush_icache_all | ||
312 | .long v7_flush_kern_cache_all | 322 | .long v7_flush_kern_cache_all |
313 | .long v7_flush_user_cache_all | 323 | .long v7_flush_user_cache_all |
314 | .long v7_flush_user_cache_range | 324 | .long v7_flush_user_cache_range |
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c index 23b0b03af5ea..1e21e125fe3a 100644 --- a/arch/arm/mm/fault.c +++ b/arch/arm/mm/fault.c | |||
@@ -581,6 +581,19 @@ static struct fsr_info ifsr_info[] = { | |||
581 | { do_bad, SIGBUS, 0, "unknown 31" }, | 581 | { do_bad, SIGBUS, 0, "unknown 31" }, |
582 | }; | 582 | }; |
583 | 583 | ||
584 | void __init | ||
585 | hook_ifault_code(int nr, int (*fn)(unsigned long, unsigned int, struct pt_regs *), | ||
586 | int sig, int code, const char *name) | ||
587 | { | ||
588 | if (nr < 0 || nr >= ARRAY_SIZE(ifsr_info)) | ||
589 | BUG(); | ||
590 | |||
591 | ifsr_info[nr].fn = fn; | ||
592 | ifsr_info[nr].sig = sig; | ||
593 | ifsr_info[nr].code = code; | ||
594 | ifsr_info[nr].name = name; | ||
595 | } | ||
596 | |||
584 | asmlinkage void __exception | 597 | asmlinkage void __exception |
585 | do_PrefetchAbort(unsigned long addr, unsigned int ifsr, struct pt_regs *regs) | 598 | do_PrefetchAbort(unsigned long addr, unsigned int ifsr, struct pt_regs *regs) |
586 | { | 599 | { |
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index 7185b00650fe..36c4553ffcce 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c | |||
@@ -277,7 +277,7 @@ void __init arm_memblock_init(struct meminfo *mi, struct machine_desc *mdesc) | |||
277 | 277 | ||
278 | /* Register the kernel text, kernel data and initrd with memblock. */ | 278 | /* Register the kernel text, kernel data and initrd with memblock. */ |
279 | #ifdef CONFIG_XIP_KERNEL | 279 | #ifdef CONFIG_XIP_KERNEL |
280 | memblock_reserve(__pa(_data), _end - _data); | 280 | memblock_reserve(__pa(_sdata), _end - _sdata); |
281 | #else | 281 | #else |
282 | memblock_reserve(__pa(_stext), _end - _stext); | 282 | memblock_reserve(__pa(_stext), _end - _stext); |
283 | #endif | 283 | #endif |
@@ -545,7 +545,7 @@ void __init mem_init(void) | |||
545 | 545 | ||
546 | MLK_ROUNDUP(__init_begin, __init_end), | 546 | MLK_ROUNDUP(__init_begin, __init_end), |
547 | MLK_ROUNDUP(_text, _etext), | 547 | MLK_ROUNDUP(_text, _etext), |
548 | MLK_ROUNDUP(_data, _edata)); | 548 | MLK_ROUNDUP(_sdata, _edata)); |
549 | 549 | ||
550 | #undef MLK | 550 | #undef MLK |
551 | #undef MLM | 551 | #undef MLM |
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 6e1c4f6a2b3f..e2335811c02e 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/nodemask.h> | 15 | #include <linux/nodemask.h> |
16 | #include <linux/memblock.h> | 16 | #include <linux/memblock.h> |
17 | #include <linux/sort.h> | 17 | #include <linux/sort.h> |
18 | #include <linux/fs.h> | ||
18 | 19 | ||
19 | #include <asm/cputype.h> | 20 | #include <asm/cputype.h> |
20 | #include <asm/sections.h> | 21 | #include <asm/sections.h> |
@@ -246,6 +247,9 @@ static struct mem_type mem_types[] = { | |||
246 | .domain = DOMAIN_USER, | 247 | .domain = DOMAIN_USER, |
247 | }, | 248 | }, |
248 | [MT_MEMORY] = { | 249 | [MT_MEMORY] = { |
250 | .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | | ||
251 | L_PTE_USER | L_PTE_EXEC, | ||
252 | .prot_l1 = PMD_TYPE_TABLE, | ||
249 | .prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE, | 253 | .prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE, |
250 | .domain = DOMAIN_KERNEL, | 254 | .domain = DOMAIN_KERNEL, |
251 | }, | 255 | }, |
@@ -254,6 +258,9 @@ static struct mem_type mem_types[] = { | |||
254 | .domain = DOMAIN_KERNEL, | 258 | .domain = DOMAIN_KERNEL, |
255 | }, | 259 | }, |
256 | [MT_MEMORY_NONCACHED] = { | 260 | [MT_MEMORY_NONCACHED] = { |
261 | .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | | ||
262 | L_PTE_USER | L_PTE_EXEC | L_PTE_MT_BUFFERABLE, | ||
263 | .prot_l1 = PMD_TYPE_TABLE, | ||
257 | .prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE, | 264 | .prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE, |
258 | .domain = DOMAIN_KERNEL, | 265 | .domain = DOMAIN_KERNEL, |
259 | }, | 266 | }, |
@@ -303,9 +310,8 @@ static void __init build_mem_type_table(void) | |||
303 | cachepolicy = CPOLICY_WRITEBACK; | 310 | cachepolicy = CPOLICY_WRITEBACK; |
304 | ecc_mask = 0; | 311 | ecc_mask = 0; |
305 | } | 312 | } |
306 | #ifdef CONFIG_SMP | 313 | if (is_smp()) |
307 | cachepolicy = CPOLICY_WRITEALLOC; | 314 | cachepolicy = CPOLICY_WRITEALLOC; |
308 | #endif | ||
309 | 315 | ||
310 | /* | 316 | /* |
311 | * Strip out features not present on earlier architectures. | 317 | * Strip out features not present on earlier architectures. |
@@ -399,21 +405,22 @@ static void __init build_mem_type_table(void) | |||
399 | cp = &cache_policies[cachepolicy]; | 405 | cp = &cache_policies[cachepolicy]; |
400 | vecs_pgprot = kern_pgprot = user_pgprot = cp->pte; | 406 | vecs_pgprot = kern_pgprot = user_pgprot = cp->pte; |
401 | 407 | ||
402 | #ifndef CONFIG_SMP | ||
403 | /* | 408 | /* |
404 | * Only use write-through for non-SMP systems | 409 | * Only use write-through for non-SMP systems |
405 | */ | 410 | */ |
406 | if (cpu_arch >= CPU_ARCH_ARMv5 && cachepolicy > CPOLICY_WRITETHROUGH) | 411 | if (!is_smp() && cpu_arch >= CPU_ARCH_ARMv5 && cachepolicy > CPOLICY_WRITETHROUGH) |
407 | vecs_pgprot = cache_policies[CPOLICY_WRITETHROUGH].pte; | 412 | vecs_pgprot = cache_policies[CPOLICY_WRITETHROUGH].pte; |
408 | #endif | ||
409 | 413 | ||
410 | /* | 414 | /* |
411 | * Enable CPU-specific coherency if supported. | 415 | * Enable CPU-specific coherency if supported. |
412 | * (Only available on XSC3 at the moment.) | 416 | * (Only available on XSC3 at the moment.) |
413 | */ | 417 | */ |
414 | if (arch_is_coherent() && cpu_is_xsc3()) | 418 | if (arch_is_coherent() && cpu_is_xsc3()) { |
415 | mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S; | 419 | mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S; |
416 | 420 | mem_types[MT_MEMORY].prot_pte |= L_PTE_SHARED; | |
421 | mem_types[MT_MEMORY_NONCACHED].prot_sect |= PMD_SECT_S; | ||
422 | mem_types[MT_MEMORY_NONCACHED].prot_pte |= L_PTE_SHARED; | ||
423 | } | ||
417 | /* | 424 | /* |
418 | * ARMv6 and above have extended page tables. | 425 | * ARMv6 and above have extended page tables. |
419 | */ | 426 | */ |
@@ -426,20 +433,23 @@ static void __init build_mem_type_table(void) | |||
426 | mem_types[MT_MINICLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE; | 433 | mem_types[MT_MINICLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE; |
427 | mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE; | 434 | mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE; |
428 | 435 | ||
429 | #ifdef CONFIG_SMP | 436 | if (is_smp()) { |
430 | /* | 437 | /* |
431 | * Mark memory with the "shared" attribute for SMP systems | 438 | * Mark memory with the "shared" attribute |
432 | */ | 439 | * for SMP systems |
433 | user_pgprot |= L_PTE_SHARED; | 440 | */ |
434 | kern_pgprot |= L_PTE_SHARED; | 441 | user_pgprot |= L_PTE_SHARED; |
435 | vecs_pgprot |= L_PTE_SHARED; | 442 | kern_pgprot |= L_PTE_SHARED; |
436 | mem_types[MT_DEVICE_WC].prot_sect |= PMD_SECT_S; | 443 | vecs_pgprot |= L_PTE_SHARED; |
437 | mem_types[MT_DEVICE_WC].prot_pte |= L_PTE_SHARED; | 444 | mem_types[MT_DEVICE_WC].prot_sect |= PMD_SECT_S; |
438 | mem_types[MT_DEVICE_CACHED].prot_sect |= PMD_SECT_S; | 445 | mem_types[MT_DEVICE_WC].prot_pte |= L_PTE_SHARED; |
439 | mem_types[MT_DEVICE_CACHED].prot_pte |= L_PTE_SHARED; | 446 | mem_types[MT_DEVICE_CACHED].prot_sect |= PMD_SECT_S; |
440 | mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S; | 447 | mem_types[MT_DEVICE_CACHED].prot_pte |= L_PTE_SHARED; |
441 | mem_types[MT_MEMORY_NONCACHED].prot_sect |= PMD_SECT_S; | 448 | mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S; |
442 | #endif | 449 | mem_types[MT_MEMORY].prot_pte |= L_PTE_SHARED; |
450 | mem_types[MT_MEMORY_NONCACHED].prot_sect |= PMD_SECT_S; | ||
451 | mem_types[MT_MEMORY_NONCACHED].prot_pte |= L_PTE_SHARED; | ||
452 | } | ||
443 | } | 453 | } |
444 | 454 | ||
445 | /* | 455 | /* |
@@ -475,6 +485,8 @@ static void __init build_mem_type_table(void) | |||
475 | mem_types[MT_LOW_VECTORS].prot_l1 |= ecc_mask; | 485 | mem_types[MT_LOW_VECTORS].prot_l1 |= ecc_mask; |
476 | mem_types[MT_HIGH_VECTORS].prot_l1 |= ecc_mask; | 486 | mem_types[MT_HIGH_VECTORS].prot_l1 |= ecc_mask; |
477 | mem_types[MT_MEMORY].prot_sect |= ecc_mask | cp->pmd; | 487 | mem_types[MT_MEMORY].prot_sect |= ecc_mask | cp->pmd; |
488 | mem_types[MT_MEMORY].prot_pte |= kern_pgprot; | ||
489 | mem_types[MT_MEMORY_NONCACHED].prot_sect |= ecc_mask; | ||
478 | mem_types[MT_ROM].prot_sect |= cp->pmd; | 490 | mem_types[MT_ROM].prot_sect |= cp->pmd; |
479 | 491 | ||
480 | switch (cp->pmd) { | 492 | switch (cp->pmd) { |
@@ -498,6 +510,19 @@ static void __init build_mem_type_table(void) | |||
498 | } | 510 | } |
499 | } | 511 | } |
500 | 512 | ||
513 | #ifdef CONFIG_ARM_DMA_MEM_BUFFERABLE | ||
514 | pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn, | ||
515 | unsigned long size, pgprot_t vma_prot) | ||
516 | { | ||
517 | if (!pfn_valid(pfn)) | ||
518 | return pgprot_noncached(vma_prot); | ||
519 | else if (file->f_flags & O_SYNC) | ||
520 | return pgprot_writecombine(vma_prot); | ||
521 | return vma_prot; | ||
522 | } | ||
523 | EXPORT_SYMBOL(phys_mem_access_prot); | ||
524 | #endif | ||
525 | |||
501 | #define vectors_base() (vectors_high() ? 0xffff0000 : 0) | 526 | #define vectors_base() (vectors_high() ? 0xffff0000 : 0) |
502 | 527 | ||
503 | static void __init *early_alloc(unsigned long sz) | 528 | static void __init *early_alloc(unsigned long sz) |
@@ -802,8 +827,7 @@ static void __init sanity_check_meminfo(void) | |||
802 | * rather difficult. | 827 | * rather difficult. |
803 | */ | 828 | */ |
804 | reason = "with VIPT aliasing cache"; | 829 | reason = "with VIPT aliasing cache"; |
805 | #ifdef CONFIG_SMP | 830 | } else if (is_smp() && tlb_ops_need_broadcast()) { |
806 | } else if (tlb_ops_need_broadcast()) { | ||
807 | /* | 831 | /* |
808 | * kmap_high needs to occasionally flush TLB entries, | 832 | * kmap_high needs to occasionally flush TLB entries, |
809 | * however, if the TLB entries need to be broadcast | 833 | * however, if the TLB entries need to be broadcast |
@@ -813,7 +837,6 @@ static void __init sanity_check_meminfo(void) | |||
813 | * (must not be called with irqs off) | 837 | * (must not be called with irqs off) |
814 | */ | 838 | */ |
815 | reason = "without hardware TLB ops broadcasting"; | 839 | reason = "without hardware TLB ops broadcasting"; |
816 | #endif | ||
817 | } | 840 | } |
818 | if (reason) { | 841 | if (reason) { |
819 | printk(KERN_CRIT "HIGHMEM is not supported %s, ignoring high memory\n", | 842 | printk(KERN_CRIT "HIGHMEM is not supported %s, ignoring high memory\n", |
diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S index 22aac8515196..b95662dedb64 100644 --- a/arch/arm/mm/proc-v6.S +++ b/arch/arm/mm/proc-v6.S | |||
@@ -30,13 +30,10 @@ | |||
30 | #define TTB_RGN_WT (2 << 3) | 30 | #define TTB_RGN_WT (2 << 3) |
31 | #define TTB_RGN_WB (3 << 3) | 31 | #define TTB_RGN_WB (3 << 3) |
32 | 32 | ||
33 | #ifndef CONFIG_SMP | 33 | #define TTB_FLAGS_UP TTB_RGN_WBWA |
34 | #define TTB_FLAGS TTB_RGN_WBWA | 34 | #define PMD_FLAGS_UP PMD_SECT_WB |
35 | #define PMD_FLAGS PMD_SECT_WB | 35 | #define TTB_FLAGS_SMP TTB_RGN_WBWA|TTB_S |
36 | #else | 36 | #define PMD_FLAGS_SMP PMD_SECT_WBWA|PMD_SECT_S |
37 | #define TTB_FLAGS TTB_RGN_WBWA|TTB_S | ||
38 | #define PMD_FLAGS PMD_SECT_WBWA|PMD_SECT_S | ||
39 | #endif | ||
40 | 37 | ||
41 | ENTRY(cpu_v6_proc_init) | 38 | ENTRY(cpu_v6_proc_init) |
42 | mov pc, lr | 39 | mov pc, lr |
@@ -97,7 +94,8 @@ ENTRY(cpu_v6_switch_mm) | |||
97 | #ifdef CONFIG_MMU | 94 | #ifdef CONFIG_MMU |
98 | mov r2, #0 | 95 | mov r2, #0 |
99 | ldr r1, [r1, #MM_CONTEXT_ID] @ get mm->context.id | 96 | ldr r1, [r1, #MM_CONTEXT_ID] @ get mm->context.id |
100 | orr r0, r0, #TTB_FLAGS | 97 | ALT_SMP(orr r0, r0, #TTB_FLAGS_SMP) |
98 | ALT_UP(orr r0, r0, #TTB_FLAGS_UP) | ||
101 | mcr p15, 0, r2, c7, c5, 6 @ flush BTAC/BTB | 99 | mcr p15, 0, r2, c7, c5, 6 @ flush BTAC/BTB |
102 | mcr p15, 0, r2, c7, c10, 4 @ drain write buffer | 100 | mcr p15, 0, r2, c7, c10, 4 @ drain write buffer |
103 | mcr p15, 0, r0, c2, c0, 0 @ set TTB 0 | 101 | mcr p15, 0, r0, c2, c0, 0 @ set TTB 0 |
@@ -156,9 +154,11 @@ cpu_pj4_name: | |||
156 | */ | 154 | */ |
157 | __v6_setup: | 155 | __v6_setup: |
158 | #ifdef CONFIG_SMP | 156 | #ifdef CONFIG_SMP |
159 | mrc p15, 0, r0, c1, c0, 1 @ Enable SMP/nAMP mode | 157 | ALT_SMP(mrc p15, 0, r0, c1, c0, 1) @ Enable SMP/nAMP mode |
158 | ALT_UP(nop) | ||
160 | orr r0, r0, #0x20 | 159 | orr r0, r0, #0x20 |
161 | mcr p15, 0, r0, c1, c0, 1 | 160 | ALT_SMP(mcr p15, 0, r0, c1, c0, 1) |
161 | ALT_UP(nop) | ||
162 | #endif | 162 | #endif |
163 | 163 | ||
164 | mov r0, #0 | 164 | mov r0, #0 |
@@ -169,7 +169,8 @@ __v6_setup: | |||
169 | #ifdef CONFIG_MMU | 169 | #ifdef CONFIG_MMU |
170 | mcr p15, 0, r0, c8, c7, 0 @ invalidate I + D TLBs | 170 | mcr p15, 0, r0, c8, c7, 0 @ invalidate I + D TLBs |
171 | mcr p15, 0, r0, c2, c0, 2 @ TTB control register | 171 | mcr p15, 0, r0, c2, c0, 2 @ TTB control register |
172 | orr r4, r4, #TTB_FLAGS | 172 | ALT_SMP(orr r4, r4, #TTB_FLAGS_SMP) |
173 | ALT_UP(orr r4, r4, #TTB_FLAGS_UP) | ||
173 | mcr p15, 0, r4, c2, c0, 1 @ load TTB1 | 174 | mcr p15, 0, r4, c2, c0, 1 @ load TTB1 |
174 | #endif /* CONFIG_MMU */ | 175 | #endif /* CONFIG_MMU */ |
175 | adr r5, v6_crval | 176 | adr r5, v6_crval |
@@ -225,10 +226,16 @@ cpu_elf_name: | |||
225 | __v6_proc_info: | 226 | __v6_proc_info: |
226 | .long 0x0007b000 | 227 | .long 0x0007b000 |
227 | .long 0x0007f000 | 228 | .long 0x0007f000 |
228 | .long PMD_TYPE_SECT | \ | 229 | ALT_SMP(.long \ |
230 | PMD_TYPE_SECT | \ | ||
231 | PMD_SECT_AP_WRITE | \ | ||
232 | PMD_SECT_AP_READ | \ | ||
233 | PMD_FLAGS_SMP) | ||
234 | ALT_UP(.long \ | ||
235 | PMD_TYPE_SECT | \ | ||
229 | PMD_SECT_AP_WRITE | \ | 236 | PMD_SECT_AP_WRITE | \ |
230 | PMD_SECT_AP_READ | \ | 237 | PMD_SECT_AP_READ | \ |
231 | PMD_FLAGS | 238 | PMD_FLAGS_UP) |
232 | .long PMD_TYPE_SECT | \ | 239 | .long PMD_TYPE_SECT | \ |
233 | PMD_SECT_XN | \ | 240 | PMD_SECT_XN | \ |
234 | PMD_SECT_AP_WRITE | \ | 241 | PMD_SECT_AP_WRITE | \ |
@@ -249,10 +256,16 @@ __v6_proc_info: | |||
249 | __pj4_v6_proc_info: | 256 | __pj4_v6_proc_info: |
250 | .long 0x560f5810 | 257 | .long 0x560f5810 |
251 | .long 0xff0ffff0 | 258 | .long 0xff0ffff0 |
252 | .long PMD_TYPE_SECT | \ | 259 | ALT_SMP(.long \ |
260 | PMD_TYPE_SECT | \ | ||
261 | PMD_SECT_AP_WRITE | \ | ||
262 | PMD_SECT_AP_READ | \ | ||
263 | PMD_FLAGS_SMP) | ||
264 | ALT_UP(.long \ | ||
265 | PMD_TYPE_SECT | \ | ||
253 | PMD_SECT_AP_WRITE | \ | 266 | PMD_SECT_AP_WRITE | \ |
254 | PMD_SECT_AP_READ | \ | 267 | PMD_SECT_AP_READ | \ |
255 | PMD_FLAGS | 268 | PMD_FLAGS_UP) |
256 | .long PMD_TYPE_SECT | \ | 269 | .long PMD_TYPE_SECT | \ |
257 | PMD_SECT_XN | \ | 270 | PMD_SECT_XN | \ |
258 | PMD_SECT_AP_WRITE | \ | 271 | PMD_SECT_AP_WRITE | \ |
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S index 6a8506d99ee9..df422fee1cb6 100644 --- a/arch/arm/mm/proc-v7.S +++ b/arch/arm/mm/proc-v7.S | |||
@@ -30,15 +30,13 @@ | |||
30 | #define TTB_IRGN_WT ((1 << 0) | (0 << 6)) | 30 | #define TTB_IRGN_WT ((1 << 0) | (0 << 6)) |
31 | #define TTB_IRGN_WB ((1 << 0) | (1 << 6)) | 31 | #define TTB_IRGN_WB ((1 << 0) | (1 << 6)) |
32 | 32 | ||
33 | #ifndef CONFIG_SMP | ||
34 | /* PTWs cacheable, inner WB not shareable, outer WB not shareable */ | 33 | /* PTWs cacheable, inner WB not shareable, outer WB not shareable */ |
35 | #define TTB_FLAGS TTB_IRGN_WB|TTB_RGN_OC_WB | 34 | #define TTB_FLAGS_UP TTB_IRGN_WB|TTB_RGN_OC_WB |
36 | #define PMD_FLAGS PMD_SECT_WB | 35 | #define PMD_FLAGS_UP PMD_SECT_WB |
37 | #else | 36 | |
38 | /* PTWs cacheable, inner WBWA shareable, outer WBWA not shareable */ | 37 | /* PTWs cacheable, inner WBWA shareable, outer WBWA not shareable */ |
39 | #define TTB_FLAGS TTB_IRGN_WBWA|TTB_S|TTB_NOS|TTB_RGN_OC_WBWA | 38 | #define TTB_FLAGS_SMP TTB_IRGN_WBWA|TTB_S|TTB_NOS|TTB_RGN_OC_WBWA |
40 | #define PMD_FLAGS PMD_SECT_WBWA|PMD_SECT_S | 39 | #define PMD_FLAGS_SMP PMD_SECT_WBWA|PMD_SECT_S |
41 | #endif | ||
42 | 40 | ||
43 | ENTRY(cpu_v7_proc_init) | 41 | ENTRY(cpu_v7_proc_init) |
44 | mov pc, lr | 42 | mov pc, lr |
@@ -105,7 +103,8 @@ ENTRY(cpu_v7_switch_mm) | |||
105 | #ifdef CONFIG_MMU | 103 | #ifdef CONFIG_MMU |
106 | mov r2, #0 | 104 | mov r2, #0 |
107 | ldr r1, [r1, #MM_CONTEXT_ID] @ get mm->context.id | 105 | ldr r1, [r1, #MM_CONTEXT_ID] @ get mm->context.id |
108 | orr r0, r0, #TTB_FLAGS | 106 | ALT_SMP(orr r0, r0, #TTB_FLAGS_SMP) |
107 | ALT_UP(orr r0, r0, #TTB_FLAGS_UP) | ||
109 | #ifdef CONFIG_ARM_ERRATA_430973 | 108 | #ifdef CONFIG_ARM_ERRATA_430973 |
110 | mcr p15, 0, r2, c7, c5, 6 @ flush BTAC/BTB | 109 | mcr p15, 0, r2, c7, c5, 6 @ flush BTAC/BTB |
111 | #endif | 110 | #endif |
@@ -186,13 +185,15 @@ cpu_v7_name: | |||
186 | * It is assumed that: | 185 | * It is assumed that: |
187 | * - cache type register is implemented | 186 | * - cache type register is implemented |
188 | */ | 187 | */ |
189 | __v7_setup: | 188 | __v7_ca9mp_setup: |
190 | #ifdef CONFIG_SMP | 189 | #ifdef CONFIG_SMP |
191 | mrc p15, 0, r0, c1, c0, 1 | 190 | ALT_SMP(mrc p15, 0, r0, c1, c0, 1) |
191 | ALT_UP(mov r0, #(1 << 6)) @ fake it for UP | ||
192 | tst r0, #(1 << 6) @ SMP/nAMP mode enabled? | 192 | tst r0, #(1 << 6) @ SMP/nAMP mode enabled? |
193 | orreq r0, r0, #(1 << 6) | (1 << 0) @ Enable SMP/nAMP mode and | 193 | orreq r0, r0, #(1 << 6) | (1 << 0) @ Enable SMP/nAMP mode and |
194 | mcreq p15, 0, r0, c1, c0, 1 @ TLB ops broadcasting | 194 | mcreq p15, 0, r0, c1, c0, 1 @ TLB ops broadcasting |
195 | #endif | 195 | #endif |
196 | __v7_setup: | ||
196 | adr r12, __v7_setup_stack @ the local stack | 197 | adr r12, __v7_setup_stack @ the local stack |
197 | stmia r12, {r0-r5, r7, r9, r11, lr} | 198 | stmia r12, {r0-r5, r7, r9, r11, lr} |
198 | bl v7_flush_dcache_all | 199 | bl v7_flush_dcache_all |
@@ -201,11 +202,16 @@ __v7_setup: | |||
201 | mrc p15, 0, r0, c0, c0, 0 @ read main ID register | 202 | mrc p15, 0, r0, c0, c0, 0 @ read main ID register |
202 | and r10, r0, #0xff000000 @ ARM? | 203 | and r10, r0, #0xff000000 @ ARM? |
203 | teq r10, #0x41000000 | 204 | teq r10, #0x41000000 |
204 | bne 2f | 205 | bne 3f |
205 | and r5, r0, #0x00f00000 @ variant | 206 | and r5, r0, #0x00f00000 @ variant |
206 | and r6, r0, #0x0000000f @ revision | 207 | and r6, r0, #0x0000000f @ revision |
207 | orr r0, r6, r5, lsr #20-4 @ combine variant and revision | 208 | orr r6, r6, r5, lsr #20-4 @ combine variant and revision |
209 | ubfx r0, r0, #4, #12 @ primary part number | ||
208 | 210 | ||
211 | /* Cortex-A8 Errata */ | ||
212 | ldr r10, =0x00000c08 @ Cortex-A8 primary part number | ||
213 | teq r0, r10 | ||
214 | bne 2f | ||
209 | #ifdef CONFIG_ARM_ERRATA_430973 | 215 | #ifdef CONFIG_ARM_ERRATA_430973 |
210 | teq r5, #0x00100000 @ only present in r1p* | 216 | teq r5, #0x00100000 @ only present in r1p* |
211 | mrceq p15, 0, r10, c1, c0, 1 @ read aux control register | 217 | mrceq p15, 0, r10, c1, c0, 1 @ read aux control register |
@@ -213,21 +219,42 @@ __v7_setup: | |||
213 | mcreq p15, 0, r10, c1, c0, 1 @ write aux control register | 219 | mcreq p15, 0, r10, c1, c0, 1 @ write aux control register |
214 | #endif | 220 | #endif |
215 | #ifdef CONFIG_ARM_ERRATA_458693 | 221 | #ifdef CONFIG_ARM_ERRATA_458693 |
216 | teq r0, #0x20 @ only present in r2p0 | 222 | teq r6, #0x20 @ only present in r2p0 |
217 | mrceq p15, 0, r10, c1, c0, 1 @ read aux control register | 223 | mrceq p15, 0, r10, c1, c0, 1 @ read aux control register |
218 | orreq r10, r10, #(1 << 5) @ set L1NEON to 1 | 224 | orreq r10, r10, #(1 << 5) @ set L1NEON to 1 |
219 | orreq r10, r10, #(1 << 9) @ set PLDNOP to 1 | 225 | orreq r10, r10, #(1 << 9) @ set PLDNOP to 1 |
220 | mcreq p15, 0, r10, c1, c0, 1 @ write aux control register | 226 | mcreq p15, 0, r10, c1, c0, 1 @ write aux control register |
221 | #endif | 227 | #endif |
222 | #ifdef CONFIG_ARM_ERRATA_460075 | 228 | #ifdef CONFIG_ARM_ERRATA_460075 |
223 | teq r0, #0x20 @ only present in r2p0 | 229 | teq r6, #0x20 @ only present in r2p0 |
224 | mrceq p15, 1, r10, c9, c0, 2 @ read L2 cache aux ctrl register | 230 | mrceq p15, 1, r10, c9, c0, 2 @ read L2 cache aux ctrl register |
225 | tsteq r10, #1 << 22 | 231 | tsteq r10, #1 << 22 |
226 | orreq r10, r10, #(1 << 22) @ set the Write Allocate disable bit | 232 | orreq r10, r10, #(1 << 22) @ set the Write Allocate disable bit |
227 | mcreq p15, 1, r10, c9, c0, 2 @ write the L2 cache aux ctrl register | 233 | mcreq p15, 1, r10, c9, c0, 2 @ write the L2 cache aux ctrl register |
228 | #endif | 234 | #endif |
235 | b 3f | ||
236 | |||
237 | /* Cortex-A9 Errata */ | ||
238 | 2: ldr r10, =0x00000c09 @ Cortex-A9 primary part number | ||
239 | teq r0, r10 | ||
240 | bne 3f | ||
241 | #ifdef CONFIG_ARM_ERRATA_742230 | ||
242 | cmp r6, #0x22 @ only present up to r2p2 | ||
243 | mrcle p15, 0, r10, c15, c0, 1 @ read diagnostic register | ||
244 | orrle r10, r10, #1 << 4 @ set bit #4 | ||
245 | mcrle p15, 0, r10, c15, c0, 1 @ write diagnostic register | ||
246 | #endif | ||
247 | #ifdef CONFIG_ARM_ERRATA_742231 | ||
248 | teq r6, #0x20 @ present in r2p0 | ||
249 | teqne r6, #0x21 @ present in r2p1 | ||
250 | teqne r6, #0x22 @ present in r2p2 | ||
251 | mrceq p15, 0, r10, c15, c0, 1 @ read diagnostic register | ||
252 | orreq r10, r10, #1 << 12 @ set bit #12 | ||
253 | orreq r10, r10, #1 << 22 @ set bit #22 | ||
254 | mcreq p15, 0, r10, c15, c0, 1 @ write diagnostic register | ||
255 | #endif | ||
229 | 256 | ||
230 | 2: mov r10, #0 | 257 | 3: mov r10, #0 |
231 | #ifdef HARVARD_CACHE | 258 | #ifdef HARVARD_CACHE |
232 | mcr p15, 0, r10, c7, c5, 0 @ I+BTB cache invalidate | 259 | mcr p15, 0, r10, c7, c5, 0 @ I+BTB cache invalidate |
233 | #endif | 260 | #endif |
@@ -235,7 +262,8 @@ __v7_setup: | |||
235 | #ifdef CONFIG_MMU | 262 | #ifdef CONFIG_MMU |
236 | mcr p15, 0, r10, c8, c7, 0 @ invalidate I + D TLBs | 263 | mcr p15, 0, r10, c8, c7, 0 @ invalidate I + D TLBs |
237 | mcr p15, 0, r10, c2, c0, 2 @ TTB control register | 264 | mcr p15, 0, r10, c2, c0, 2 @ TTB control register |
238 | orr r4, r4, #TTB_FLAGS | 265 | ALT_SMP(orr r4, r4, #TTB_FLAGS_SMP) |
266 | ALT_UP(orr r4, r4, #TTB_FLAGS_UP) | ||
239 | mcr p15, 0, r4, c2, c0, 1 @ load TTB1 | 267 | mcr p15, 0, r4, c2, c0, 1 @ load TTB1 |
240 | mov r10, #0x1f @ domains 0, 1 = manager | 268 | mov r10, #0x1f @ domains 0, 1 = manager |
241 | mcr p15, 0, r10, c3, c0, 0 @ load domain access register | 269 | mcr p15, 0, r10, c3, c0, 0 @ load domain access register |
@@ -323,6 +351,35 @@ cpu_elf_name: | |||
323 | 351 | ||
324 | .section ".proc.info.init", #alloc, #execinstr | 352 | .section ".proc.info.init", #alloc, #execinstr |
325 | 353 | ||
354 | .type __v7_ca9mp_proc_info, #object | ||
355 | __v7_ca9mp_proc_info: | ||
356 | .long 0x410fc090 @ Required ID value | ||
357 | .long 0xff0ffff0 @ Mask for ID | ||
358 | ALT_SMP(.long \ | ||
359 | PMD_TYPE_SECT | \ | ||
360 | PMD_SECT_AP_WRITE | \ | ||
361 | PMD_SECT_AP_READ | \ | ||
362 | PMD_FLAGS_SMP) | ||
363 | ALT_UP(.long \ | ||
364 | PMD_TYPE_SECT | \ | ||
365 | PMD_SECT_AP_WRITE | \ | ||
366 | PMD_SECT_AP_READ | \ | ||
367 | PMD_FLAGS_UP) | ||
368 | .long PMD_TYPE_SECT | \ | ||
369 | PMD_SECT_XN | \ | ||
370 | PMD_SECT_AP_WRITE | \ | ||
371 | PMD_SECT_AP_READ | ||
372 | b __v7_ca9mp_setup | ||
373 | .long cpu_arch_name | ||
374 | .long cpu_elf_name | ||
375 | .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP | ||
376 | .long cpu_v7_name | ||
377 | .long v7_processor_functions | ||
378 | .long v7wbi_tlb_fns | ||
379 | .long v6_user_fns | ||
380 | .long v7_cache_fns | ||
381 | .size __v7_ca9mp_proc_info, . - __v7_ca9mp_proc_info | ||
382 | |||
326 | /* | 383 | /* |
327 | * Match any ARMv7 processor core. | 384 | * Match any ARMv7 processor core. |
328 | */ | 385 | */ |
@@ -330,10 +387,16 @@ cpu_elf_name: | |||
330 | __v7_proc_info: | 387 | __v7_proc_info: |
331 | .long 0x000f0000 @ Required ID value | 388 | .long 0x000f0000 @ Required ID value |
332 | .long 0x000f0000 @ Mask for ID | 389 | .long 0x000f0000 @ Mask for ID |
333 | .long PMD_TYPE_SECT | \ | 390 | ALT_SMP(.long \ |
391 | PMD_TYPE_SECT | \ | ||
392 | PMD_SECT_AP_WRITE | \ | ||
393 | PMD_SECT_AP_READ | \ | ||
394 | PMD_FLAGS_SMP) | ||
395 | ALT_UP(.long \ | ||
396 | PMD_TYPE_SECT | \ | ||
334 | PMD_SECT_AP_WRITE | \ | 397 | PMD_SECT_AP_WRITE | \ |
335 | PMD_SECT_AP_READ | \ | 398 | PMD_SECT_AP_READ | \ |
336 | PMD_FLAGS | 399 | PMD_FLAGS_UP) |
337 | .long PMD_TYPE_SECT | \ | 400 | .long PMD_TYPE_SECT | \ |
338 | PMD_SECT_XN | \ | 401 | PMD_SECT_XN | \ |
339 | PMD_SECT_AP_WRITE | \ | 402 | PMD_SECT_AP_WRITE | \ |
diff --git a/arch/arm/mm/tlb-v7.S b/arch/arm/mm/tlb-v7.S index f3f288a9546d..53cd5b454673 100644 --- a/arch/arm/mm/tlb-v7.S +++ b/arch/arm/mm/tlb-v7.S | |||
@@ -13,6 +13,7 @@ | |||
13 | */ | 13 | */ |
14 | #include <linux/init.h> | 14 | #include <linux/init.h> |
15 | #include <linux/linkage.h> | 15 | #include <linux/linkage.h> |
16 | #include <asm/assembler.h> | ||
16 | #include <asm/asm-offsets.h> | 17 | #include <asm/asm-offsets.h> |
17 | #include <asm/page.h> | 18 | #include <asm/page.h> |
18 | #include <asm/tlbflush.h> | 19 | #include <asm/tlbflush.h> |
@@ -41,20 +42,15 @@ ENTRY(v7wbi_flush_user_tlb_range) | |||
41 | orr r0, r3, r0, lsl #PAGE_SHIFT @ Create initial MVA | 42 | orr r0, r3, r0, lsl #PAGE_SHIFT @ Create initial MVA |
42 | mov r1, r1, lsl #PAGE_SHIFT | 43 | mov r1, r1, lsl #PAGE_SHIFT |
43 | 1: | 44 | 1: |
44 | #ifdef CONFIG_SMP | 45 | ALT_SMP(mcr p15, 0, r0, c8, c3, 1) @ TLB invalidate U MVA (shareable) |
45 | mcr p15, 0, r0, c8, c3, 1 @ TLB invalidate U MVA (shareable) | 46 | ALT_UP(mcr p15, 0, r0, c8, c7, 1) @ TLB invalidate U MVA |
46 | #else | 47 | |
47 | mcr p15, 0, r0, c8, c7, 1 @ TLB invalidate U MVA | ||
48 | #endif | ||
49 | add r0, r0, #PAGE_SZ | 48 | add r0, r0, #PAGE_SZ |
50 | cmp r0, r1 | 49 | cmp r0, r1 |
51 | blo 1b | 50 | blo 1b |
52 | mov ip, #0 | 51 | mov ip, #0 |
53 | #ifdef CONFIG_SMP | 52 | ALT_SMP(mcr p15, 0, ip, c7, c1, 6) @ flush BTAC/BTB Inner Shareable |
54 | mcr p15, 0, ip, c7, c1, 6 @ flush BTAC/BTB Inner Shareable | 53 | ALT_UP(mcr p15, 0, ip, c7, c5, 6) @ flush BTAC/BTB |
55 | #else | ||
56 | mcr p15, 0, ip, c7, c5, 6 @ flush BTAC/BTB | ||
57 | #endif | ||
58 | dsb | 54 | dsb |
59 | mov pc, lr | 55 | mov pc, lr |
60 | ENDPROC(v7wbi_flush_user_tlb_range) | 56 | ENDPROC(v7wbi_flush_user_tlb_range) |
@@ -74,20 +70,14 @@ ENTRY(v7wbi_flush_kern_tlb_range) | |||
74 | mov r0, r0, lsl #PAGE_SHIFT | 70 | mov r0, r0, lsl #PAGE_SHIFT |
75 | mov r1, r1, lsl #PAGE_SHIFT | 71 | mov r1, r1, lsl #PAGE_SHIFT |
76 | 1: | 72 | 1: |
77 | #ifdef CONFIG_SMP | 73 | ALT_SMP(mcr p15, 0, r0, c8, c3, 1) @ TLB invalidate U MVA (shareable) |
78 | mcr p15, 0, r0, c8, c3, 1 @ TLB invalidate U MVA (shareable) | 74 | ALT_UP(mcr p15, 0, r0, c8, c7, 1) @ TLB invalidate U MVA |
79 | #else | ||
80 | mcr p15, 0, r0, c8, c7, 1 @ TLB invalidate U MVA | ||
81 | #endif | ||
82 | add r0, r0, #PAGE_SZ | 75 | add r0, r0, #PAGE_SZ |
83 | cmp r0, r1 | 76 | cmp r0, r1 |
84 | blo 1b | 77 | blo 1b |
85 | mov r2, #0 | 78 | mov r2, #0 |
86 | #ifdef CONFIG_SMP | 79 | ALT_SMP(mcr p15, 0, r2, c7, c1, 6) @ flush BTAC/BTB Inner Shareable |
87 | mcr p15, 0, r2, c7, c1, 6 @ flush BTAC/BTB Inner Shareable | 80 | ALT_UP(mcr p15, 0, r2, c7, c5, 6) @ flush BTAC/BTB |
88 | #else | ||
89 | mcr p15, 0, r2, c7, c5, 6 @ flush BTAC/BTB | ||
90 | #endif | ||
91 | dsb | 81 | dsb |
92 | isb | 82 | isb |
93 | mov pc, lr | 83 | mov pc, lr |
@@ -99,5 +89,6 @@ ENDPROC(v7wbi_flush_kern_tlb_range) | |||
99 | ENTRY(v7wbi_tlb_fns) | 89 | ENTRY(v7wbi_tlb_fns) |
100 | .long v7wbi_flush_user_tlb_range | 90 | .long v7wbi_flush_user_tlb_range |
101 | .long v7wbi_flush_kern_tlb_range | 91 | .long v7wbi_flush_kern_tlb_range |
102 | .long v7wbi_tlb_flags | 92 | ALT_SMP(.long v7wbi_tlb_flags_smp) |
93 | ALT_UP(.long v7wbi_tlb_flags_up) | ||
103 | .size v7wbi_tlb_fns, . - v7wbi_tlb_fns | 94 | .size v7wbi_tlb_fns, . - v7wbi_tlb_fns |
diff --git a/arch/arm/plat-nomadik/gpio.c b/arch/arm/plat-nomadik/gpio.c index 977c8f9a07a2..85e6fd212a41 100644 --- a/arch/arm/plat-nomadik/gpio.c +++ b/arch/arm/plat-nomadik/gpio.c | |||
@@ -102,6 +102,22 @@ static void __nmk_gpio_make_input(struct nmk_gpio_chip *nmk_chip, | |||
102 | writel(1 << offset, nmk_chip->addr + NMK_GPIO_DIRC); | 102 | writel(1 << offset, nmk_chip->addr + NMK_GPIO_DIRC); |
103 | } | 103 | } |
104 | 104 | ||
105 | static void __nmk_gpio_set_output(struct nmk_gpio_chip *nmk_chip, | ||
106 | unsigned offset, int val) | ||
107 | { | ||
108 | if (val) | ||
109 | writel(1 << offset, nmk_chip->addr + NMK_GPIO_DATS); | ||
110 | else | ||
111 | writel(1 << offset, nmk_chip->addr + NMK_GPIO_DATC); | ||
112 | } | ||
113 | |||
114 | static void __nmk_gpio_make_output(struct nmk_gpio_chip *nmk_chip, | ||
115 | unsigned offset, int val) | ||
116 | { | ||
117 | writel(1 << offset, nmk_chip->addr + NMK_GPIO_DIRS); | ||
118 | __nmk_gpio_set_output(nmk_chip, offset, val); | ||
119 | } | ||
120 | |||
105 | static void __nmk_config_pin(struct nmk_gpio_chip *nmk_chip, unsigned offset, | 121 | static void __nmk_config_pin(struct nmk_gpio_chip *nmk_chip, unsigned offset, |
106 | pin_cfg_t cfg) | 122 | pin_cfg_t cfg) |
107 | { | 123 | { |
@@ -118,20 +134,29 @@ static void __nmk_config_pin(struct nmk_gpio_chip *nmk_chip, unsigned offset, | |||
118 | [3] /* illegal */ = "??" | 134 | [3] /* illegal */ = "??" |
119 | }; | 135 | }; |
120 | static const char *slpmnames[] = { | 136 | static const char *slpmnames[] = { |
121 | [NMK_GPIO_SLPM_INPUT] = "input", | 137 | [NMK_GPIO_SLPM_INPUT] = "input/wakeup", |
122 | [NMK_GPIO_SLPM_NOCHANGE] = "no-change", | 138 | [NMK_GPIO_SLPM_NOCHANGE] = "no-change/no-wakeup", |
123 | }; | 139 | }; |
124 | 140 | ||
125 | int pin = PIN_NUM(cfg); | 141 | int pin = PIN_NUM(cfg); |
126 | int pull = PIN_PULL(cfg); | 142 | int pull = PIN_PULL(cfg); |
127 | int af = PIN_ALT(cfg); | 143 | int af = PIN_ALT(cfg); |
128 | int slpm = PIN_SLPM(cfg); | 144 | int slpm = PIN_SLPM(cfg); |
145 | int output = PIN_DIR(cfg); | ||
146 | int val = PIN_VAL(cfg); | ||
129 | 147 | ||
130 | dev_dbg(nmk_chip->chip.dev, "pin %d: af %s, pull %s, slpm %s\n", | 148 | dev_dbg(nmk_chip->chip.dev, "pin %d: af %s, pull %s, slpm %s (%s%s)\n", |
131 | pin, afnames[af], pullnames[pull], slpmnames[slpm]); | 149 | pin, afnames[af], pullnames[pull], slpmnames[slpm], |
150 | output ? "output " : "input", | ||
151 | output ? (val ? "high" : "low") : ""); | ||
152 | |||
153 | if (output) | ||
154 | __nmk_gpio_make_output(nmk_chip, offset, val); | ||
155 | else { | ||
156 | __nmk_gpio_make_input(nmk_chip, offset); | ||
157 | __nmk_gpio_set_pull(nmk_chip, offset, pull); | ||
158 | } | ||
132 | 159 | ||
133 | __nmk_gpio_make_input(nmk_chip, offset); | ||
134 | __nmk_gpio_set_pull(nmk_chip, offset, pull); | ||
135 | __nmk_gpio_set_slpm(nmk_chip, offset, slpm); | 160 | __nmk_gpio_set_slpm(nmk_chip, offset, slpm); |
136 | __nmk_gpio_set_mode(nmk_chip, offset, af); | 161 | __nmk_gpio_set_mode(nmk_chip, offset, af); |
137 | } | 162 | } |
@@ -200,6 +225,10 @@ EXPORT_SYMBOL(nmk_config_pins); | |||
200 | * changed to an input (with pullup/down enabled) in sleep and deep sleep. If | 225 | * changed to an input (with pullup/down enabled) in sleep and deep sleep. If |
201 | * @mode is NMK_GPIO_SLPM_NOCHANGE, the pin remains in the state it was | 226 | * @mode is NMK_GPIO_SLPM_NOCHANGE, the pin remains in the state it was |
202 | * configured even when in sleep and deep sleep. | 227 | * configured even when in sleep and deep sleep. |
228 | * | ||
229 | * On DB8500v2 onwards, this setting loses the previous meaning and instead | ||
230 | * indicates if wakeup detection is enabled on the pin. Note that | ||
231 | * enable_irq_wake() will automatically enable wakeup detection. | ||
203 | */ | 232 | */ |
204 | int nmk_gpio_set_slpm(int gpio, enum nmk_gpio_slpm mode) | 233 | int nmk_gpio_set_slpm(int gpio, enum nmk_gpio_slpm mode) |
205 | { | 234 | { |
@@ -367,7 +396,27 @@ static void nmk_gpio_irq_unmask(unsigned int irq) | |||
367 | 396 | ||
368 | static int nmk_gpio_irq_set_wake(unsigned int irq, unsigned int on) | 397 | static int nmk_gpio_irq_set_wake(unsigned int irq, unsigned int on) |
369 | { | 398 | { |
370 | return nmk_gpio_irq_modify(irq, WAKE, on); | 399 | struct nmk_gpio_chip *nmk_chip; |
400 | unsigned long flags; | ||
401 | int gpio; | ||
402 | |||
403 | gpio = NOMADIK_IRQ_TO_GPIO(irq); | ||
404 | nmk_chip = get_irq_chip_data(irq); | ||
405 | if (!nmk_chip) | ||
406 | return -EINVAL; | ||
407 | |||
408 | spin_lock_irqsave(&nmk_chip->lock, flags); | ||
409 | #ifdef CONFIG_ARCH_U8500 | ||
410 | if (cpu_is_u8500v2()) { | ||
411 | __nmk_gpio_set_slpm(nmk_chip, gpio, | ||
412 | on ? NMK_GPIO_SLPM_WAKEUP_ENABLE | ||
413 | : NMK_GPIO_SLPM_WAKEUP_DISABLE); | ||
414 | } | ||
415 | #endif | ||
416 | __nmk_gpio_irq_modify(nmk_chip, gpio, WAKE, on); | ||
417 | spin_unlock_irqrestore(&nmk_chip->lock, flags); | ||
418 | |||
419 | return 0; | ||
371 | } | 420 | } |
372 | 421 | ||
373 | static int nmk_gpio_irq_set_type(unsigned int irq, unsigned int type) | 422 | static int nmk_gpio_irq_set_type(unsigned int irq, unsigned int type) |
@@ -495,12 +544,8 @@ static void nmk_gpio_set_output(struct gpio_chip *chip, unsigned offset, | |||
495 | { | 544 | { |
496 | struct nmk_gpio_chip *nmk_chip = | 545 | struct nmk_gpio_chip *nmk_chip = |
497 | container_of(chip, struct nmk_gpio_chip, chip); | 546 | container_of(chip, struct nmk_gpio_chip, chip); |
498 | u32 bit = 1 << offset; | ||
499 | 547 | ||
500 | if (val) | 548 | __nmk_gpio_set_output(nmk_chip, offset, val); |
501 | writel(bit, nmk_chip->addr + NMK_GPIO_DATS); | ||
502 | else | ||
503 | writel(bit, nmk_chip->addr + NMK_GPIO_DATC); | ||
504 | } | 549 | } |
505 | 550 | ||
506 | static int nmk_gpio_make_output(struct gpio_chip *chip, unsigned offset, | 551 | static int nmk_gpio_make_output(struct gpio_chip *chip, unsigned offset, |
@@ -509,8 +554,7 @@ static int nmk_gpio_make_output(struct gpio_chip *chip, unsigned offset, | |||
509 | struct nmk_gpio_chip *nmk_chip = | 554 | struct nmk_gpio_chip *nmk_chip = |
510 | container_of(chip, struct nmk_gpio_chip, chip); | 555 | container_of(chip, struct nmk_gpio_chip, chip); |
511 | 556 | ||
512 | writel(1 << offset, nmk_chip->addr + NMK_GPIO_DIRS); | 557 | __nmk_gpio_make_output(nmk_chip, offset, val); |
513 | nmk_gpio_set_output(chip, offset, val); | ||
514 | 558 | ||
515 | return 0; | 559 | return 0; |
516 | } | 560 | } |
@@ -534,7 +578,7 @@ static struct gpio_chip nmk_gpio_template = { | |||
534 | .can_sleep = 0, | 578 | .can_sleep = 0, |
535 | }; | 579 | }; |
536 | 580 | ||
537 | static int __init nmk_gpio_probe(struct platform_device *dev) | 581 | static int __devinit nmk_gpio_probe(struct platform_device *dev) |
538 | { | 582 | { |
539 | struct nmk_gpio_platform_data *pdata = dev->dev.platform_data; | 583 | struct nmk_gpio_platform_data *pdata = dev->dev.platform_data; |
540 | struct nmk_gpio_chip *nmk_chip; | 584 | struct nmk_gpio_chip *nmk_chip; |
diff --git a/arch/arm/plat-nomadik/include/plat/gpio.h b/arch/arm/plat-nomadik/include/plat/gpio.h index aba355101f49..67b113d639d8 100644 --- a/arch/arm/plat-nomadik/include/plat/gpio.h +++ b/arch/arm/plat-nomadik/include/plat/gpio.h | |||
@@ -65,7 +65,9 @@ enum nmk_gpio_pull { | |||
65 | /* Sleep mode */ | 65 | /* Sleep mode */ |
66 | enum nmk_gpio_slpm { | 66 | enum nmk_gpio_slpm { |
67 | NMK_GPIO_SLPM_INPUT, | 67 | NMK_GPIO_SLPM_INPUT, |
68 | NMK_GPIO_SLPM_WAKEUP_ENABLE = NMK_GPIO_SLPM_INPUT, | ||
68 | NMK_GPIO_SLPM_NOCHANGE, | 69 | NMK_GPIO_SLPM_NOCHANGE, |
70 | NMK_GPIO_SLPM_WAKEUP_DISABLE = NMK_GPIO_SLPM_NOCHANGE, | ||
69 | }; | 71 | }; |
70 | 72 | ||
71 | extern int nmk_gpio_set_slpm(int gpio, enum nmk_gpio_slpm mode); | 73 | extern int nmk_gpio_set_slpm(int gpio, enum nmk_gpio_slpm mode); |
diff --git a/arch/arm/plat-nomadik/include/plat/pincfg.h b/arch/arm/plat-nomadik/include/plat/pincfg.h index 7eed11c1038d..8c5ae3f2acf8 100644 --- a/arch/arm/plat-nomadik/include/plat/pincfg.h +++ b/arch/arm/plat-nomadik/include/plat/pincfg.h | |||
@@ -19,12 +19,16 @@ | |||
19 | * bit 9..10 - Alternate Function Selection | 19 | * bit 9..10 - Alternate Function Selection |
20 | * bit 11..12 - Pull up/down state | 20 | * bit 11..12 - Pull up/down state |
21 | * bit 13 - Sleep mode behaviour | 21 | * bit 13 - Sleep mode behaviour |
22 | * bit 14 - (sleep mode) Direction | ||
23 | * bit 15 - (sleep mode) Value (if output) | ||
22 | * | 24 | * |
23 | * to facilitate the definition, the following macros are provided | 25 | * to facilitate the definition, the following macros are provided |
24 | * | 26 | * |
25 | * PIN_CFG_DEFAULT - default config (0): | 27 | * PIN_CFG_DEFAULT - default config (0): |
26 | * pull up/down = disabled | 28 | * pull up/down = disabled |
27 | * sleep mode = input | 29 | * sleep mode = input/wakeup |
30 | * (sleep mode) direction = input | ||
31 | * (sleep mode) value = low | ||
28 | * | 32 | * |
29 | * PIN_CFG - default config with alternate function | 33 | * PIN_CFG - default config with alternate function |
30 | * PIN_CFG_PULL - default config with alternate function and pull up/down | 34 | * PIN_CFG_PULL - default config with alternate function and pull up/down |
@@ -53,8 +57,36 @@ typedef unsigned long pin_cfg_t; | |||
53 | #define PIN_SLPM_SHIFT 13 | 57 | #define PIN_SLPM_SHIFT 13 |
54 | #define PIN_SLPM_MASK (0x1 << PIN_SLPM_SHIFT) | 58 | #define PIN_SLPM_MASK (0x1 << PIN_SLPM_SHIFT) |
55 | #define PIN_SLPM(x) (((x) & PIN_SLPM_MASK) >> PIN_SLPM_SHIFT) | 59 | #define PIN_SLPM(x) (((x) & PIN_SLPM_MASK) >> PIN_SLPM_SHIFT) |
56 | #define PIN_SLPM_INPUT (NMK_GPIO_SLPM_INPUT << PIN_SLPM_SHIFT) | 60 | #define PIN_SLPM_MAKE_INPUT (NMK_GPIO_SLPM_INPUT << PIN_SLPM_SHIFT) |
57 | #define PIN_SLPM_NOCHANGE (NMK_GPIO_SLPM_NOCHANGE << PIN_SLPM_SHIFT) | 61 | #define PIN_SLPM_NOCHANGE (NMK_GPIO_SLPM_NOCHANGE << PIN_SLPM_SHIFT) |
62 | /* These two replace the above in DB8500v2+ */ | ||
63 | #define PIN_SLPM_WAKEUP_ENABLE (NMK_GPIO_SLPM_WAKEUP_ENABLE << PIN_SLPM_SHIFT) | ||
64 | #define PIN_SLPM_WAKEUP_DISABLE (NMK_GPIO_SLPM_WAKEUP_DISABLE << PIN_SLPM_SHIFT) | ||
65 | |||
66 | #define PIN_DIR_SHIFT 14 | ||
67 | #define PIN_DIR_MASK (0x1 << PIN_DIR_SHIFT) | ||
68 | #define PIN_DIR(x) (((x) & PIN_DIR_MASK) >> PIN_DIR_SHIFT) | ||
69 | #define PIN_DIR_INPUT (0 << PIN_DIR_SHIFT) | ||
70 | #define PIN_DIR_OUTPUT (1 << PIN_DIR_SHIFT) | ||
71 | |||
72 | #define PIN_VAL_SHIFT 15 | ||
73 | #define PIN_VAL_MASK (0x1 << PIN_VAL_SHIFT) | ||
74 | #define PIN_VAL(x) (((x) & PIN_VAL_MASK) >> PIN_VAL_SHIFT) | ||
75 | #define PIN_VAL_LOW (0 << PIN_VAL_SHIFT) | ||
76 | #define PIN_VAL_HIGH (1 << PIN_VAL_SHIFT) | ||
77 | |||
78 | /* Shortcuts. Use these instead of separate DIR and VAL. */ | ||
79 | #define PIN_INPUT PIN_DIR_INPUT | ||
80 | #define PIN_OUTPUT_LOW (PIN_DIR_OUTPUT | PIN_VAL_LOW) | ||
81 | #define PIN_OUTPUT_HIGH (PIN_DIR_OUTPUT | PIN_VAL_HIGH) | ||
82 | |||
83 | /* | ||
84 | * These are the same as the ones above, but should make more sense to the | ||
85 | * reader when seen along with a setting a pin to AF mode. | ||
86 | */ | ||
87 | #define PIN_SLPM_INPUT PIN_INPUT | ||
88 | #define PIN_SLPM_OUTPUT_LOW PIN_OUTPUT_LOW | ||
89 | #define PIN_SLPM_OUTPUT_HIGH PIN_OUTPUT_HIGH | ||
58 | 90 | ||
59 | #define PIN_CFG_DEFAULT (PIN_PULL_NONE | PIN_SLPM_INPUT) | 91 | #define PIN_CFG_DEFAULT (PIN_PULL_NONE | PIN_SLPM_INPUT) |
60 | 92 | ||
diff --git a/arch/arm/plat-nomadik/timer.c b/arch/arm/plat-nomadik/timer.c index ea3ca86c5283..aedf9c1d645e 100644 --- a/arch/arm/plat-nomadik/timer.c +++ b/arch/arm/plat-nomadik/timer.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * linux/arch/arm/mach-nomadik/timer.c | 2 | * linux/arch/arm/plat-nomadik/timer.c |
3 | * | 3 | * |
4 | * Copyright (C) 2008 STMicroelectronics | 4 | * Copyright (C) 2008 STMicroelectronics |
5 | * Copyright (C) 2010 Alessandro Rubini | 5 | * Copyright (C) 2010 Alessandro Rubini |
@@ -75,7 +75,7 @@ static void nmdk_clkevt_mode(enum clock_event_mode mode, | |||
75 | cr = readl(mtu_base + MTU_CR(1)); | 75 | cr = readl(mtu_base + MTU_CR(1)); |
76 | writel(0, mtu_base + MTU_LR(1)); | 76 | writel(0, mtu_base + MTU_LR(1)); |
77 | writel(cr | MTU_CRn_ENA, mtu_base + MTU_CR(1)); | 77 | writel(cr | MTU_CRn_ENA, mtu_base + MTU_CR(1)); |
78 | writel(0x2, mtu_base + MTU_IMSC); | 78 | writel(1 << 1, mtu_base + MTU_IMSC); |
79 | break; | 79 | break; |
80 | case CLOCK_EVT_MODE_SHUTDOWN: | 80 | case CLOCK_EVT_MODE_SHUTDOWN: |
81 | case CLOCK_EVT_MODE_UNUSED: | 81 | case CLOCK_EVT_MODE_UNUSED: |
@@ -131,25 +131,23 @@ void __init nmdk_timer_init(void) | |||
131 | { | 131 | { |
132 | unsigned long rate; | 132 | unsigned long rate; |
133 | struct clk *clk0; | 133 | struct clk *clk0; |
134 | struct clk *clk1; | 134 | u32 cr = MTU_CRn_32BITS; |
135 | u32 cr; | ||
136 | 135 | ||
137 | clk0 = clk_get_sys("mtu0", NULL); | 136 | clk0 = clk_get_sys("mtu0", NULL); |
138 | BUG_ON(IS_ERR(clk0)); | 137 | BUG_ON(IS_ERR(clk0)); |
139 | 138 | ||
140 | clk1 = clk_get_sys("mtu1", NULL); | ||
141 | BUG_ON(IS_ERR(clk1)); | ||
142 | |||
143 | clk_enable(clk0); | 139 | clk_enable(clk0); |
144 | clk_enable(clk1); | ||
145 | 140 | ||
146 | /* | 141 | /* |
147 | * Tick rate is 2.4MHz for Nomadik and 110MHz for ux500: | 142 | * Tick rate is 2.4MHz for Nomadik and 2.4Mhz, 100MHz or 133 MHz |
148 | * use a divide-by-16 counter if it's more than 16MHz | 143 | * for ux500. |
144 | * Use a divide-by-16 counter if the tick rate is more than 32MHz. | ||
145 | * At 32 MHz, the timer (with 32 bit counter) can be programmed | ||
146 | * to wake-up at a max 127s a head in time. Dividing a 2.4 MHz timer | ||
147 | * with 16 gives too low timer resolution. | ||
149 | */ | 148 | */ |
150 | cr = MTU_CRn_32BITS;; | ||
151 | rate = clk_get_rate(clk0); | 149 | rate = clk_get_rate(clk0); |
152 | if (rate > 16 << 20) { | 150 | if (rate > 32000000) { |
153 | rate /= 16; | 151 | rate /= 16; |
154 | cr |= MTU_CRn_PRESCALE_16; | 152 | cr |= MTU_CRn_PRESCALE_16; |
155 | } else { | 153 | } else { |
@@ -170,15 +168,8 @@ void __init nmdk_timer_init(void) | |||
170 | pr_err("timer: failed to initialize clock source %s\n", | 168 | pr_err("timer: failed to initialize clock source %s\n", |
171 | nmdk_clksrc.name); | 169 | nmdk_clksrc.name); |
172 | 170 | ||
173 | /* Timer 1 is used for events, fix according to rate */ | 171 | /* Timer 1 is used for events */ |
174 | cr = MTU_CRn_32BITS; | 172 | |
175 | rate = clk_get_rate(clk1); | ||
176 | if (rate > 16 << 20) { | ||
177 | rate /= 16; | ||
178 | cr |= MTU_CRn_PRESCALE_16; | ||
179 | } else { | ||
180 | cr |= MTU_CRn_PRESCALE_1; | ||
181 | } | ||
182 | clockevents_calc_mult_shift(&nmdk_clkevt, rate, MTU_MIN_RANGE); | 173 | clockevents_calc_mult_shift(&nmdk_clkevt, rate, MTU_MIN_RANGE); |
183 | 174 | ||
184 | writel(cr | MTU_CRn_ONESHOT, mtu_base + MTU_CR(1)); /* off, currently */ | 175 | writel(cr | MTU_CRn_ONESHOT, mtu_base + MTU_CR(1)); /* off, currently */ |
diff --git a/arch/arm/plat-omap/include/plat/smp.h b/arch/arm/plat-omap/include/plat/smp.h index 5177a9c5a25a..ecd6a488c497 100644 --- a/arch/arm/plat-omap/include/plat/smp.h +++ b/arch/arm/plat-omap/include/plat/smp.h | |||
@@ -18,6 +18,7 @@ | |||
18 | #define OMAP_ARCH_SMP_H | 18 | #define OMAP_ARCH_SMP_H |
19 | 19 | ||
20 | #include <asm/hardware/gic.h> | 20 | #include <asm/hardware/gic.h> |
21 | #include <asm/smp_mpidr.h> | ||
21 | 22 | ||
22 | /* Needed for secondary core boot */ | 23 | /* Needed for secondary core boot */ |
23 | extern void omap_secondary_startup(void); | 24 | extern void omap_secondary_startup(void); |
@@ -33,15 +34,4 @@ static inline void smp_cross_call(const struct cpumask *mask) | |||
33 | gic_raise_softirq(mask, 1); | 34 | gic_raise_softirq(mask, 1); |
34 | } | 35 | } |
35 | 36 | ||
36 | /* | ||
37 | * Read MPIDR: Multiprocessor affinity register | ||
38 | */ | ||
39 | #define hard_smp_processor_id() \ | ||
40 | ({ \ | ||
41 | unsigned int cpunum; \ | ||
42 | __asm__("mrc p15, 0, %0, c0, c0, 5" \ | ||
43 | : "=r" (cpunum)); \ | ||
44 | cpunum &= 0x0F; \ | ||
45 | }) | ||
46 | |||
47 | #endif | 37 | #endif |
diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c index 226b2e858d6c..10b3b4c63372 100644 --- a/arch/arm/plat-omap/sram.c +++ b/arch/arm/plat-omap/sram.c | |||
@@ -220,20 +220,7 @@ void __init omap_map_sram(void) | |||
220 | if (omap_sram_size == 0) | 220 | if (omap_sram_size == 0) |
221 | return; | 221 | return; |
222 | 222 | ||
223 | if (cpu_is_omap24xx()) { | ||
224 | omap_sram_io_desc[0].virtual = OMAP2_SRAM_VA; | ||
225 | |||
226 | base = OMAP2_SRAM_PA; | ||
227 | base = ROUND_DOWN(base, PAGE_SIZE); | ||
228 | omap_sram_io_desc[0].pfn = __phys_to_pfn(base); | ||
229 | } | ||
230 | |||
231 | if (cpu_is_omap34xx()) { | 223 | if (cpu_is_omap34xx()) { |
232 | omap_sram_io_desc[0].virtual = OMAP3_SRAM_VA; | ||
233 | base = OMAP3_SRAM_PA; | ||
234 | base = ROUND_DOWN(base, PAGE_SIZE); | ||
235 | omap_sram_io_desc[0].pfn = __phys_to_pfn(base); | ||
236 | |||
237 | /* | 224 | /* |
238 | * SRAM must be marked as non-cached on OMAP3 since the | 225 | * SRAM must be marked as non-cached on OMAP3 since the |
239 | * CORE DPLL M2 divider change code (in SRAM) runs with the | 226 | * CORE DPLL M2 divider change code (in SRAM) runs with the |
@@ -244,13 +231,11 @@ void __init omap_map_sram(void) | |||
244 | omap_sram_io_desc[0].type = MT_MEMORY_NONCACHED; | 231 | omap_sram_io_desc[0].type = MT_MEMORY_NONCACHED; |
245 | } | 232 | } |
246 | 233 | ||
247 | if (cpu_is_omap44xx()) { | 234 | omap_sram_io_desc[0].virtual = omap_sram_base; |
248 | omap_sram_io_desc[0].virtual = OMAP4_SRAM_VA; | 235 | base = omap_sram_start; |
249 | base = OMAP4_SRAM_PA; | 236 | base = ROUND_DOWN(base, PAGE_SIZE); |
250 | base = ROUND_DOWN(base, PAGE_SIZE); | 237 | omap_sram_io_desc[0].pfn = __phys_to_pfn(base); |
251 | omap_sram_io_desc[0].pfn = __phys_to_pfn(base); | 238 | omap_sram_io_desc[0].length = ROUND_DOWN(omap_sram_size, PAGE_SIZE); |
252 | } | ||
253 | omap_sram_io_desc[0].length = 1024 * 1024; /* Use section desc */ | ||
254 | iotable_init(omap_sram_io_desc, ARRAY_SIZE(omap_sram_io_desc)); | 239 | iotable_init(omap_sram_io_desc, ARRAY_SIZE(omap_sram_io_desc)); |
255 | 240 | ||
256 | printk(KERN_INFO "SRAM: Mapped pa 0x%08lx to va 0x%08lx size: 0x%lx\n", | 241 | printk(KERN_INFO "SRAM: Mapped pa 0x%08lx to va 0x%08lx size: 0x%lx\n", |
diff --git a/arch/arm/plat-s5p/dev-fimc0.c b/arch/arm/plat-s5p/dev-fimc0.c index d3f1a9b5d2b5..608770fc1531 100644 --- a/arch/arm/plat-s5p/dev-fimc0.c +++ b/arch/arm/plat-s5p/dev-fimc0.c | |||
@@ -10,6 +10,7 @@ | |||
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
13 | #include <linux/dma-mapping.h> | ||
13 | #include <linux/platform_device.h> | 14 | #include <linux/platform_device.h> |
14 | #include <linux/interrupt.h> | 15 | #include <linux/interrupt.h> |
15 | #include <linux/ioport.h> | 16 | #include <linux/ioport.h> |
@@ -18,7 +19,7 @@ | |||
18 | static struct resource s5p_fimc0_resource[] = { | 19 | static struct resource s5p_fimc0_resource[] = { |
19 | [0] = { | 20 | [0] = { |
20 | .start = S5P_PA_FIMC0, | 21 | .start = S5P_PA_FIMC0, |
21 | .end = S5P_PA_FIMC0 + SZ_1M - 1, | 22 | .end = S5P_PA_FIMC0 + SZ_4K - 1, |
22 | .flags = IORESOURCE_MEM, | 23 | .flags = IORESOURCE_MEM, |
23 | }, | 24 | }, |
24 | [1] = { | 25 | [1] = { |
@@ -28,9 +29,15 @@ static struct resource s5p_fimc0_resource[] = { | |||
28 | }, | 29 | }, |
29 | }; | 30 | }; |
30 | 31 | ||
32 | static u64 s5p_fimc0_dma_mask = DMA_BIT_MASK(32); | ||
33 | |||
31 | struct platform_device s5p_device_fimc0 = { | 34 | struct platform_device s5p_device_fimc0 = { |
32 | .name = "s5p-fimc", | 35 | .name = "s5p-fimc", |
33 | .id = 0, | 36 | .id = 0, |
34 | .num_resources = ARRAY_SIZE(s5p_fimc0_resource), | 37 | .num_resources = ARRAY_SIZE(s5p_fimc0_resource), |
35 | .resource = s5p_fimc0_resource, | 38 | .resource = s5p_fimc0_resource, |
39 | .dev = { | ||
40 | .dma_mask = &s5p_fimc0_dma_mask, | ||
41 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
42 | }, | ||
36 | }; | 43 | }; |
diff --git a/arch/arm/plat-s5p/dev-fimc1.c b/arch/arm/plat-s5p/dev-fimc1.c index 41bd6986d0ad..76e3a97a87d3 100644 --- a/arch/arm/plat-s5p/dev-fimc1.c +++ b/arch/arm/plat-s5p/dev-fimc1.c | |||
@@ -10,6 +10,7 @@ | |||
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
13 | #include <linux/dma-mapping.h> | ||
13 | #include <linux/platform_device.h> | 14 | #include <linux/platform_device.h> |
14 | #include <linux/interrupt.h> | 15 | #include <linux/interrupt.h> |
15 | #include <linux/ioport.h> | 16 | #include <linux/ioport.h> |
@@ -18,7 +19,7 @@ | |||
18 | static struct resource s5p_fimc1_resource[] = { | 19 | static struct resource s5p_fimc1_resource[] = { |
19 | [0] = { | 20 | [0] = { |
20 | .start = S5P_PA_FIMC1, | 21 | .start = S5P_PA_FIMC1, |
21 | .end = S5P_PA_FIMC1 + SZ_1M - 1, | 22 | .end = S5P_PA_FIMC1 + SZ_4K - 1, |
22 | .flags = IORESOURCE_MEM, | 23 | .flags = IORESOURCE_MEM, |
23 | }, | 24 | }, |
24 | [1] = { | 25 | [1] = { |
@@ -28,9 +29,15 @@ static struct resource s5p_fimc1_resource[] = { | |||
28 | }, | 29 | }, |
29 | }; | 30 | }; |
30 | 31 | ||
32 | static u64 s5p_fimc1_dma_mask = DMA_BIT_MASK(32); | ||
33 | |||
31 | struct platform_device s5p_device_fimc1 = { | 34 | struct platform_device s5p_device_fimc1 = { |
32 | .name = "s5p-fimc", | 35 | .name = "s5p-fimc", |
33 | .id = 1, | 36 | .id = 1, |
34 | .num_resources = ARRAY_SIZE(s5p_fimc1_resource), | 37 | .num_resources = ARRAY_SIZE(s5p_fimc1_resource), |
35 | .resource = s5p_fimc1_resource, | 38 | .resource = s5p_fimc1_resource, |
39 | .dev = { | ||
40 | .dma_mask = &s5p_fimc1_dma_mask, | ||
41 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
42 | }, | ||
36 | }; | 43 | }; |
diff --git a/arch/arm/plat-s5p/dev-fimc2.c b/arch/arm/plat-s5p/dev-fimc2.c index dfddeda6d4a3..24d29816fa2c 100644 --- a/arch/arm/plat-s5p/dev-fimc2.c +++ b/arch/arm/plat-s5p/dev-fimc2.c | |||
@@ -10,6 +10,7 @@ | |||
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
13 | #include <linux/dma-mapping.h> | ||
13 | #include <linux/platform_device.h> | 14 | #include <linux/platform_device.h> |
14 | #include <linux/interrupt.h> | 15 | #include <linux/interrupt.h> |
15 | #include <linux/ioport.h> | 16 | #include <linux/ioport.h> |
@@ -18,7 +19,7 @@ | |||
18 | static struct resource s5p_fimc2_resource[] = { | 19 | static struct resource s5p_fimc2_resource[] = { |
19 | [0] = { | 20 | [0] = { |
20 | .start = S5P_PA_FIMC2, | 21 | .start = S5P_PA_FIMC2, |
21 | .end = S5P_PA_FIMC2 + SZ_1M - 1, | 22 | .end = S5P_PA_FIMC2 + SZ_4K - 1, |
22 | .flags = IORESOURCE_MEM, | 23 | .flags = IORESOURCE_MEM, |
23 | }, | 24 | }, |
24 | [1] = { | 25 | [1] = { |
@@ -28,9 +29,15 @@ static struct resource s5p_fimc2_resource[] = { | |||
28 | }, | 29 | }, |
29 | }; | 30 | }; |
30 | 31 | ||
32 | static u64 s5p_fimc2_dma_mask = DMA_BIT_MASK(32); | ||
33 | |||
31 | struct platform_device s5p_device_fimc2 = { | 34 | struct platform_device s5p_device_fimc2 = { |
32 | .name = "s5p-fimc", | 35 | .name = "s5p-fimc", |
33 | .id = 2, | 36 | .id = 2, |
34 | .num_resources = ARRAY_SIZE(s5p_fimc2_resource), | 37 | .num_resources = ARRAY_SIZE(s5p_fimc2_resource), |
35 | .resource = s5p_fimc2_resource, | 38 | .resource = s5p_fimc2_resource, |
39 | .dev = { | ||
40 | .dma_mask = &s5p_fimc2_dma_mask, | ||
41 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
42 | }, | ||
36 | }; | 43 | }; |
diff --git a/arch/arm/plat-samsung/gpio-config.c b/arch/arm/plat-samsung/gpio-config.c index 57b68a50f45e..e3d41eaed1ff 100644 --- a/arch/arm/plat-samsung/gpio-config.c +++ b/arch/arm/plat-samsung/gpio-config.c | |||
@@ -273,13 +273,13 @@ s5p_gpio_drvstr_t s5p_gpio_get_drvstr(unsigned int pin) | |||
273 | if (!chip) | 273 | if (!chip) |
274 | return -EINVAL; | 274 | return -EINVAL; |
275 | 275 | ||
276 | off = chip->chip.base - pin; | 276 | off = pin - chip->chip.base; |
277 | shift = off * 2; | 277 | shift = off * 2; |
278 | reg = chip->base + 0x0C; | 278 | reg = chip->base + 0x0C; |
279 | 279 | ||
280 | drvstr = __raw_readl(reg); | 280 | drvstr = __raw_readl(reg); |
281 | drvstr = 0xffff & (0x3 << shift); | ||
282 | drvstr = drvstr >> shift; | 281 | drvstr = drvstr >> shift; |
282 | drvstr &= 0x3; | ||
283 | 283 | ||
284 | return (__force s5p_gpio_drvstr_t)drvstr; | 284 | return (__force s5p_gpio_drvstr_t)drvstr; |
285 | } | 285 | } |
@@ -296,11 +296,12 @@ int s5p_gpio_set_drvstr(unsigned int pin, s5p_gpio_drvstr_t drvstr) | |||
296 | if (!chip) | 296 | if (!chip) |
297 | return -EINVAL; | 297 | return -EINVAL; |
298 | 298 | ||
299 | off = chip->chip.base - pin; | 299 | off = pin - chip->chip.base; |
300 | shift = off * 2; | 300 | shift = off * 2; |
301 | reg = chip->base + 0x0C; | 301 | reg = chip->base + 0x0C; |
302 | 302 | ||
303 | tmp = __raw_readl(reg); | 303 | tmp = __raw_readl(reg); |
304 | tmp &= ~(0x3 << shift); | ||
304 | tmp |= drvstr << shift; | 305 | tmp |= drvstr << shift; |
305 | 306 | ||
306 | __raw_writel(tmp, reg); | 307 | __raw_writel(tmp, reg); |
diff --git a/arch/arm/plat-samsung/include/plat/gpio-cfg.h b/arch/arm/plat-samsung/include/plat/gpio-cfg.h index db4112c6f2be..1c6b92947c5d 100644 --- a/arch/arm/plat-samsung/include/plat/gpio-cfg.h +++ b/arch/arm/plat-samsung/include/plat/gpio-cfg.h | |||
@@ -143,12 +143,12 @@ extern s3c_gpio_pull_t s3c_gpio_getpull(unsigned int pin); | |||
143 | /* Define values for the drvstr available for each gpio pin. | 143 | /* Define values for the drvstr available for each gpio pin. |
144 | * | 144 | * |
145 | * These values control the value of the output signal driver strength, | 145 | * These values control the value of the output signal driver strength, |
146 | * configurable on most pins on the S5C series. | 146 | * configurable on most pins on the S5P series. |
147 | */ | 147 | */ |
148 | #define S5P_GPIO_DRVSTR_LV1 ((__force s5p_gpio_drvstr_t)0x00) | 148 | #define S5P_GPIO_DRVSTR_LV1 ((__force s5p_gpio_drvstr_t)0x0) |
149 | #define S5P_GPIO_DRVSTR_LV2 ((__force s5p_gpio_drvstr_t)0x01) | 149 | #define S5P_GPIO_DRVSTR_LV2 ((__force s5p_gpio_drvstr_t)0x2) |
150 | #define S5P_GPIO_DRVSTR_LV3 ((__force s5p_gpio_drvstr_t)0x10) | 150 | #define S5P_GPIO_DRVSTR_LV3 ((__force s5p_gpio_drvstr_t)0x1) |
151 | #define S5P_GPIO_DRVSTR_LV4 ((__force s5p_gpio_drvstr_t)0x11) | 151 | #define S5P_GPIO_DRVSTR_LV4 ((__force s5p_gpio_drvstr_t)0x3) |
152 | 152 | ||
153 | /** | 153 | /** |
154 | * s5c_gpio_get_drvstr() - get the driver streght value of a gpio pin | 154 | * s5c_gpio_get_drvstr() - get the driver streght value of a gpio pin |
diff --git a/arch/frv/kernel/signal.c b/arch/frv/kernel/signal.c index 0974c0ecc594..bab01298b58e 100644 --- a/arch/frv/kernel/signal.c +++ b/arch/frv/kernel/signal.c | |||
@@ -121,6 +121,9 @@ static int restore_sigcontext(struct sigcontext __user *sc, int *_gr8) | |||
121 | struct user_context *user = current->thread.user; | 121 | struct user_context *user = current->thread.user; |
122 | unsigned long tbr, psr; | 122 | unsigned long tbr, psr; |
123 | 123 | ||
124 | /* Always make any pending restarted system calls return -EINTR */ | ||
125 | current_thread_info()->restart_block.fn = do_no_restart_syscall; | ||
126 | |||
124 | tbr = user->i.tbr; | 127 | tbr = user->i.tbr; |
125 | psr = user->i.psr; | 128 | psr = user->i.psr; |
126 | if (copy_from_user(user, &sc->sc_context, sizeof(sc->sc_context))) | 129 | if (copy_from_user(user, &sc->sc_context, sizeof(sc->sc_context))) |
@@ -250,6 +253,8 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set) | |||
250 | struct sigframe __user *frame; | 253 | struct sigframe __user *frame; |
251 | int rsig; | 254 | int rsig; |
252 | 255 | ||
256 | set_fs(USER_DS); | ||
257 | |||
253 | frame = get_sigframe(ka, sizeof(*frame)); | 258 | frame = get_sigframe(ka, sizeof(*frame)); |
254 | 259 | ||
255 | if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) | 260 | if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) |
@@ -293,22 +298,23 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set) | |||
293 | (unsigned long) (frame->retcode + 2)); | 298 | (unsigned long) (frame->retcode + 2)); |
294 | } | 299 | } |
295 | 300 | ||
296 | /* set up registers for signal handler */ | 301 | /* Set up registers for the signal handler */ |
297 | __frame->sp = (unsigned long) frame; | ||
298 | __frame->lr = (unsigned long) &frame->retcode; | ||
299 | __frame->gr8 = sig; | ||
300 | |||
301 | if (current->personality & FDPIC_FUNCPTRS) { | 302 | if (current->personality & FDPIC_FUNCPTRS) { |
302 | struct fdpic_func_descriptor __user *funcptr = | 303 | struct fdpic_func_descriptor __user *funcptr = |
303 | (struct fdpic_func_descriptor __user *) ka->sa.sa_handler; | 304 | (struct fdpic_func_descriptor __user *) ka->sa.sa_handler; |
304 | __get_user(__frame->pc, &funcptr->text); | 305 | struct fdpic_func_descriptor desc; |
305 | __get_user(__frame->gr15, &funcptr->GOT); | 306 | if (copy_from_user(&desc, funcptr, sizeof(desc))) |
307 | goto give_sigsegv; | ||
308 | __frame->pc = desc.text; | ||
309 | __frame->gr15 = desc.GOT; | ||
306 | } else { | 310 | } else { |
307 | __frame->pc = (unsigned long) ka->sa.sa_handler; | 311 | __frame->pc = (unsigned long) ka->sa.sa_handler; |
308 | __frame->gr15 = 0; | 312 | __frame->gr15 = 0; |
309 | } | 313 | } |
310 | 314 | ||
311 | set_fs(USER_DS); | 315 | __frame->sp = (unsigned long) frame; |
316 | __frame->lr = (unsigned long) &frame->retcode; | ||
317 | __frame->gr8 = sig; | ||
312 | 318 | ||
313 | /* the tracer may want to single-step inside the handler */ | 319 | /* the tracer may want to single-step inside the handler */ |
314 | if (test_thread_flag(TIF_SINGLESTEP)) | 320 | if (test_thread_flag(TIF_SINGLESTEP)) |
@@ -323,7 +329,7 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set) | |||
323 | return 0; | 329 | return 0; |
324 | 330 | ||
325 | give_sigsegv: | 331 | give_sigsegv: |
326 | force_sig(SIGSEGV, current); | 332 | force_sigsegv(sig, current); |
327 | return -EFAULT; | 333 | return -EFAULT; |
328 | 334 | ||
329 | } /* end setup_frame() */ | 335 | } /* end setup_frame() */ |
@@ -338,6 +344,8 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
338 | struct rt_sigframe __user *frame; | 344 | struct rt_sigframe __user *frame; |
339 | int rsig; | 345 | int rsig; |
340 | 346 | ||
347 | set_fs(USER_DS); | ||
348 | |||
341 | frame = get_sigframe(ka, sizeof(*frame)); | 349 | frame = get_sigframe(ka, sizeof(*frame)); |
342 | 350 | ||
343 | if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) | 351 | if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) |
@@ -392,22 +400,23 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
392 | } | 400 | } |
393 | 401 | ||
394 | /* Set up registers for signal handler */ | 402 | /* Set up registers for signal handler */ |
395 | __frame->sp = (unsigned long) frame; | ||
396 | __frame->lr = (unsigned long) &frame->retcode; | ||
397 | __frame->gr8 = sig; | ||
398 | __frame->gr9 = (unsigned long) &frame->info; | ||
399 | |||
400 | if (current->personality & FDPIC_FUNCPTRS) { | 403 | if (current->personality & FDPIC_FUNCPTRS) { |
401 | struct fdpic_func_descriptor __user *funcptr = | 404 | struct fdpic_func_descriptor __user *funcptr = |
402 | (struct fdpic_func_descriptor __user *) ka->sa.sa_handler; | 405 | (struct fdpic_func_descriptor __user *) ka->sa.sa_handler; |
403 | __get_user(__frame->pc, &funcptr->text); | 406 | struct fdpic_func_descriptor desc; |
404 | __get_user(__frame->gr15, &funcptr->GOT); | 407 | if (copy_from_user(&desc, funcptr, sizeof(desc))) |
408 | goto give_sigsegv; | ||
409 | __frame->pc = desc.text; | ||
410 | __frame->gr15 = desc.GOT; | ||
405 | } else { | 411 | } else { |
406 | __frame->pc = (unsigned long) ka->sa.sa_handler; | 412 | __frame->pc = (unsigned long) ka->sa.sa_handler; |
407 | __frame->gr15 = 0; | 413 | __frame->gr15 = 0; |
408 | } | 414 | } |
409 | 415 | ||
410 | set_fs(USER_DS); | 416 | __frame->sp = (unsigned long) frame; |
417 | __frame->lr = (unsigned long) &frame->retcode; | ||
418 | __frame->gr8 = sig; | ||
419 | __frame->gr9 = (unsigned long) &frame->info; | ||
411 | 420 | ||
412 | /* the tracer may want to single-step inside the handler */ | 421 | /* the tracer may want to single-step inside the handler */ |
413 | if (test_thread_flag(TIF_SINGLESTEP)) | 422 | if (test_thread_flag(TIF_SINGLESTEP)) |
@@ -422,7 +431,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
422 | return 0; | 431 | return 0; |
423 | 432 | ||
424 | give_sigsegv: | 433 | give_sigsegv: |
425 | force_sig(SIGSEGV, current); | 434 | force_sigsegv(sig, current); |
426 | return -EFAULT; | 435 | return -EFAULT; |
427 | 436 | ||
428 | } /* end setup_rt_frame() */ | 437 | } /* end setup_rt_frame() */ |
@@ -437,7 +446,7 @@ static int handle_signal(unsigned long sig, siginfo_t *info, | |||
437 | int ret; | 446 | int ret; |
438 | 447 | ||
439 | /* Are we from a system call? */ | 448 | /* Are we from a system call? */ |
440 | if (in_syscall(__frame)) { | 449 | if (__frame->syscallno != -1) { |
441 | /* If so, check system call restarting.. */ | 450 | /* If so, check system call restarting.. */ |
442 | switch (__frame->gr8) { | 451 | switch (__frame->gr8) { |
443 | case -ERESTART_RESTARTBLOCK: | 452 | case -ERESTART_RESTARTBLOCK: |
@@ -456,6 +465,7 @@ static int handle_signal(unsigned long sig, siginfo_t *info, | |||
456 | __frame->gr8 = __frame->orig_gr8; | 465 | __frame->gr8 = __frame->orig_gr8; |
457 | __frame->pc -= 4; | 466 | __frame->pc -= 4; |
458 | } | 467 | } |
468 | __frame->syscallno = -1; | ||
459 | } | 469 | } |
460 | 470 | ||
461 | /* Set up the stack frame */ | 471 | /* Set up the stack frame */ |
@@ -538,10 +548,11 @@ no_signal: | |||
538 | break; | 548 | break; |
539 | 549 | ||
540 | case -ERESTART_RESTARTBLOCK: | 550 | case -ERESTART_RESTARTBLOCK: |
541 | __frame->gr8 = __NR_restart_syscall; | 551 | __frame->gr7 = __NR_restart_syscall; |
542 | __frame->pc -= 4; | 552 | __frame->pc -= 4; |
543 | break; | 553 | break; |
544 | } | 554 | } |
555 | __frame->syscallno = -1; | ||
545 | } | 556 | } |
546 | 557 | ||
547 | /* if there's no signal to deliver, we just put the saved sigmask | 558 | /* if there's no signal to deliver, we just put the saved sigmask |
diff --git a/arch/m32r/include/asm/signal.h b/arch/m32r/include/asm/signal.h index 9c1acb2b1a92..b2eeb0de1c8d 100644 --- a/arch/m32r/include/asm/signal.h +++ b/arch/m32r/include/asm/signal.h | |||
@@ -157,7 +157,6 @@ typedef struct sigaltstack { | |||
157 | #undef __HAVE_ARCH_SIG_BITOPS | 157 | #undef __HAVE_ARCH_SIG_BITOPS |
158 | 158 | ||
159 | struct pt_regs; | 159 | struct pt_regs; |
160 | extern int do_signal(struct pt_regs *regs, sigset_t *oldset); | ||
161 | 160 | ||
162 | #define ptrace_signal_deliver(regs, cookie) do { } while (0) | 161 | #define ptrace_signal_deliver(regs, cookie) do { } while (0) |
163 | 162 | ||
diff --git a/arch/m32r/include/asm/unistd.h b/arch/m32r/include/asm/unistd.h index 76125777483c..c70545689da8 100644 --- a/arch/m32r/include/asm/unistd.h +++ b/arch/m32r/include/asm/unistd.h | |||
@@ -351,6 +351,7 @@ | |||
351 | #define __ARCH_WANT_SYS_OLD_GETRLIMIT /*will be unused*/ | 351 | #define __ARCH_WANT_SYS_OLD_GETRLIMIT /*will be unused*/ |
352 | #define __ARCH_WANT_SYS_OLDUMOUNT | 352 | #define __ARCH_WANT_SYS_OLDUMOUNT |
353 | #define __ARCH_WANT_SYS_RT_SIGACTION | 353 | #define __ARCH_WANT_SYS_RT_SIGACTION |
354 | #define __ARCH_WANT_SYS_RT_SIGSUSPEND | ||
354 | 355 | ||
355 | #define __IGNORE_lchown | 356 | #define __IGNORE_lchown |
356 | #define __IGNORE_setuid | 357 | #define __IGNORE_setuid |
diff --git a/arch/m32r/kernel/entry.S b/arch/m32r/kernel/entry.S index 403869833b98..225412bc227e 100644 --- a/arch/m32r/kernel/entry.S +++ b/arch/m32r/kernel/entry.S | |||
@@ -235,10 +235,9 @@ work_resched: | |||
235 | work_notifysig: ; deal with pending signals and | 235 | work_notifysig: ; deal with pending signals and |
236 | ; notify-resume requests | 236 | ; notify-resume requests |
237 | mv r0, sp ; arg1 : struct pt_regs *regs | 237 | mv r0, sp ; arg1 : struct pt_regs *regs |
238 | ldi r1, #0 ; arg2 : sigset_t *oldset | 238 | mv r1, r9 ; arg2 : __u32 thread_info_flags |
239 | mv r2, r9 ; arg3 : __u32 thread_info_flags | ||
240 | bl do_notify_resume | 239 | bl do_notify_resume |
241 | bra restore_all | 240 | bra resume_userspace |
242 | 241 | ||
243 | ; perform syscall exit tracing | 242 | ; perform syscall exit tracing |
244 | ALIGN | 243 | ALIGN |
diff --git a/arch/m32r/kernel/ptrace.c b/arch/m32r/kernel/ptrace.c index e555091eb97c..0021ade4cba8 100644 --- a/arch/m32r/kernel/ptrace.c +++ b/arch/m32r/kernel/ptrace.c | |||
@@ -592,16 +592,17 @@ void user_enable_single_step(struct task_struct *child) | |||
592 | 592 | ||
593 | if (access_process_vm(child, pc&~3, &insn, sizeof(insn), 0) | 593 | if (access_process_vm(child, pc&~3, &insn, sizeof(insn), 0) |
594 | != sizeof(insn)) | 594 | != sizeof(insn)) |
595 | break; | 595 | return -EIO; |
596 | 596 | ||
597 | compute_next_pc(insn, pc, &next_pc, child); | 597 | compute_next_pc(insn, pc, &next_pc, child); |
598 | if (next_pc & 0x80000000) | 598 | if (next_pc & 0x80000000) |
599 | break; | 599 | return -EIO; |
600 | 600 | ||
601 | if (embed_debug_trap(child, next_pc)) | 601 | if (embed_debug_trap(child, next_pc)) |
602 | break; | 602 | return -EIO; |
603 | 603 | ||
604 | invalidate_cache(); | 604 | invalidate_cache(); |
605 | return 0; | ||
605 | } | 606 | } |
606 | 607 | ||
607 | void user_disable_single_step(struct task_struct *child) | 608 | void user_disable_single_step(struct task_struct *child) |
diff --git a/arch/m32r/kernel/signal.c b/arch/m32r/kernel/signal.c index 144b0f124fc7..7bbe38645ed5 100644 --- a/arch/m32r/kernel/signal.c +++ b/arch/m32r/kernel/signal.c | |||
@@ -28,37 +28,6 @@ | |||
28 | 28 | ||
29 | #define DEBUG_SIG 0 | 29 | #define DEBUG_SIG 0 |
30 | 30 | ||
31 | #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) | ||
32 | |||
33 | int do_signal(struct pt_regs *, sigset_t *); | ||
34 | |||
35 | asmlinkage int | ||
36 | sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize, | ||
37 | unsigned long r2, unsigned long r3, unsigned long r4, | ||
38 | unsigned long r5, unsigned long r6, struct pt_regs *regs) | ||
39 | { | ||
40 | sigset_t newset; | ||
41 | |||
42 | /* XXX: Don't preclude handling different sized sigset_t's. */ | ||
43 | if (sigsetsize != sizeof(sigset_t)) | ||
44 | return -EINVAL; | ||
45 | |||
46 | if (copy_from_user(&newset, unewset, sizeof(newset))) | ||
47 | return -EFAULT; | ||
48 | sigdelsetmask(&newset, sigmask(SIGKILL)|sigmask(SIGSTOP)); | ||
49 | |||
50 | spin_lock_irq(¤t->sighand->siglock); | ||
51 | current->saved_sigmask = current->blocked; | ||
52 | current->blocked = newset; | ||
53 | recalc_sigpending(); | ||
54 | spin_unlock_irq(¤t->sighand->siglock); | ||
55 | |||
56 | current->state = TASK_INTERRUPTIBLE; | ||
57 | schedule(); | ||
58 | set_thread_flag(TIF_RESTORE_SIGMASK); | ||
59 | return -ERESTARTNOHAND; | ||
60 | } | ||
61 | |||
62 | asmlinkage int | 31 | asmlinkage int |
63 | sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, | 32 | sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, |
64 | unsigned long r2, unsigned long r3, unsigned long r4, | 33 | unsigned long r2, unsigned long r3, unsigned long r4, |
@@ -218,7 +187,7 @@ get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size) | |||
218 | return (void __user *)((sp - frame_size) & -8ul); | 187 | return (void __user *)((sp - frame_size) & -8ul); |
219 | } | 188 | } |
220 | 189 | ||
221 | static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | 190 | static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, |
222 | sigset_t *set, struct pt_regs *regs) | 191 | sigset_t *set, struct pt_regs *regs) |
223 | { | 192 | { |
224 | struct rt_sigframe __user *frame; | 193 | struct rt_sigframe __user *frame; |
@@ -275,22 +244,34 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
275 | current->comm, current->pid, frame, regs->pc); | 244 | current->comm, current->pid, frame, regs->pc); |
276 | #endif | 245 | #endif |
277 | 246 | ||
278 | return; | 247 | return 0; |
279 | 248 | ||
280 | give_sigsegv: | 249 | give_sigsegv: |
281 | force_sigsegv(sig, current); | 250 | force_sigsegv(sig, current); |
251 | return -EFAULT; | ||
252 | } | ||
253 | |||
254 | static int prev_insn(struct pt_regs *regs) | ||
255 | { | ||
256 | u16 inst; | ||
257 | if (get_user(&inst, (u16 __user *)(regs->bpc - 2))) | ||
258 | return -EFAULT; | ||
259 | if ((inst & 0xfff0) == 0x10f0) /* trap ? */ | ||
260 | regs->bpc -= 2; | ||
261 | else | ||
262 | regs->bpc -= 4; | ||
263 | regs->syscall_nr = -1; | ||
264 | return 0; | ||
282 | } | 265 | } |
283 | 266 | ||
284 | /* | 267 | /* |
285 | * OK, we're invoking a handler | 268 | * OK, we're invoking a handler |
286 | */ | 269 | */ |
287 | 270 | ||
288 | static void | 271 | static int |
289 | handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, | 272 | handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, |
290 | sigset_t *oldset, struct pt_regs *regs) | 273 | sigset_t *oldset, struct pt_regs *regs) |
291 | { | 274 | { |
292 | unsigned short inst; | ||
293 | |||
294 | /* Are we from a system call? */ | 275 | /* Are we from a system call? */ |
295 | if (regs->syscall_nr >= 0) { | 276 | if (regs->syscall_nr >= 0) { |
296 | /* If so, check system call restarting.. */ | 277 | /* If so, check system call restarting.. */ |
@@ -308,16 +289,14 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, | |||
308 | /* fallthrough */ | 289 | /* fallthrough */ |
309 | case -ERESTARTNOINTR: | 290 | case -ERESTARTNOINTR: |
310 | regs->r0 = regs->orig_r0; | 291 | regs->r0 = regs->orig_r0; |
311 | inst = *(unsigned short *)(regs->bpc - 2); | 292 | if (prev_insn(regs) < 0) |
312 | if ((inst & 0xfff0) == 0x10f0) /* trap ? */ | 293 | return -EFAULT; |
313 | regs->bpc -= 2; | ||
314 | else | ||
315 | regs->bpc -= 4; | ||
316 | } | 294 | } |
317 | } | 295 | } |
318 | 296 | ||
319 | /* Set up the stack frame */ | 297 | /* Set up the stack frame */ |
320 | setup_rt_frame(sig, ka, info, oldset, regs); | 298 | if (setup_rt_frame(sig, ka, info, oldset, regs)) |
299 | return -EFAULT; | ||
321 | 300 | ||
322 | spin_lock_irq(¤t->sighand->siglock); | 301 | spin_lock_irq(¤t->sighand->siglock); |
323 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); | 302 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); |
@@ -325,6 +304,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, | |||
325 | sigaddset(¤t->blocked,sig); | 304 | sigaddset(¤t->blocked,sig); |
326 | recalc_sigpending(); | 305 | recalc_sigpending(); |
327 | spin_unlock_irq(¤t->sighand->siglock); | 306 | spin_unlock_irq(¤t->sighand->siglock); |
307 | return 0; | ||
328 | } | 308 | } |
329 | 309 | ||
330 | /* | 310 | /* |
@@ -332,12 +312,12 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, | |||
332 | * want to handle. Thus you cannot kill init even with a SIGKILL even by | 312 | * want to handle. Thus you cannot kill init even with a SIGKILL even by |
333 | * mistake. | 313 | * mistake. |
334 | */ | 314 | */ |
335 | int do_signal(struct pt_regs *regs, sigset_t *oldset) | 315 | static void do_signal(struct pt_regs *regs) |
336 | { | 316 | { |
337 | siginfo_t info; | 317 | siginfo_t info; |
338 | int signr; | 318 | int signr; |
339 | struct k_sigaction ka; | 319 | struct k_sigaction ka; |
340 | unsigned short inst; | 320 | sigset_t *oldset; |
341 | 321 | ||
342 | /* | 322 | /* |
343 | * We want the common case to go fast, which | 323 | * We want the common case to go fast, which |
@@ -346,12 +326,14 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset) | |||
346 | * if so. | 326 | * if so. |
347 | */ | 327 | */ |
348 | if (!user_mode(regs)) | 328 | if (!user_mode(regs)) |
349 | return 1; | 329 | return; |
350 | 330 | ||
351 | if (try_to_freeze()) | 331 | if (try_to_freeze()) |
352 | goto no_signal; | 332 | goto no_signal; |
353 | 333 | ||
354 | if (!oldset) | 334 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) |
335 | oldset = ¤t->saved_sigmask; | ||
336 | else | ||
355 | oldset = ¤t->blocked; | 337 | oldset = ¤t->blocked; |
356 | 338 | ||
357 | signr = get_signal_to_deliver(&info, &ka, regs, NULL); | 339 | signr = get_signal_to_deliver(&info, &ka, regs, NULL); |
@@ -363,8 +345,10 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset) | |||
363 | */ | 345 | */ |
364 | 346 | ||
365 | /* Whee! Actually deliver the signal. */ | 347 | /* Whee! Actually deliver the signal. */ |
366 | handle_signal(signr, &ka, &info, oldset, regs); | 348 | if (handle_signal(signr, &ka, &info, oldset, regs) == 0) |
367 | return 1; | 349 | clear_thread_flag(TIF_RESTORE_SIGMASK); |
350 | |||
351 | return; | ||
368 | } | 352 | } |
369 | 353 | ||
370 | no_signal: | 354 | no_signal: |
@@ -375,31 +359,24 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset) | |||
375 | regs->r0 == -ERESTARTSYS || | 359 | regs->r0 == -ERESTARTSYS || |
376 | regs->r0 == -ERESTARTNOINTR) { | 360 | regs->r0 == -ERESTARTNOINTR) { |
377 | regs->r0 = regs->orig_r0; | 361 | regs->r0 = regs->orig_r0; |
378 | inst = *(unsigned short *)(regs->bpc - 2); | 362 | prev_insn(regs); |
379 | if ((inst & 0xfff0) == 0x10f0) /* trap ? */ | 363 | } else if (regs->r0 == -ERESTART_RESTARTBLOCK){ |
380 | regs->bpc -= 2; | ||
381 | else | ||
382 | regs->bpc -= 4; | ||
383 | } | ||
384 | if (regs->r0 == -ERESTART_RESTARTBLOCK){ | ||
385 | regs->r0 = regs->orig_r0; | 364 | regs->r0 = regs->orig_r0; |
386 | regs->r7 = __NR_restart_syscall; | 365 | regs->r7 = __NR_restart_syscall; |
387 | inst = *(unsigned short *)(regs->bpc - 2); | 366 | prev_insn(regs); |
388 | if ((inst & 0xfff0) == 0x10f0) /* trap ? */ | ||
389 | regs->bpc -= 2; | ||
390 | else | ||
391 | regs->bpc -= 4; | ||
392 | } | 367 | } |
393 | } | 368 | } |
394 | return 0; | 369 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) { |
370 | clear_thread_flag(TIF_RESTORE_SIGMASK); | ||
371 | sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); | ||
372 | } | ||
395 | } | 373 | } |
396 | 374 | ||
397 | /* | 375 | /* |
398 | * notification of userspace execution resumption | 376 | * notification of userspace execution resumption |
399 | * - triggered by current->work.notify_resume | 377 | * - triggered by current->work.notify_resume |
400 | */ | 378 | */ |
401 | void do_notify_resume(struct pt_regs *regs, sigset_t *oldset, | 379 | void do_notify_resume(struct pt_regs *regs, __u32 thread_info_flags) |
402 | __u32 thread_info_flags) | ||
403 | { | 380 | { |
404 | /* Pending single-step? */ | 381 | /* Pending single-step? */ |
405 | if (thread_info_flags & _TIF_SINGLESTEP) | 382 | if (thread_info_flags & _TIF_SINGLESTEP) |
@@ -407,7 +384,7 @@ void do_notify_resume(struct pt_regs *regs, sigset_t *oldset, | |||
407 | 384 | ||
408 | /* deal with pending signal delivery */ | 385 | /* deal with pending signal delivery */ |
409 | if (thread_info_flags & _TIF_SIGPENDING) | 386 | if (thread_info_flags & _TIF_SIGPENDING) |
410 | do_signal(regs,oldset); | 387 | do_signal(regs); |
411 | 388 | ||
412 | if (thread_info_flags & _TIF_NOTIFY_RESUME) { | 389 | if (thread_info_flags & _TIF_NOTIFY_RESUME) { |
413 | clear_thread_flag(TIF_NOTIFY_RESUME); | 390 | clear_thread_flag(TIF_NOTIFY_RESUME); |
diff --git a/arch/mn10300/Kconfig b/arch/mn10300/Kconfig index 444b9f918fdf..7c2a2f7f8dc1 100644 --- a/arch/mn10300/Kconfig +++ b/arch/mn10300/Kconfig | |||
@@ -8,7 +8,6 @@ mainmenu "Linux Kernel Configuration" | |||
8 | config MN10300 | 8 | config MN10300 |
9 | def_bool y | 9 | def_bool y |
10 | select HAVE_OPROFILE | 10 | select HAVE_OPROFILE |
11 | select HAVE_ARCH_TRACEHOOK | ||
12 | 11 | ||
13 | config AM33 | 12 | config AM33 |
14 | def_bool y | 13 | def_bool y |
diff --git a/arch/mn10300/Kconfig.debug b/arch/mn10300/Kconfig.debug index ff80e86b9bd2..ce83c74b3fd7 100644 --- a/arch/mn10300/Kconfig.debug +++ b/arch/mn10300/Kconfig.debug | |||
@@ -101,7 +101,7 @@ config GDBSTUB_DEBUG_BREAKPOINT | |||
101 | 101 | ||
102 | choice | 102 | choice |
103 | prompt "GDB stub port" | 103 | prompt "GDB stub port" |
104 | default GDBSTUB_TTYSM0 | 104 | default GDBSTUB_ON_TTYSM0 |
105 | depends on GDBSTUB | 105 | depends on GDBSTUB |
106 | help | 106 | help |
107 | Select the serial port used for GDB-stub. | 107 | Select the serial port used for GDB-stub. |
diff --git a/arch/mn10300/include/asm/bitops.h b/arch/mn10300/include/asm/bitops.h index f49ac49e09ad..3f50e9661076 100644 --- a/arch/mn10300/include/asm/bitops.h +++ b/arch/mn10300/include/asm/bitops.h | |||
@@ -229,9 +229,9 @@ int ffs(int x) | |||
229 | #include <asm-generic/bitops/hweight.h> | 229 | #include <asm-generic/bitops/hweight.h> |
230 | 230 | ||
231 | #define ext2_set_bit_atomic(lock, nr, addr) \ | 231 | #define ext2_set_bit_atomic(lock, nr, addr) \ |
232 | test_and_set_bit((nr) ^ 0x18, (addr)) | 232 | test_and_set_bit((nr), (addr)) |
233 | #define ext2_clear_bit_atomic(lock, nr, addr) \ | 233 | #define ext2_clear_bit_atomic(lock, nr, addr) \ |
234 | test_and_clear_bit((nr) ^ 0x18, (addr)) | 234 | test_and_clear_bit((nr), (addr)) |
235 | 235 | ||
236 | #include <asm-generic/bitops/ext2-non-atomic.h> | 236 | #include <asm-generic/bitops/ext2-non-atomic.h> |
237 | #include <asm-generic/bitops/minix-le.h> | 237 | #include <asm-generic/bitops/minix-le.h> |
diff --git a/arch/mn10300/include/asm/signal.h b/arch/mn10300/include/asm/signal.h index 7e891fce2370..1865d72a86ff 100644 --- a/arch/mn10300/include/asm/signal.h +++ b/arch/mn10300/include/asm/signal.h | |||
@@ -78,7 +78,7 @@ typedef unsigned long sigset_t; | |||
78 | 78 | ||
79 | /* These should not be considered constants from userland. */ | 79 | /* These should not be considered constants from userland. */ |
80 | #define SIGRTMIN 32 | 80 | #define SIGRTMIN 32 |
81 | #define SIGRTMAX (_NSIG-1) | 81 | #define SIGRTMAX _NSIG |
82 | 82 | ||
83 | /* | 83 | /* |
84 | * SA_FLAGS values: | 84 | * SA_FLAGS values: |
diff --git a/arch/mn10300/kernel/signal.c b/arch/mn10300/kernel/signal.c index 717db14c2cc3..d4de05ab7864 100644 --- a/arch/mn10300/kernel/signal.c +++ b/arch/mn10300/kernel/signal.c | |||
@@ -65,10 +65,10 @@ asmlinkage long sys_sigaction(int sig, | |||
65 | old_sigset_t mask; | 65 | old_sigset_t mask; |
66 | if (verify_area(VERIFY_READ, act, sizeof(*act)) || | 66 | if (verify_area(VERIFY_READ, act, sizeof(*act)) || |
67 | __get_user(new_ka.sa.sa_handler, &act->sa_handler) || | 67 | __get_user(new_ka.sa.sa_handler, &act->sa_handler) || |
68 | __get_user(new_ka.sa.sa_restorer, &act->sa_restorer)) | 68 | __get_user(new_ka.sa.sa_restorer, &act->sa_restorer) || |
69 | __get_user(new_ka.sa.sa_flags, &act->sa_flags) || | ||
70 | __get_user(mask, &act->sa_mask)) | ||
69 | return -EFAULT; | 71 | return -EFAULT; |
70 | __get_user(new_ka.sa.sa_flags, &act->sa_flags); | ||
71 | __get_user(mask, &act->sa_mask); | ||
72 | siginitset(&new_ka.sa.sa_mask, mask); | 72 | siginitset(&new_ka.sa.sa_mask, mask); |
73 | } | 73 | } |
74 | 74 | ||
@@ -77,10 +77,10 @@ asmlinkage long sys_sigaction(int sig, | |||
77 | if (!ret && oact) { | 77 | if (!ret && oact) { |
78 | if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) || | 78 | if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) || |
79 | __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || | 79 | __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || |
80 | __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer)) | 80 | __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer) || |
81 | __put_user(old_ka.sa.sa_flags, &oact->sa_flags) || | ||
82 | __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask)) | ||
81 | return -EFAULT; | 83 | return -EFAULT; |
82 | __put_user(old_ka.sa.sa_flags, &oact->sa_flags); | ||
83 | __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask); | ||
84 | } | 84 | } |
85 | 85 | ||
86 | return ret; | 86 | return ret; |
@@ -102,6 +102,9 @@ static int restore_sigcontext(struct pt_regs *regs, | |||
102 | { | 102 | { |
103 | unsigned int err = 0; | 103 | unsigned int err = 0; |
104 | 104 | ||
105 | /* Always make any pending restarted system calls return -EINTR */ | ||
106 | current_thread_info()->restart_block.fn = do_no_restart_syscall; | ||
107 | |||
105 | if (is_using_fpu(current)) | 108 | if (is_using_fpu(current)) |
106 | fpu_kill_state(current); | 109 | fpu_kill_state(current); |
107 | 110 | ||
@@ -330,8 +333,6 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, | |||
330 | regs->d0 = sig; | 333 | regs->d0 = sig; |
331 | regs->d1 = (unsigned long) &frame->sc; | 334 | regs->d1 = (unsigned long) &frame->sc; |
332 | 335 | ||
333 | set_fs(USER_DS); | ||
334 | |||
335 | /* the tracer may want to single-step inside the handler */ | 336 | /* the tracer may want to single-step inside the handler */ |
336 | if (test_thread_flag(TIF_SINGLESTEP)) | 337 | if (test_thread_flag(TIF_SINGLESTEP)) |
337 | ptrace_notify(SIGTRAP); | 338 | ptrace_notify(SIGTRAP); |
@@ -345,7 +346,7 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, | |||
345 | return 0; | 346 | return 0; |
346 | 347 | ||
347 | give_sigsegv: | 348 | give_sigsegv: |
348 | force_sig(SIGSEGV, current); | 349 | force_sigsegv(sig, current); |
349 | return -EFAULT; | 350 | return -EFAULT; |
350 | } | 351 | } |
351 | 352 | ||
@@ -413,8 +414,6 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
413 | regs->d0 = sig; | 414 | regs->d0 = sig; |
414 | regs->d1 = (long) &frame->info; | 415 | regs->d1 = (long) &frame->info; |
415 | 416 | ||
416 | set_fs(USER_DS); | ||
417 | |||
418 | /* the tracer may want to single-step inside the handler */ | 417 | /* the tracer may want to single-step inside the handler */ |
419 | if (test_thread_flag(TIF_SINGLESTEP)) | 418 | if (test_thread_flag(TIF_SINGLESTEP)) |
420 | ptrace_notify(SIGTRAP); | 419 | ptrace_notify(SIGTRAP); |
@@ -428,10 +427,16 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
428 | return 0; | 427 | return 0; |
429 | 428 | ||
430 | give_sigsegv: | 429 | give_sigsegv: |
431 | force_sig(SIGSEGV, current); | 430 | force_sigsegv(sig, current); |
432 | return -EFAULT; | 431 | return -EFAULT; |
433 | } | 432 | } |
434 | 433 | ||
434 | static inline void stepback(struct pt_regs *regs) | ||
435 | { | ||
436 | regs->pc -= 2; | ||
437 | regs->orig_d0 = -1; | ||
438 | } | ||
439 | |||
435 | /* | 440 | /* |
436 | * handle the actual delivery of a signal to userspace | 441 | * handle the actual delivery of a signal to userspace |
437 | */ | 442 | */ |
@@ -459,7 +464,7 @@ static int handle_signal(int sig, | |||
459 | /* fallthrough */ | 464 | /* fallthrough */ |
460 | case -ERESTARTNOINTR: | 465 | case -ERESTARTNOINTR: |
461 | regs->d0 = regs->orig_d0; | 466 | regs->d0 = regs->orig_d0; |
462 | regs->pc -= 2; | 467 | stepback(regs); |
463 | } | 468 | } |
464 | } | 469 | } |
465 | 470 | ||
@@ -527,12 +532,12 @@ static void do_signal(struct pt_regs *regs) | |||
527 | case -ERESTARTSYS: | 532 | case -ERESTARTSYS: |
528 | case -ERESTARTNOINTR: | 533 | case -ERESTARTNOINTR: |
529 | regs->d0 = regs->orig_d0; | 534 | regs->d0 = regs->orig_d0; |
530 | regs->pc -= 2; | 535 | stepback(regs); |
531 | break; | 536 | break; |
532 | 537 | ||
533 | case -ERESTART_RESTARTBLOCK: | 538 | case -ERESTART_RESTARTBLOCK: |
534 | regs->d0 = __NR_restart_syscall; | 539 | regs->d0 = __NR_restart_syscall; |
535 | regs->pc -= 2; | 540 | stepback(regs); |
536 | break; | 541 | break; |
537 | } | 542 | } |
538 | } | 543 | } |
diff --git a/arch/mn10300/mm/Makefile b/arch/mn10300/mm/Makefile index 28b9d983db0c..1557277fbc5c 100644 --- a/arch/mn10300/mm/Makefile +++ b/arch/mn10300/mm/Makefile | |||
@@ -2,13 +2,11 @@ | |||
2 | # Makefile for the MN10300-specific memory management code | 2 | # Makefile for the MN10300-specific memory management code |
3 | # | 3 | # |
4 | 4 | ||
5 | cacheflush-y := cache.o cache-mn10300.o | ||
6 | cacheflush-$(CONFIG_MN10300_CACHE_WBACK) += cache-flush-mn10300.o | ||
7 | |||
8 | cacheflush-$(CONFIG_MN10300_CACHE_DISABLED) := cache-disabled.o | ||
9 | |||
5 | obj-y := \ | 10 | obj-y := \ |
6 | init.o fault.o pgtable.o extable.o tlb-mn10300.o mmu-context.o \ | 11 | init.o fault.o pgtable.o extable.o tlb-mn10300.o mmu-context.o \ |
7 | misalignment.o dma-alloc.o | 12 | misalignment.o dma-alloc.o $(cacheflush-y) |
8 | |||
9 | ifneq ($(CONFIG_MN10300_CACHE_DISABLED),y) | ||
10 | obj-y += cache.o cache-mn10300.o | ||
11 | ifeq ($(CONFIG_MN10300_CACHE_WBACK),y) | ||
12 | obj-y += cache-flush-mn10300.o | ||
13 | endif | ||
14 | endif | ||
diff --git a/arch/mn10300/mm/cache-disabled.c b/arch/mn10300/mm/cache-disabled.c new file mode 100644 index 000000000000..f669ea42aba6 --- /dev/null +++ b/arch/mn10300/mm/cache-disabled.c | |||
@@ -0,0 +1,21 @@ | |||
1 | /* Handle the cache being disabled | ||
2 | * | ||
3 | * Copyright (C) 2010 Red Hat, Inc. All Rights Reserved. | ||
4 | * Written by David Howells (dhowells@redhat.com) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public Licence | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the Licence, or (at your option) any later version. | ||
10 | */ | ||
11 | #include <linux/mm.h> | ||
12 | |||
13 | /* | ||
14 | * allow userspace to flush the instruction cache | ||
15 | */ | ||
16 | asmlinkage long sys_cacheflush(unsigned long start, unsigned long end) | ||
17 | { | ||
18 | if (end < start) | ||
19 | return -EINVAL; | ||
20 | return 0; | ||
21 | } | ||
diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c index 7109f5b1baa8..2300426e531a 100644 --- a/arch/powerpc/kernel/signal.c +++ b/arch/powerpc/kernel/signal.c | |||
@@ -138,6 +138,7 @@ static int do_signal_pending(sigset_t *oldset, struct pt_regs *regs) | |||
138 | ti->local_flags &= ~_TLF_RESTORE_SIGMASK; | 138 | ti->local_flags &= ~_TLF_RESTORE_SIGMASK; |
139 | sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); | 139 | sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); |
140 | } | 140 | } |
141 | regs->trap = 0; | ||
141 | return 0; /* no signals delivered */ | 142 | return 0; /* no signals delivered */ |
142 | } | 143 | } |
143 | 144 | ||
@@ -164,6 +165,7 @@ static int do_signal_pending(sigset_t *oldset, struct pt_regs *regs) | |||
164 | ret = handle_rt_signal64(signr, &ka, &info, oldset, regs); | 165 | ret = handle_rt_signal64(signr, &ka, &info, oldset, regs); |
165 | } | 166 | } |
166 | 167 | ||
168 | regs->trap = 0; | ||
167 | if (ret) { | 169 | if (ret) { |
168 | spin_lock_irq(¤t->sighand->siglock); | 170 | spin_lock_irq(¤t->sighand->siglock); |
169 | sigorsets(¤t->blocked, ¤t->blocked, | 171 | sigorsets(¤t->blocked, ¤t->blocked, |
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index 266610119f66..b96a3a010c26 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c | |||
@@ -511,6 +511,7 @@ static long restore_user_regs(struct pt_regs *regs, | |||
511 | if (!sig) | 511 | if (!sig) |
512 | save_r2 = (unsigned int)regs->gpr[2]; | 512 | save_r2 = (unsigned int)regs->gpr[2]; |
513 | err = restore_general_regs(regs, sr); | 513 | err = restore_general_regs(regs, sr); |
514 | regs->trap = 0; | ||
514 | err |= __get_user(msr, &sr->mc_gregs[PT_MSR]); | 515 | err |= __get_user(msr, &sr->mc_gregs[PT_MSR]); |
515 | if (!sig) | 516 | if (!sig) |
516 | regs->gpr[2] = (unsigned long) save_r2; | 517 | regs->gpr[2] = (unsigned long) save_r2; |
@@ -884,7 +885,6 @@ int handle_rt_signal32(unsigned long sig, struct k_sigaction *ka, | |||
884 | regs->nip = (unsigned long) ka->sa.sa_handler; | 885 | regs->nip = (unsigned long) ka->sa.sa_handler; |
885 | /* enter the signal handler in big-endian mode */ | 886 | /* enter the signal handler in big-endian mode */ |
886 | regs->msr &= ~MSR_LE; | 887 | regs->msr &= ~MSR_LE; |
887 | regs->trap = 0; | ||
888 | return 1; | 888 | return 1; |
889 | 889 | ||
890 | badframe: | 890 | badframe: |
@@ -1228,7 +1228,6 @@ int handle_signal32(unsigned long sig, struct k_sigaction *ka, | |||
1228 | regs->nip = (unsigned long) ka->sa.sa_handler; | 1228 | regs->nip = (unsigned long) ka->sa.sa_handler; |
1229 | /* enter the signal handler in big-endian mode */ | 1229 | /* enter the signal handler in big-endian mode */ |
1230 | regs->msr &= ~MSR_LE; | 1230 | regs->msr &= ~MSR_LE; |
1231 | regs->trap = 0; | ||
1232 | 1231 | ||
1233 | return 1; | 1232 | return 1; |
1234 | 1233 | ||
diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c index 2fe6fc64b614..27c4a4584f80 100644 --- a/arch/powerpc/kernel/signal_64.c +++ b/arch/powerpc/kernel/signal_64.c | |||
@@ -178,7 +178,7 @@ static long restore_sigcontext(struct pt_regs *regs, sigset_t *set, int sig, | |||
178 | err |= __get_user(regs->xer, &sc->gp_regs[PT_XER]); | 178 | err |= __get_user(regs->xer, &sc->gp_regs[PT_XER]); |
179 | err |= __get_user(regs->ccr, &sc->gp_regs[PT_CCR]); | 179 | err |= __get_user(regs->ccr, &sc->gp_regs[PT_CCR]); |
180 | /* skip SOFTE */ | 180 | /* skip SOFTE */ |
181 | err |= __get_user(regs->trap, &sc->gp_regs[PT_TRAP]); | 181 | regs->trap = 0; |
182 | err |= __get_user(regs->dar, &sc->gp_regs[PT_DAR]); | 182 | err |= __get_user(regs->dar, &sc->gp_regs[PT_DAR]); |
183 | err |= __get_user(regs->dsisr, &sc->gp_regs[PT_DSISR]); | 183 | err |= __get_user(regs->dsisr, &sc->gp_regs[PT_DSISR]); |
184 | err |= __get_user(regs->result, &sc->gp_regs[PT_RESULT]); | 184 | err |= __get_user(regs->result, &sc->gp_regs[PT_RESULT]); |
diff --git a/arch/sparc/kernel/perf_event.c b/arch/sparc/kernel/perf_event.c index 357ced3c33ff..6318e622cfb0 100644 --- a/arch/sparc/kernel/perf_event.c +++ b/arch/sparc/kernel/perf_event.c | |||
@@ -1038,6 +1038,7 @@ static int __hw_perf_event_init(struct perf_event *event) | |||
1038 | if (atomic_read(&nmi_active) < 0) | 1038 | if (atomic_read(&nmi_active) < 0) |
1039 | return -ENODEV; | 1039 | return -ENODEV; |
1040 | 1040 | ||
1041 | pmap = NULL; | ||
1041 | if (attr->type == PERF_TYPE_HARDWARE) { | 1042 | if (attr->type == PERF_TYPE_HARDWARE) { |
1042 | if (attr->config >= sparc_pmu->max_events) | 1043 | if (attr->config >= sparc_pmu->max_events) |
1043 | return -EINVAL; | 1044 | return -EINVAL; |
@@ -1046,9 +1047,18 @@ static int __hw_perf_event_init(struct perf_event *event) | |||
1046 | pmap = sparc_map_cache_event(attr->config); | 1047 | pmap = sparc_map_cache_event(attr->config); |
1047 | if (IS_ERR(pmap)) | 1048 | if (IS_ERR(pmap)) |
1048 | return PTR_ERR(pmap); | 1049 | return PTR_ERR(pmap); |
1049 | } else | 1050 | } else if (attr->type != PERF_TYPE_RAW) |
1050 | return -EOPNOTSUPP; | 1051 | return -EOPNOTSUPP; |
1051 | 1052 | ||
1053 | if (pmap) { | ||
1054 | hwc->event_base = perf_event_encode(pmap); | ||
1055 | } else { | ||
1056 | /* User gives us "(encoding << 16) | pic_mask" for | ||
1057 | * PERF_TYPE_RAW events. | ||
1058 | */ | ||
1059 | hwc->event_base = attr->config; | ||
1060 | } | ||
1061 | |||
1052 | /* We save the enable bits in the config_base. */ | 1062 | /* We save the enable bits in the config_base. */ |
1053 | hwc->config_base = sparc_pmu->irq_bit; | 1063 | hwc->config_base = sparc_pmu->irq_bit; |
1054 | if (!attr->exclude_user) | 1064 | if (!attr->exclude_user) |
@@ -1058,8 +1068,6 @@ static int __hw_perf_event_init(struct perf_event *event) | |||
1058 | if (!attr->exclude_hv) | 1068 | if (!attr->exclude_hv) |
1059 | hwc->config_base |= sparc_pmu->hv_bit; | 1069 | hwc->config_base |= sparc_pmu->hv_bit; |
1060 | 1070 | ||
1061 | hwc->event_base = perf_event_encode(pmap); | ||
1062 | |||
1063 | n = 0; | 1071 | n = 0; |
1064 | if (event->group_leader != event) { | 1072 | if (event->group_leader != event) { |
1065 | n = collect_events(event->group_leader, | 1073 | n = collect_events(event->group_leader, |
diff --git a/arch/sparc/kernel/signal32.c b/arch/sparc/kernel/signal32.c index ea22cd373c64..75fad425e249 100644 --- a/arch/sparc/kernel/signal32.c +++ b/arch/sparc/kernel/signal32.c | |||
@@ -453,8 +453,66 @@ static int save_fpu_state32(struct pt_regs *regs, __siginfo_fpu_t __user *fpu) | |||
453 | return err; | 453 | return err; |
454 | } | 454 | } |
455 | 455 | ||
456 | static void setup_frame32(struct k_sigaction *ka, struct pt_regs *regs, | 456 | /* The I-cache flush instruction only works in the primary ASI, which |
457 | int signo, sigset_t *oldset) | 457 | * right now is the nucleus, aka. kernel space. |
458 | * | ||
459 | * Therefore we have to kick the instructions out using the kernel | ||
460 | * side linear mapping of the physical address backing the user | ||
461 | * instructions. | ||
462 | */ | ||
463 | static void flush_signal_insns(unsigned long address) | ||
464 | { | ||
465 | unsigned long pstate, paddr; | ||
466 | pte_t *ptep, pte; | ||
467 | pgd_t *pgdp; | ||
468 | pud_t *pudp; | ||
469 | pmd_t *pmdp; | ||
470 | |||
471 | /* Commit all stores of the instructions we are about to flush. */ | ||
472 | wmb(); | ||
473 | |||
474 | /* Disable cross-call reception. In this way even a very wide | ||
475 | * munmap() on another cpu can't tear down the page table | ||
476 | * hierarchy from underneath us, since that can't complete | ||
477 | * until the IPI tlb flush returns. | ||
478 | */ | ||
479 | |||
480 | __asm__ __volatile__("rdpr %%pstate, %0" : "=r" (pstate)); | ||
481 | __asm__ __volatile__("wrpr %0, %1, %%pstate" | ||
482 | : : "r" (pstate), "i" (PSTATE_IE)); | ||
483 | |||
484 | pgdp = pgd_offset(current->mm, address); | ||
485 | if (pgd_none(*pgdp)) | ||
486 | goto out_irqs_on; | ||
487 | pudp = pud_offset(pgdp, address); | ||
488 | if (pud_none(*pudp)) | ||
489 | goto out_irqs_on; | ||
490 | pmdp = pmd_offset(pudp, address); | ||
491 | if (pmd_none(*pmdp)) | ||
492 | goto out_irqs_on; | ||
493 | |||
494 | ptep = pte_offset_map(pmdp, address); | ||
495 | pte = *ptep; | ||
496 | if (!pte_present(pte)) | ||
497 | goto out_unmap; | ||
498 | |||
499 | paddr = (unsigned long) page_address(pte_page(pte)); | ||
500 | |||
501 | __asm__ __volatile__("flush %0 + %1" | ||
502 | : /* no outputs */ | ||
503 | : "r" (paddr), | ||
504 | "r" (address & (PAGE_SIZE - 1)) | ||
505 | : "memory"); | ||
506 | |||
507 | out_unmap: | ||
508 | pte_unmap(ptep); | ||
509 | out_irqs_on: | ||
510 | __asm__ __volatile__("wrpr %0, 0x0, %%pstate" : : "r" (pstate)); | ||
511 | |||
512 | } | ||
513 | |||
514 | static int setup_frame32(struct k_sigaction *ka, struct pt_regs *regs, | ||
515 | int signo, sigset_t *oldset) | ||
458 | { | 516 | { |
459 | struct signal_frame32 __user *sf; | 517 | struct signal_frame32 __user *sf; |
460 | int sigframe_size; | 518 | int sigframe_size; |
@@ -547,13 +605,7 @@ static void setup_frame32(struct k_sigaction *ka, struct pt_regs *regs, | |||
547 | if (ka->ka_restorer) { | 605 | if (ka->ka_restorer) { |
548 | regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer; | 606 | regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer; |
549 | } else { | 607 | } else { |
550 | /* Flush instruction space. */ | ||
551 | unsigned long address = ((unsigned long)&(sf->insns[0])); | 608 | unsigned long address = ((unsigned long)&(sf->insns[0])); |
552 | pgd_t *pgdp = pgd_offset(current->mm, address); | ||
553 | pud_t *pudp = pud_offset(pgdp, address); | ||
554 | pmd_t *pmdp = pmd_offset(pudp, address); | ||
555 | pte_t *ptep; | ||
556 | pte_t pte; | ||
557 | 609 | ||
558 | regs->u_regs[UREG_I7] = (unsigned long) (&(sf->insns[0]) - 2); | 610 | regs->u_regs[UREG_I7] = (unsigned long) (&(sf->insns[0]) - 2); |
559 | 611 | ||
@@ -562,34 +614,22 @@ static void setup_frame32(struct k_sigaction *ka, struct pt_regs *regs, | |||
562 | if (err) | 614 | if (err) |
563 | goto sigsegv; | 615 | goto sigsegv; |
564 | 616 | ||
565 | preempt_disable(); | 617 | flush_signal_insns(address); |
566 | ptep = pte_offset_map(pmdp, address); | ||
567 | pte = *ptep; | ||
568 | if (pte_present(pte)) { | ||
569 | unsigned long page = (unsigned long) | ||
570 | page_address(pte_page(pte)); | ||
571 | |||
572 | wmb(); | ||
573 | __asm__ __volatile__("flush %0 + %1" | ||
574 | : /* no outputs */ | ||
575 | : "r" (page), | ||
576 | "r" (address & (PAGE_SIZE - 1)) | ||
577 | : "memory"); | ||
578 | } | ||
579 | pte_unmap(ptep); | ||
580 | preempt_enable(); | ||
581 | } | 618 | } |
582 | return; | 619 | return 0; |
583 | 620 | ||
584 | sigill: | 621 | sigill: |
585 | do_exit(SIGILL); | 622 | do_exit(SIGILL); |
623 | return -EINVAL; | ||
624 | |||
586 | sigsegv: | 625 | sigsegv: |
587 | force_sigsegv(signo, current); | 626 | force_sigsegv(signo, current); |
627 | return -EFAULT; | ||
588 | } | 628 | } |
589 | 629 | ||
590 | static void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs, | 630 | static int setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs, |
591 | unsigned long signr, sigset_t *oldset, | 631 | unsigned long signr, sigset_t *oldset, |
592 | siginfo_t *info) | 632 | siginfo_t *info) |
593 | { | 633 | { |
594 | struct rt_signal_frame32 __user *sf; | 634 | struct rt_signal_frame32 __user *sf; |
595 | int sigframe_size; | 635 | int sigframe_size; |
@@ -687,12 +727,7 @@ static void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs, | |||
687 | if (ka->ka_restorer) | 727 | if (ka->ka_restorer) |
688 | regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer; | 728 | regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer; |
689 | else { | 729 | else { |
690 | /* Flush instruction space. */ | ||
691 | unsigned long address = ((unsigned long)&(sf->insns[0])); | 730 | unsigned long address = ((unsigned long)&(sf->insns[0])); |
692 | pgd_t *pgdp = pgd_offset(current->mm, address); | ||
693 | pud_t *pudp = pud_offset(pgdp, address); | ||
694 | pmd_t *pmdp = pmd_offset(pudp, address); | ||
695 | pte_t *ptep; | ||
696 | 731 | ||
697 | regs->u_regs[UREG_I7] = (unsigned long) (&(sf->insns[0]) - 2); | 732 | regs->u_regs[UREG_I7] = (unsigned long) (&(sf->insns[0]) - 2); |
698 | 733 | ||
@@ -704,38 +739,32 @@ static void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs, | |||
704 | if (err) | 739 | if (err) |
705 | goto sigsegv; | 740 | goto sigsegv; |
706 | 741 | ||
707 | preempt_disable(); | 742 | flush_signal_insns(address); |
708 | ptep = pte_offset_map(pmdp, address); | ||
709 | if (pte_present(*ptep)) { | ||
710 | unsigned long page = (unsigned long) | ||
711 | page_address(pte_page(*ptep)); | ||
712 | |||
713 | wmb(); | ||
714 | __asm__ __volatile__("flush %0 + %1" | ||
715 | : /* no outputs */ | ||
716 | : "r" (page), | ||
717 | "r" (address & (PAGE_SIZE - 1)) | ||
718 | : "memory"); | ||
719 | } | ||
720 | pte_unmap(ptep); | ||
721 | preempt_enable(); | ||
722 | } | 743 | } |
723 | return; | 744 | return 0; |
724 | 745 | ||
725 | sigill: | 746 | sigill: |
726 | do_exit(SIGILL); | 747 | do_exit(SIGILL); |
748 | return -EINVAL; | ||
749 | |||
727 | sigsegv: | 750 | sigsegv: |
728 | force_sigsegv(signr, current); | 751 | force_sigsegv(signr, current); |
752 | return -EFAULT; | ||
729 | } | 753 | } |
730 | 754 | ||
731 | static inline void handle_signal32(unsigned long signr, struct k_sigaction *ka, | 755 | static inline int handle_signal32(unsigned long signr, struct k_sigaction *ka, |
732 | siginfo_t *info, | 756 | siginfo_t *info, |
733 | sigset_t *oldset, struct pt_regs *regs) | 757 | sigset_t *oldset, struct pt_regs *regs) |
734 | { | 758 | { |
759 | int err; | ||
760 | |||
735 | if (ka->sa.sa_flags & SA_SIGINFO) | 761 | if (ka->sa.sa_flags & SA_SIGINFO) |
736 | setup_rt_frame32(ka, regs, signr, oldset, info); | 762 | err = setup_rt_frame32(ka, regs, signr, oldset, info); |
737 | else | 763 | else |
738 | setup_frame32(ka, regs, signr, oldset); | 764 | err = setup_frame32(ka, regs, signr, oldset); |
765 | |||
766 | if (err) | ||
767 | return err; | ||
739 | 768 | ||
740 | spin_lock_irq(¤t->sighand->siglock); | 769 | spin_lock_irq(¤t->sighand->siglock); |
741 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); | 770 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); |
@@ -743,6 +772,10 @@ static inline void handle_signal32(unsigned long signr, struct k_sigaction *ka, | |||
743 | sigaddset(¤t->blocked,signr); | 772 | sigaddset(¤t->blocked,signr); |
744 | recalc_sigpending(); | 773 | recalc_sigpending(); |
745 | spin_unlock_irq(¤t->sighand->siglock); | 774 | spin_unlock_irq(¤t->sighand->siglock); |
775 | |||
776 | tracehook_signal_handler(signr, info, ka, regs, 0); | ||
777 | |||
778 | return 0; | ||
746 | } | 779 | } |
747 | 780 | ||
748 | static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs, | 781 | static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs, |
@@ -789,16 +822,14 @@ void do_signal32(sigset_t *oldset, struct pt_regs * regs, | |||
789 | if (signr > 0) { | 822 | if (signr > 0) { |
790 | if (restart_syscall) | 823 | if (restart_syscall) |
791 | syscall_restart32(orig_i0, regs, &ka.sa); | 824 | syscall_restart32(orig_i0, regs, &ka.sa); |
792 | handle_signal32(signr, &ka, &info, oldset, regs); | 825 | if (handle_signal32(signr, &ka, &info, oldset, regs) == 0) { |
793 | 826 | /* A signal was successfully delivered; the saved | |
794 | /* A signal was successfully delivered; the saved | 827 | * sigmask will have been stored in the signal frame, |
795 | * sigmask will have been stored in the signal frame, | 828 | * and will be restored by sigreturn, so we can simply |
796 | * and will be restored by sigreturn, so we can simply | 829 | * clear the TS_RESTORE_SIGMASK flag. |
797 | * clear the TS_RESTORE_SIGMASK flag. | 830 | */ |
798 | */ | 831 | current_thread_info()->status &= ~TS_RESTORE_SIGMASK; |
799 | current_thread_info()->status &= ~TS_RESTORE_SIGMASK; | 832 | } |
800 | |||
801 | tracehook_signal_handler(signr, &info, &ka, regs, 0); | ||
802 | return; | 833 | return; |
803 | } | 834 | } |
804 | if (restart_syscall && | 835 | if (restart_syscall && |
@@ -809,12 +840,14 @@ void do_signal32(sigset_t *oldset, struct pt_regs * regs, | |||
809 | regs->u_regs[UREG_I0] = orig_i0; | 840 | regs->u_regs[UREG_I0] = orig_i0; |
810 | regs->tpc -= 4; | 841 | regs->tpc -= 4; |
811 | regs->tnpc -= 4; | 842 | regs->tnpc -= 4; |
843 | pt_regs_clear_syscall(regs); | ||
812 | } | 844 | } |
813 | if (restart_syscall && | 845 | if (restart_syscall && |
814 | regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) { | 846 | regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) { |
815 | regs->u_regs[UREG_G1] = __NR_restart_syscall; | 847 | regs->u_regs[UREG_G1] = __NR_restart_syscall; |
816 | regs->tpc -= 4; | 848 | regs->tpc -= 4; |
817 | regs->tnpc -= 4; | 849 | regs->tnpc -= 4; |
850 | pt_regs_clear_syscall(regs); | ||
818 | } | 851 | } |
819 | 852 | ||
820 | /* If there's no signal to deliver, we just put the saved sigmask | 853 | /* If there's no signal to deliver, we just put the saved sigmask |
diff --git a/arch/sparc/kernel/signal_32.c b/arch/sparc/kernel/signal_32.c index 9882df92ba0a..5e5c5fd03783 100644 --- a/arch/sparc/kernel/signal_32.c +++ b/arch/sparc/kernel/signal_32.c | |||
@@ -315,8 +315,8 @@ save_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu) | |||
315 | return err; | 315 | return err; |
316 | } | 316 | } |
317 | 317 | ||
318 | static void setup_frame(struct k_sigaction *ka, struct pt_regs *regs, | 318 | static int setup_frame(struct k_sigaction *ka, struct pt_regs *regs, |
319 | int signo, sigset_t *oldset) | 319 | int signo, sigset_t *oldset) |
320 | { | 320 | { |
321 | struct signal_frame __user *sf; | 321 | struct signal_frame __user *sf; |
322 | int sigframe_size, err; | 322 | int sigframe_size, err; |
@@ -384,16 +384,19 @@ static void setup_frame(struct k_sigaction *ka, struct pt_regs *regs, | |||
384 | /* Flush instruction space. */ | 384 | /* Flush instruction space. */ |
385 | flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0])); | 385 | flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0])); |
386 | } | 386 | } |
387 | return; | 387 | return 0; |
388 | 388 | ||
389 | sigill_and_return: | 389 | sigill_and_return: |
390 | do_exit(SIGILL); | 390 | do_exit(SIGILL); |
391 | return -EINVAL; | ||
392 | |||
391 | sigsegv: | 393 | sigsegv: |
392 | force_sigsegv(signo, current); | 394 | force_sigsegv(signo, current); |
395 | return -EFAULT; | ||
393 | } | 396 | } |
394 | 397 | ||
395 | static void setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs, | 398 | static int setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs, |
396 | int signo, sigset_t *oldset, siginfo_t *info) | 399 | int signo, sigset_t *oldset, siginfo_t *info) |
397 | { | 400 | { |
398 | struct rt_signal_frame __user *sf; | 401 | struct rt_signal_frame __user *sf; |
399 | int sigframe_size; | 402 | int sigframe_size; |
@@ -466,22 +469,30 @@ static void setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs, | |||
466 | /* Flush instruction space. */ | 469 | /* Flush instruction space. */ |
467 | flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0])); | 470 | flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0])); |
468 | } | 471 | } |
469 | return; | 472 | return 0; |
470 | 473 | ||
471 | sigill: | 474 | sigill: |
472 | do_exit(SIGILL); | 475 | do_exit(SIGILL); |
476 | return -EINVAL; | ||
477 | |||
473 | sigsegv: | 478 | sigsegv: |
474 | force_sigsegv(signo, current); | 479 | force_sigsegv(signo, current); |
480 | return -EFAULT; | ||
475 | } | 481 | } |
476 | 482 | ||
477 | static inline void | 483 | static inline int |
478 | handle_signal(unsigned long signr, struct k_sigaction *ka, | 484 | handle_signal(unsigned long signr, struct k_sigaction *ka, |
479 | siginfo_t *info, sigset_t *oldset, struct pt_regs *regs) | 485 | siginfo_t *info, sigset_t *oldset, struct pt_regs *regs) |
480 | { | 486 | { |
487 | int err; | ||
488 | |||
481 | if (ka->sa.sa_flags & SA_SIGINFO) | 489 | if (ka->sa.sa_flags & SA_SIGINFO) |
482 | setup_rt_frame(ka, regs, signr, oldset, info); | 490 | err = setup_rt_frame(ka, regs, signr, oldset, info); |
483 | else | 491 | else |
484 | setup_frame(ka, regs, signr, oldset); | 492 | err = setup_frame(ka, regs, signr, oldset); |
493 | |||
494 | if (err) | ||
495 | return err; | ||
485 | 496 | ||
486 | spin_lock_irq(¤t->sighand->siglock); | 497 | spin_lock_irq(¤t->sighand->siglock); |
487 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); | 498 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); |
@@ -489,6 +500,10 @@ handle_signal(unsigned long signr, struct k_sigaction *ka, | |||
489 | sigaddset(¤t->blocked, signr); | 500 | sigaddset(¤t->blocked, signr); |
490 | recalc_sigpending(); | 501 | recalc_sigpending(); |
491 | spin_unlock_irq(¤t->sighand->siglock); | 502 | spin_unlock_irq(¤t->sighand->siglock); |
503 | |||
504 | tracehook_signal_handler(signr, info, ka, regs, 0); | ||
505 | |||
506 | return 0; | ||
492 | } | 507 | } |
493 | 508 | ||
494 | static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs, | 509 | static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs, |
@@ -546,17 +561,15 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0) | |||
546 | if (signr > 0) { | 561 | if (signr > 0) { |
547 | if (restart_syscall) | 562 | if (restart_syscall) |
548 | syscall_restart(orig_i0, regs, &ka.sa); | 563 | syscall_restart(orig_i0, regs, &ka.sa); |
549 | handle_signal(signr, &ka, &info, oldset, regs); | 564 | if (handle_signal(signr, &ka, &info, oldset, regs) == 0) { |
550 | 565 | /* a signal was successfully delivered; the saved | |
551 | /* a signal was successfully delivered; the saved | 566 | * sigmask will have been stored in the signal frame, |
552 | * sigmask will have been stored in the signal frame, | 567 | * and will be restored by sigreturn, so we can simply |
553 | * and will be restored by sigreturn, so we can simply | 568 | * clear the TIF_RESTORE_SIGMASK flag. |
554 | * clear the TIF_RESTORE_SIGMASK flag. | 569 | */ |
555 | */ | 570 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) |
556 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) | 571 | clear_thread_flag(TIF_RESTORE_SIGMASK); |
557 | clear_thread_flag(TIF_RESTORE_SIGMASK); | 572 | } |
558 | |||
559 | tracehook_signal_handler(signr, &info, &ka, regs, 0); | ||
560 | return; | 573 | return; |
561 | } | 574 | } |
562 | if (restart_syscall && | 575 | if (restart_syscall && |
@@ -567,12 +580,14 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0) | |||
567 | regs->u_regs[UREG_I0] = orig_i0; | 580 | regs->u_regs[UREG_I0] = orig_i0; |
568 | regs->pc -= 4; | 581 | regs->pc -= 4; |
569 | regs->npc -= 4; | 582 | regs->npc -= 4; |
583 | pt_regs_clear_syscall(regs); | ||
570 | } | 584 | } |
571 | if (restart_syscall && | 585 | if (restart_syscall && |
572 | regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) { | 586 | regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) { |
573 | regs->u_regs[UREG_G1] = __NR_restart_syscall; | 587 | regs->u_regs[UREG_G1] = __NR_restart_syscall; |
574 | regs->pc -= 4; | 588 | regs->pc -= 4; |
575 | regs->npc -= 4; | 589 | regs->npc -= 4; |
590 | pt_regs_clear_syscall(regs); | ||
576 | } | 591 | } |
577 | 592 | ||
578 | /* if there's no signal to deliver, we just put the saved sigmask | 593 | /* if there's no signal to deliver, we just put the saved sigmask |
diff --git a/arch/sparc/kernel/signal_64.c b/arch/sparc/kernel/signal_64.c index 9fa48c30037e..006fe4515886 100644 --- a/arch/sparc/kernel/signal_64.c +++ b/arch/sparc/kernel/signal_64.c | |||
@@ -409,7 +409,7 @@ static inline void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs * | |||
409 | return (void __user *) sp; | 409 | return (void __user *) sp; |
410 | } | 410 | } |
411 | 411 | ||
412 | static inline void | 412 | static inline int |
413 | setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs, | 413 | setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs, |
414 | int signo, sigset_t *oldset, siginfo_t *info) | 414 | int signo, sigset_t *oldset, siginfo_t *info) |
415 | { | 415 | { |
@@ -483,26 +483,37 @@ setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs, | |||
483 | } | 483 | } |
484 | /* 4. return to kernel instructions */ | 484 | /* 4. return to kernel instructions */ |
485 | regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer; | 485 | regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer; |
486 | return; | 486 | return 0; |
487 | 487 | ||
488 | sigill: | 488 | sigill: |
489 | do_exit(SIGILL); | 489 | do_exit(SIGILL); |
490 | return -EINVAL; | ||
491 | |||
490 | sigsegv: | 492 | sigsegv: |
491 | force_sigsegv(signo, current); | 493 | force_sigsegv(signo, current); |
494 | return -EFAULT; | ||
492 | } | 495 | } |
493 | 496 | ||
494 | static inline void handle_signal(unsigned long signr, struct k_sigaction *ka, | 497 | static inline int handle_signal(unsigned long signr, struct k_sigaction *ka, |
495 | siginfo_t *info, | 498 | siginfo_t *info, |
496 | sigset_t *oldset, struct pt_regs *regs) | 499 | sigset_t *oldset, struct pt_regs *regs) |
497 | { | 500 | { |
498 | setup_rt_frame(ka, regs, signr, oldset, | 501 | int err; |
499 | (ka->sa.sa_flags & SA_SIGINFO) ? info : NULL); | 502 | |
503 | err = setup_rt_frame(ka, regs, signr, oldset, | ||
504 | (ka->sa.sa_flags & SA_SIGINFO) ? info : NULL); | ||
505 | if (err) | ||
506 | return err; | ||
500 | spin_lock_irq(¤t->sighand->siglock); | 507 | spin_lock_irq(¤t->sighand->siglock); |
501 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); | 508 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); |
502 | if (!(ka->sa.sa_flags & SA_NOMASK)) | 509 | if (!(ka->sa.sa_flags & SA_NOMASK)) |
503 | sigaddset(¤t->blocked,signr); | 510 | sigaddset(¤t->blocked,signr); |
504 | recalc_sigpending(); | 511 | recalc_sigpending(); |
505 | spin_unlock_irq(¤t->sighand->siglock); | 512 | spin_unlock_irq(¤t->sighand->siglock); |
513 | |||
514 | tracehook_signal_handler(signr, info, ka, regs, 0); | ||
515 | |||
516 | return 0; | ||
506 | } | 517 | } |
507 | 518 | ||
508 | static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs, | 519 | static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs, |
@@ -571,16 +582,14 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0) | |||
571 | if (signr > 0) { | 582 | if (signr > 0) { |
572 | if (restart_syscall) | 583 | if (restart_syscall) |
573 | syscall_restart(orig_i0, regs, &ka.sa); | 584 | syscall_restart(orig_i0, regs, &ka.sa); |
574 | handle_signal(signr, &ka, &info, oldset, regs); | 585 | if (handle_signal(signr, &ka, &info, oldset, regs) == 0) { |
575 | 586 | /* A signal was successfully delivered; the saved | |
576 | /* A signal was successfully delivered; the saved | 587 | * sigmask will have been stored in the signal frame, |
577 | * sigmask will have been stored in the signal frame, | 588 | * and will be restored by sigreturn, so we can simply |
578 | * and will be restored by sigreturn, so we can simply | 589 | * clear the TS_RESTORE_SIGMASK flag. |
579 | * clear the TS_RESTORE_SIGMASK flag. | 590 | */ |
580 | */ | 591 | current_thread_info()->status &= ~TS_RESTORE_SIGMASK; |
581 | current_thread_info()->status &= ~TS_RESTORE_SIGMASK; | 592 | } |
582 | |||
583 | tracehook_signal_handler(signr, &info, &ka, regs, 0); | ||
584 | return; | 593 | return; |
585 | } | 594 | } |
586 | if (restart_syscall && | 595 | if (restart_syscall && |
@@ -591,12 +600,14 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0) | |||
591 | regs->u_regs[UREG_I0] = orig_i0; | 600 | regs->u_regs[UREG_I0] = orig_i0; |
592 | regs->tpc -= 4; | 601 | regs->tpc -= 4; |
593 | regs->tnpc -= 4; | 602 | regs->tnpc -= 4; |
603 | pt_regs_clear_syscall(regs); | ||
594 | } | 604 | } |
595 | if (restart_syscall && | 605 | if (restart_syscall && |
596 | regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) { | 606 | regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) { |
597 | regs->u_regs[UREG_G1] = __NR_restart_syscall; | 607 | regs->u_regs[UREG_G1] = __NR_restart_syscall; |
598 | regs->tpc -= 4; | 608 | regs->tpc -= 4; |
599 | regs->tnpc -= 4; | 609 | regs->tnpc -= 4; |
610 | pt_regs_clear_syscall(regs); | ||
600 | } | 611 | } |
601 | 612 | ||
602 | /* If there's no signal to deliver, we just put the saved sigmask | 613 | /* If there's no signal to deliver, we just put the saved sigmask |
diff --git a/arch/tile/kernel/intvec_32.S b/arch/tile/kernel/intvec_32.S index 84f296ca9e63..8f58bdff20d7 100644 --- a/arch/tile/kernel/intvec_32.S +++ b/arch/tile/kernel/intvec_32.S | |||
@@ -1506,13 +1506,6 @@ handle_ill: | |||
1506 | } | 1506 | } |
1507 | STD_ENDPROC(handle_ill) | 1507 | STD_ENDPROC(handle_ill) |
1508 | 1508 | ||
1509 | .pushsection .rodata, "a" | ||
1510 | .align 8 | ||
1511 | bpt_code: | ||
1512 | bpt | ||
1513 | ENDPROC(bpt_code) | ||
1514 | .popsection | ||
1515 | |||
1516 | /* Various stub interrupt handlers and syscall handlers */ | 1509 | /* Various stub interrupt handlers and syscall handlers */ |
1517 | 1510 | ||
1518 | STD_ENTRY_LOCAL(_kernel_double_fault) | 1511 | STD_ENTRY_LOCAL(_kernel_double_fault) |
diff --git a/arch/um/kernel/exec.c b/arch/um/kernel/exec.c index cd145eda3579..49b5e1eb3262 100644 --- a/arch/um/kernel/exec.c +++ b/arch/um/kernel/exec.c | |||
@@ -62,7 +62,7 @@ static long execve1(const char *file, | |||
62 | return error; | 62 | return error; |
63 | } | 63 | } |
64 | 64 | ||
65 | long um_execve(const char *file, char __user *__user *argv, char __user *__user *env) | 65 | long um_execve(const char *file, const char __user *const __user *argv, const char __user *const __user *env) |
66 | { | 66 | { |
67 | long err; | 67 | long err; |
68 | 68 | ||
@@ -72,8 +72,8 @@ long um_execve(const char *file, char __user *__user *argv, char __user *__user | |||
72 | return err; | 72 | return err; |
73 | } | 73 | } |
74 | 74 | ||
75 | long sys_execve(const char __user *file, char __user *__user *argv, | 75 | long sys_execve(const char __user *file, const char __user *const __user *argv, |
76 | char __user *__user *env) | 76 | const char __user *const __user *env) |
77 | { | 77 | { |
78 | long error; | 78 | long error; |
79 | char *filename; | 79 | char *filename; |
diff --git a/arch/um/kernel/internal.h b/arch/um/kernel/internal.h index 1303a105fe91..5bf97db24a04 100644 --- a/arch/um/kernel/internal.h +++ b/arch/um/kernel/internal.h | |||
@@ -1 +1 @@ | |||
extern long um_execve(const char *file, char __user *__user *argv, char __user *__user *env); | extern long um_execve(const char *file, const char __user *const __user *argv, const char __user *const __user *env); | ||
diff --git a/arch/um/kernel/syscall.c b/arch/um/kernel/syscall.c index 5ddb246626db..f958cb876ee3 100644 --- a/arch/um/kernel/syscall.c +++ b/arch/um/kernel/syscall.c | |||
@@ -60,8 +60,8 @@ int kernel_execve(const char *filename, | |||
60 | 60 | ||
61 | fs = get_fs(); | 61 | fs = get_fs(); |
62 | set_fs(KERNEL_DS); | 62 | set_fs(KERNEL_DS); |
63 | ret = um_execve(filename, (char __user *__user *)argv, | 63 | ret = um_execve(filename, (const char __user *const __user *)argv, |
64 | (char __user *__user *) envp); | 64 | (const char __user *const __user *) envp); |
65 | set_fs(fs); | 65 | set_fs(fs); |
66 | 66 | ||
67 | return ret; | 67 | return ret; |
diff --git a/arch/x86/boot/early_serial_console.c b/arch/x86/boot/early_serial_console.c index 030f4b93e255..5df2869c874b 100644 --- a/arch/x86/boot/early_serial_console.c +++ b/arch/x86/boot/early_serial_console.c | |||
@@ -58,7 +58,19 @@ static void parse_earlyprintk(void) | |||
58 | if (arg[pos] == ',') | 58 | if (arg[pos] == ',') |
59 | pos++; | 59 | pos++; |
60 | 60 | ||
61 | if (!strncmp(arg, "ttyS", 4)) { | 61 | /* |
62 | * make sure we have | ||
63 | * "serial,0x3f8,115200" | ||
64 | * "serial,ttyS0,115200" | ||
65 | * "ttyS0,115200" | ||
66 | */ | ||
67 | if (pos == 7 && !strncmp(arg + pos, "0x", 2)) { | ||
68 | port = simple_strtoull(arg + pos, &e, 16); | ||
69 | if (port == 0 || arg + pos == e) | ||
70 | port = DEFAULT_SERIAL_PORT; | ||
71 | else | ||
72 | pos = e - arg; | ||
73 | } else if (!strncmp(arg + pos, "ttyS", 4)) { | ||
62 | static const int bases[] = { 0x3f8, 0x2f8 }; | 74 | static const int bases[] = { 0x3f8, 0x2f8 }; |
63 | int idx = 0; | 75 | int idx = 0; |
64 | 76 | ||
diff --git a/arch/x86/include/asm/amd_iommu_proto.h b/arch/x86/include/asm/amd_iommu_proto.h index d2544f1d705d..cb030374b90a 100644 --- a/arch/x86/include/asm/amd_iommu_proto.h +++ b/arch/x86/include/asm/amd_iommu_proto.h | |||
@@ -38,4 +38,10 @@ static inline void amd_iommu_stats_init(void) { } | |||
38 | 38 | ||
39 | #endif /* !CONFIG_AMD_IOMMU_STATS */ | 39 | #endif /* !CONFIG_AMD_IOMMU_STATS */ |
40 | 40 | ||
41 | static inline bool is_rd890_iommu(struct pci_dev *pdev) | ||
42 | { | ||
43 | return (pdev->vendor == PCI_VENDOR_ID_ATI) && | ||
44 | (pdev->device == PCI_DEVICE_ID_RD890_IOMMU); | ||
45 | } | ||
46 | |||
41 | #endif /* _ASM_X86_AMD_IOMMU_PROTO_H */ | 47 | #endif /* _ASM_X86_AMD_IOMMU_PROTO_H */ |
diff --git a/arch/x86/include/asm/amd_iommu_types.h b/arch/x86/include/asm/amd_iommu_types.h index 7014e88bc779..08616180deaf 100644 --- a/arch/x86/include/asm/amd_iommu_types.h +++ b/arch/x86/include/asm/amd_iommu_types.h | |||
@@ -368,6 +368,9 @@ struct amd_iommu { | |||
368 | /* capabilities of that IOMMU read from ACPI */ | 368 | /* capabilities of that IOMMU read from ACPI */ |
369 | u32 cap; | 369 | u32 cap; |
370 | 370 | ||
371 | /* flags read from acpi table */ | ||
372 | u8 acpi_flags; | ||
373 | |||
371 | /* | 374 | /* |
372 | * Capability pointer. There could be more than one IOMMU per PCI | 375 | * Capability pointer. There could be more than one IOMMU per PCI |
373 | * device function if there are more than one AMD IOMMU capability | 376 | * device function if there are more than one AMD IOMMU capability |
@@ -411,6 +414,15 @@ struct amd_iommu { | |||
411 | 414 | ||
412 | /* default dma_ops domain for that IOMMU */ | 415 | /* default dma_ops domain for that IOMMU */ |
413 | struct dma_ops_domain *default_dom; | 416 | struct dma_ops_domain *default_dom; |
417 | |||
418 | /* | ||
419 | * This array is required to work around a potential BIOS bug. | ||
420 | * The BIOS may miss to restore parts of the PCI configuration | ||
421 | * space when the system resumes from S3. The result is that the | ||
422 | * IOMMU does not execute commands anymore which leads to system | ||
423 | * failure. | ||
424 | */ | ||
425 | u32 cache_cfg[4]; | ||
414 | }; | 426 | }; |
415 | 427 | ||
416 | /* | 428 | /* |
diff --git a/arch/x86/include/asm/bitops.h b/arch/x86/include/asm/bitops.h index 545776efeb16..bafd80defa43 100644 --- a/arch/x86/include/asm/bitops.h +++ b/arch/x86/include/asm/bitops.h | |||
@@ -309,7 +309,7 @@ static inline int test_and_change_bit(int nr, volatile unsigned long *addr) | |||
309 | static __always_inline int constant_test_bit(unsigned int nr, const volatile unsigned long *addr) | 309 | static __always_inline int constant_test_bit(unsigned int nr, const volatile unsigned long *addr) |
310 | { | 310 | { |
311 | return ((1UL << (nr % BITS_PER_LONG)) & | 311 | return ((1UL << (nr % BITS_PER_LONG)) & |
312 | (((unsigned long *)addr)[nr / BITS_PER_LONG])) != 0; | 312 | (addr[nr / BITS_PER_LONG])) != 0; |
313 | } | 313 | } |
314 | 314 | ||
315 | static inline int variable_test_bit(int nr, volatile const unsigned long *addr) | 315 | static inline int variable_test_bit(int nr, volatile const unsigned long *addr) |
diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h index c6fbb7b430d1..3f76523589af 100644 --- a/arch/x86/include/asm/cpufeature.h +++ b/arch/x86/include/asm/cpufeature.h | |||
@@ -168,6 +168,7 @@ | |||
168 | #define X86_FEATURE_XSAVEOPT (7*32+ 4) /* Optimized Xsave */ | 168 | #define X86_FEATURE_XSAVEOPT (7*32+ 4) /* Optimized Xsave */ |
169 | #define X86_FEATURE_PLN (7*32+ 5) /* Intel Power Limit Notification */ | 169 | #define X86_FEATURE_PLN (7*32+ 5) /* Intel Power Limit Notification */ |
170 | #define X86_FEATURE_PTS (7*32+ 6) /* Intel Package Thermal Status */ | 170 | #define X86_FEATURE_PTS (7*32+ 6) /* Intel Package Thermal Status */ |
171 | #define X86_FEATURE_DTS (7*32+ 7) /* Digital Thermal Sensor */ | ||
171 | 172 | ||
172 | /* Virtualization flags: Linux defined, word 8 */ | 173 | /* Virtualization flags: Linux defined, word 8 */ |
173 | #define X86_FEATURE_TPR_SHADOW (8*32+ 0) /* Intel TPR Shadow */ | 174 | #define X86_FEATURE_TPR_SHADOW (8*32+ 0) /* Intel TPR Shadow */ |
diff --git a/arch/x86/include/asm/hw_breakpoint.h b/arch/x86/include/asm/hw_breakpoint.h index 528a11e8d3e3..824ca07860d0 100644 --- a/arch/x86/include/asm/hw_breakpoint.h +++ b/arch/x86/include/asm/hw_breakpoint.h | |||
@@ -20,7 +20,7 @@ struct arch_hw_breakpoint { | |||
20 | #include <linux/list.h> | 20 | #include <linux/list.h> |
21 | 21 | ||
22 | /* Available HW breakpoint length encodings */ | 22 | /* Available HW breakpoint length encodings */ |
23 | #define X86_BREAKPOINT_LEN_X 0x00 | 23 | #define X86_BREAKPOINT_LEN_X 0x40 |
24 | #define X86_BREAKPOINT_LEN_1 0x40 | 24 | #define X86_BREAKPOINT_LEN_1 0x40 |
25 | #define X86_BREAKPOINT_LEN_2 0x44 | 25 | #define X86_BREAKPOINT_LEN_2 0x44 |
26 | #define X86_BREAKPOINT_LEN_4 0x4c | 26 | #define X86_BREAKPOINT_LEN_4 0x4c |
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index 0925676266bd..fedf32a8c3ec 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile | |||
@@ -11,6 +11,8 @@ ifdef CONFIG_FUNCTION_TRACER | |||
11 | CFLAGS_REMOVE_tsc.o = -pg | 11 | CFLAGS_REMOVE_tsc.o = -pg |
12 | CFLAGS_REMOVE_rtc.o = -pg | 12 | CFLAGS_REMOVE_rtc.o = -pg |
13 | CFLAGS_REMOVE_paravirt-spinlocks.o = -pg | 13 | CFLAGS_REMOVE_paravirt-spinlocks.o = -pg |
14 | CFLAGS_REMOVE_pvclock.o = -pg | ||
15 | CFLAGS_REMOVE_kvmclock.o = -pg | ||
14 | CFLAGS_REMOVE_ftrace.o = -pg | 16 | CFLAGS_REMOVE_ftrace.o = -pg |
15 | CFLAGS_REMOVE_early_printk.o = -pg | 17 | CFLAGS_REMOVE_early_printk.o = -pg |
16 | endif | 18 | endif |
diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c index fa044e1e30a2..679b6450382b 100644 --- a/arch/x86/kernel/amd_iommu.c +++ b/arch/x86/kernel/amd_iommu.c | |||
@@ -1953,6 +1953,7 @@ static void __unmap_single(struct dma_ops_domain *dma_dom, | |||
1953 | size_t size, | 1953 | size_t size, |
1954 | int dir) | 1954 | int dir) |
1955 | { | 1955 | { |
1956 | dma_addr_t flush_addr; | ||
1956 | dma_addr_t i, start; | 1957 | dma_addr_t i, start; |
1957 | unsigned int pages; | 1958 | unsigned int pages; |
1958 | 1959 | ||
@@ -1960,6 +1961,7 @@ static void __unmap_single(struct dma_ops_domain *dma_dom, | |||
1960 | (dma_addr + size > dma_dom->aperture_size)) | 1961 | (dma_addr + size > dma_dom->aperture_size)) |
1961 | return; | 1962 | return; |
1962 | 1963 | ||
1964 | flush_addr = dma_addr; | ||
1963 | pages = iommu_num_pages(dma_addr, size, PAGE_SIZE); | 1965 | pages = iommu_num_pages(dma_addr, size, PAGE_SIZE); |
1964 | dma_addr &= PAGE_MASK; | 1966 | dma_addr &= PAGE_MASK; |
1965 | start = dma_addr; | 1967 | start = dma_addr; |
@@ -1974,7 +1976,7 @@ static void __unmap_single(struct dma_ops_domain *dma_dom, | |||
1974 | dma_ops_free_addresses(dma_dom, dma_addr, pages); | 1976 | dma_ops_free_addresses(dma_dom, dma_addr, pages); |
1975 | 1977 | ||
1976 | if (amd_iommu_unmap_flush || dma_dom->need_flush) { | 1978 | if (amd_iommu_unmap_flush || dma_dom->need_flush) { |
1977 | iommu_flush_pages(&dma_dom->domain, dma_addr, size); | 1979 | iommu_flush_pages(&dma_dom->domain, flush_addr, size); |
1978 | dma_dom->need_flush = false; | 1980 | dma_dom->need_flush = false; |
1979 | } | 1981 | } |
1980 | } | 1982 | } |
diff --git a/arch/x86/kernel/amd_iommu_init.c b/arch/x86/kernel/amd_iommu_init.c index 3cc63e2b8dd4..5a170cbbbed8 100644 --- a/arch/x86/kernel/amd_iommu_init.c +++ b/arch/x86/kernel/amd_iommu_init.c | |||
@@ -632,6 +632,13 @@ static void __init init_iommu_from_pci(struct amd_iommu *iommu) | |||
632 | iommu->last_device = calc_devid(MMIO_GET_BUS(range), | 632 | iommu->last_device = calc_devid(MMIO_GET_BUS(range), |
633 | MMIO_GET_LD(range)); | 633 | MMIO_GET_LD(range)); |
634 | iommu->evt_msi_num = MMIO_MSI_NUM(misc); | 634 | iommu->evt_msi_num = MMIO_MSI_NUM(misc); |
635 | |||
636 | if (is_rd890_iommu(iommu->dev)) { | ||
637 | pci_read_config_dword(iommu->dev, 0xf0, &iommu->cache_cfg[0]); | ||
638 | pci_read_config_dword(iommu->dev, 0xf4, &iommu->cache_cfg[1]); | ||
639 | pci_read_config_dword(iommu->dev, 0xf8, &iommu->cache_cfg[2]); | ||
640 | pci_read_config_dword(iommu->dev, 0xfc, &iommu->cache_cfg[3]); | ||
641 | } | ||
635 | } | 642 | } |
636 | 643 | ||
637 | /* | 644 | /* |
@@ -649,29 +656,9 @@ static void __init init_iommu_from_acpi(struct amd_iommu *iommu, | |||
649 | struct ivhd_entry *e; | 656 | struct ivhd_entry *e; |
650 | 657 | ||
651 | /* | 658 | /* |
652 | * First set the recommended feature enable bits from ACPI | 659 | * First save the recommended feature enable bits from ACPI |
653 | * into the IOMMU control registers | ||
654 | */ | 660 | */ |
655 | h->flags & IVHD_FLAG_HT_TUN_EN_MASK ? | 661 | iommu->acpi_flags = h->flags; |
656 | iommu_feature_enable(iommu, CONTROL_HT_TUN_EN) : | ||
657 | iommu_feature_disable(iommu, CONTROL_HT_TUN_EN); | ||
658 | |||
659 | h->flags & IVHD_FLAG_PASSPW_EN_MASK ? | ||
660 | iommu_feature_enable(iommu, CONTROL_PASSPW_EN) : | ||
661 | iommu_feature_disable(iommu, CONTROL_PASSPW_EN); | ||
662 | |||
663 | h->flags & IVHD_FLAG_RESPASSPW_EN_MASK ? | ||
664 | iommu_feature_enable(iommu, CONTROL_RESPASSPW_EN) : | ||
665 | iommu_feature_disable(iommu, CONTROL_RESPASSPW_EN); | ||
666 | |||
667 | h->flags & IVHD_FLAG_ISOC_EN_MASK ? | ||
668 | iommu_feature_enable(iommu, CONTROL_ISOC_EN) : | ||
669 | iommu_feature_disable(iommu, CONTROL_ISOC_EN); | ||
670 | |||
671 | /* | ||
672 | * make IOMMU memory accesses cache coherent | ||
673 | */ | ||
674 | iommu_feature_enable(iommu, CONTROL_COHERENT_EN); | ||
675 | 662 | ||
676 | /* | 663 | /* |
677 | * Done. Now parse the device entries | 664 | * Done. Now parse the device entries |
@@ -1116,6 +1103,40 @@ static void init_device_table(void) | |||
1116 | } | 1103 | } |
1117 | } | 1104 | } |
1118 | 1105 | ||
1106 | static void iommu_init_flags(struct amd_iommu *iommu) | ||
1107 | { | ||
1108 | iommu->acpi_flags & IVHD_FLAG_HT_TUN_EN_MASK ? | ||
1109 | iommu_feature_enable(iommu, CONTROL_HT_TUN_EN) : | ||
1110 | iommu_feature_disable(iommu, CONTROL_HT_TUN_EN); | ||
1111 | |||
1112 | iommu->acpi_flags & IVHD_FLAG_PASSPW_EN_MASK ? | ||
1113 | iommu_feature_enable(iommu, CONTROL_PASSPW_EN) : | ||
1114 | iommu_feature_disable(iommu, CONTROL_PASSPW_EN); | ||
1115 | |||
1116 | iommu->acpi_flags & IVHD_FLAG_RESPASSPW_EN_MASK ? | ||
1117 | iommu_feature_enable(iommu, CONTROL_RESPASSPW_EN) : | ||
1118 | iommu_feature_disable(iommu, CONTROL_RESPASSPW_EN); | ||
1119 | |||
1120 | iommu->acpi_flags & IVHD_FLAG_ISOC_EN_MASK ? | ||
1121 | iommu_feature_enable(iommu, CONTROL_ISOC_EN) : | ||
1122 | iommu_feature_disable(iommu, CONTROL_ISOC_EN); | ||
1123 | |||
1124 | /* | ||
1125 | * make IOMMU memory accesses cache coherent | ||
1126 | */ | ||
1127 | iommu_feature_enable(iommu, CONTROL_COHERENT_EN); | ||
1128 | } | ||
1129 | |||
1130 | static void iommu_apply_quirks(struct amd_iommu *iommu) | ||
1131 | { | ||
1132 | if (is_rd890_iommu(iommu->dev)) { | ||
1133 | pci_write_config_dword(iommu->dev, 0xf0, iommu->cache_cfg[0]); | ||
1134 | pci_write_config_dword(iommu->dev, 0xf4, iommu->cache_cfg[1]); | ||
1135 | pci_write_config_dword(iommu->dev, 0xf8, iommu->cache_cfg[2]); | ||
1136 | pci_write_config_dword(iommu->dev, 0xfc, iommu->cache_cfg[3]); | ||
1137 | } | ||
1138 | } | ||
1139 | |||
1119 | /* | 1140 | /* |
1120 | * This function finally enables all IOMMUs found in the system after | 1141 | * This function finally enables all IOMMUs found in the system after |
1121 | * they have been initialized | 1142 | * they have been initialized |
@@ -1126,6 +1147,8 @@ static void enable_iommus(void) | |||
1126 | 1147 | ||
1127 | for_each_iommu(iommu) { | 1148 | for_each_iommu(iommu) { |
1128 | iommu_disable(iommu); | 1149 | iommu_disable(iommu); |
1150 | iommu_apply_quirks(iommu); | ||
1151 | iommu_init_flags(iommu); | ||
1129 | iommu_set_device_table(iommu); | 1152 | iommu_set_device_table(iommu); |
1130 | iommu_enable_command_buffer(iommu); | 1153 | iommu_enable_command_buffer(iommu); |
1131 | iommu_enable_event_buffer(iommu); | 1154 | iommu_enable_event_buffer(iommu); |
diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index 3efdf2870a35..03a5b0385ad6 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c | |||
@@ -102,6 +102,7 @@ struct cpu_hw_events { | |||
102 | */ | 102 | */ |
103 | struct perf_event *events[X86_PMC_IDX_MAX]; /* in counter order */ | 103 | struct perf_event *events[X86_PMC_IDX_MAX]; /* in counter order */ |
104 | unsigned long active_mask[BITS_TO_LONGS(X86_PMC_IDX_MAX)]; | 104 | unsigned long active_mask[BITS_TO_LONGS(X86_PMC_IDX_MAX)]; |
105 | unsigned long running[BITS_TO_LONGS(X86_PMC_IDX_MAX)]; | ||
105 | int enabled; | 106 | int enabled; |
106 | 107 | ||
107 | int n_events; | 108 | int n_events; |
@@ -1010,6 +1011,7 @@ static int x86_pmu_start(struct perf_event *event) | |||
1010 | x86_perf_event_set_period(event); | 1011 | x86_perf_event_set_period(event); |
1011 | cpuc->events[idx] = event; | 1012 | cpuc->events[idx] = event; |
1012 | __set_bit(idx, cpuc->active_mask); | 1013 | __set_bit(idx, cpuc->active_mask); |
1014 | __set_bit(idx, cpuc->running); | ||
1013 | x86_pmu.enable(event); | 1015 | x86_pmu.enable(event); |
1014 | perf_event_update_userpage(event); | 1016 | perf_event_update_userpage(event); |
1015 | 1017 | ||
@@ -1141,8 +1143,16 @@ static int x86_pmu_handle_irq(struct pt_regs *regs) | |||
1141 | cpuc = &__get_cpu_var(cpu_hw_events); | 1143 | cpuc = &__get_cpu_var(cpu_hw_events); |
1142 | 1144 | ||
1143 | for (idx = 0; idx < x86_pmu.num_counters; idx++) { | 1145 | for (idx = 0; idx < x86_pmu.num_counters; idx++) { |
1144 | if (!test_bit(idx, cpuc->active_mask)) | 1146 | if (!test_bit(idx, cpuc->active_mask)) { |
1147 | /* | ||
1148 | * Though we deactivated the counter some cpus | ||
1149 | * might still deliver spurious interrupts still | ||
1150 | * in flight. Catch them: | ||
1151 | */ | ||
1152 | if (__test_and_clear_bit(idx, cpuc->running)) | ||
1153 | handled++; | ||
1145 | continue; | 1154 | continue; |
1155 | } | ||
1146 | 1156 | ||
1147 | event = cpuc->events[idx]; | 1157 | event = cpuc->events[idx]; |
1148 | hwc = &event->hw; | 1158 | hwc = &event->hw; |
diff --git a/arch/x86/kernel/cpu/scattered.c b/arch/x86/kernel/cpu/scattered.c index 34b4dad6f0b8..d49079515122 100644 --- a/arch/x86/kernel/cpu/scattered.c +++ b/arch/x86/kernel/cpu/scattered.c | |||
@@ -31,6 +31,7 @@ void __cpuinit init_scattered_cpuid_features(struct cpuinfo_x86 *c) | |||
31 | const struct cpuid_bit *cb; | 31 | const struct cpuid_bit *cb; |
32 | 32 | ||
33 | static const struct cpuid_bit __cpuinitconst cpuid_bits[] = { | 33 | static const struct cpuid_bit __cpuinitconst cpuid_bits[] = { |
34 | { X86_FEATURE_DTS, CR_EAX, 0, 0x00000006, 0 }, | ||
34 | { X86_FEATURE_IDA, CR_EAX, 1, 0x00000006, 0 }, | 35 | { X86_FEATURE_IDA, CR_EAX, 1, 0x00000006, 0 }, |
35 | { X86_FEATURE_ARAT, CR_EAX, 2, 0x00000006, 0 }, | 36 | { X86_FEATURE_ARAT, CR_EAX, 2, 0x00000006, 0 }, |
36 | { X86_FEATURE_PLN, CR_EAX, 4, 0x00000006, 0 }, | 37 | { X86_FEATURE_PLN, CR_EAX, 4, 0x00000006, 0 }, |
diff --git a/arch/x86/kernel/hw_breakpoint.c b/arch/x86/kernel/hw_breakpoint.c index a474ec37c32f..ff15c9dcc25d 100644 --- a/arch/x86/kernel/hw_breakpoint.c +++ b/arch/x86/kernel/hw_breakpoint.c | |||
@@ -206,11 +206,27 @@ int arch_check_bp_in_kernelspace(struct perf_event *bp) | |||
206 | int arch_bp_generic_fields(int x86_len, int x86_type, | 206 | int arch_bp_generic_fields(int x86_len, int x86_type, |
207 | int *gen_len, int *gen_type) | 207 | int *gen_len, int *gen_type) |
208 | { | 208 | { |
209 | /* Len */ | 209 | /* Type */ |
210 | switch (x86_len) { | 210 | switch (x86_type) { |
211 | case X86_BREAKPOINT_LEN_X: | 211 | case X86_BREAKPOINT_EXECUTE: |
212 | if (x86_len != X86_BREAKPOINT_LEN_X) | ||
213 | return -EINVAL; | ||
214 | |||
215 | *gen_type = HW_BREAKPOINT_X; | ||
212 | *gen_len = sizeof(long); | 216 | *gen_len = sizeof(long); |
217 | return 0; | ||
218 | case X86_BREAKPOINT_WRITE: | ||
219 | *gen_type = HW_BREAKPOINT_W; | ||
213 | break; | 220 | break; |
221 | case X86_BREAKPOINT_RW: | ||
222 | *gen_type = HW_BREAKPOINT_W | HW_BREAKPOINT_R; | ||
223 | break; | ||
224 | default: | ||
225 | return -EINVAL; | ||
226 | } | ||
227 | |||
228 | /* Len */ | ||
229 | switch (x86_len) { | ||
214 | case X86_BREAKPOINT_LEN_1: | 230 | case X86_BREAKPOINT_LEN_1: |
215 | *gen_len = HW_BREAKPOINT_LEN_1; | 231 | *gen_len = HW_BREAKPOINT_LEN_1; |
216 | break; | 232 | break; |
@@ -229,21 +245,6 @@ int arch_bp_generic_fields(int x86_len, int x86_type, | |||
229 | return -EINVAL; | 245 | return -EINVAL; |
230 | } | 246 | } |
231 | 247 | ||
232 | /* Type */ | ||
233 | switch (x86_type) { | ||
234 | case X86_BREAKPOINT_EXECUTE: | ||
235 | *gen_type = HW_BREAKPOINT_X; | ||
236 | break; | ||
237 | case X86_BREAKPOINT_WRITE: | ||
238 | *gen_type = HW_BREAKPOINT_W; | ||
239 | break; | ||
240 | case X86_BREAKPOINT_RW: | ||
241 | *gen_type = HW_BREAKPOINT_W | HW_BREAKPOINT_R; | ||
242 | break; | ||
243 | default: | ||
244 | return -EINVAL; | ||
245 | } | ||
246 | |||
247 | return 0; | 248 | return 0; |
248 | } | 249 | } |
249 | 250 | ||
@@ -316,9 +317,6 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp) | |||
316 | ret = -EINVAL; | 317 | ret = -EINVAL; |
317 | 318 | ||
318 | switch (info->len) { | 319 | switch (info->len) { |
319 | case X86_BREAKPOINT_LEN_X: | ||
320 | align = sizeof(long) -1; | ||
321 | break; | ||
322 | case X86_BREAKPOINT_LEN_1: | 320 | case X86_BREAKPOINT_LEN_1: |
323 | align = 0; | 321 | align = 0; |
324 | break; | 322 | break; |
diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c index 9257510b4836..9d5f55848455 100644 --- a/arch/x86/lguest/boot.c +++ b/arch/x86/lguest/boot.c | |||
@@ -324,9 +324,8 @@ static void lguest_load_gdt(const struct desc_ptr *desc) | |||
324 | } | 324 | } |
325 | 325 | ||
326 | /* | 326 | /* |
327 | * For a single GDT entry which changes, we do the lazy thing: alter our GDT, | 327 | * For a single GDT entry which changes, we simply change our copy and |
328 | * then tell the Host to reload the entire thing. This operation is so rare | 328 | * then tell the host about it. |
329 | * that this naive implementation is reasonable. | ||
330 | */ | 329 | */ |
331 | static void lguest_write_gdt_entry(struct desc_struct *dt, int entrynum, | 330 | static void lguest_write_gdt_entry(struct desc_struct *dt, int entrynum, |
332 | const void *desc, int type) | 331 | const void *desc, int type) |
@@ -338,9 +337,13 @@ static void lguest_write_gdt_entry(struct desc_struct *dt, int entrynum, | |||
338 | } | 337 | } |
339 | 338 | ||
340 | /* | 339 | /* |
341 | * OK, I lied. There are three "thread local storage" GDT entries which change | 340 | * There are three "thread local storage" GDT entries which change |
342 | * on every context switch (these three entries are how glibc implements | 341 | * on every context switch (these three entries are how glibc implements |
343 | * __thread variables). So we have a hypercall specifically for this case. | 342 | * __thread variables). As an optimization, we have a hypercall |
343 | * specifically for this case. | ||
344 | * | ||
345 | * Wouldn't it be nicer to have a general LOAD_GDT_ENTRIES hypercall | ||
346 | * which took a range of entries? | ||
344 | */ | 347 | */ |
345 | static void lguest_load_tls(struct thread_struct *t, unsigned int cpu) | 348 | static void lguest_load_tls(struct thread_struct *t, unsigned int cpu) |
346 | { | 349 | { |
diff --git a/arch/x86/oprofile/nmi_int.c b/arch/x86/oprofile/nmi_int.c index cfe4faabb0f6..009b819f48d0 100644 --- a/arch/x86/oprofile/nmi_int.c +++ b/arch/x86/oprofile/nmi_int.c | |||
@@ -671,7 +671,9 @@ static int __init ppro_init(char **cpu_type) | |||
671 | case 14: | 671 | case 14: |
672 | *cpu_type = "i386/core"; | 672 | *cpu_type = "i386/core"; |
673 | break; | 673 | break; |
674 | case 15: case 23: | 674 | case 0x0f: |
675 | case 0x16: | ||
676 | case 0x17: | ||
675 | *cpu_type = "i386/core_2"; | 677 | *cpu_type = "i386/core_2"; |
676 | break; | 678 | break; |
677 | case 0x1a: | 679 | case 0x1a: |