diff options
Diffstat (limited to 'arch/cris/arch-v32/kernel')
| -rw-r--r-- | arch/cris/arch-v32/kernel/Makefile | 2 | ||||
| -rw-r--r-- | arch/cris/arch-v32/kernel/cacheflush.S | 5 | ||||
| -rw-r--r-- | arch/cris/arch-v32/kernel/crisksyms.c | 4 | ||||
| -rw-r--r-- | arch/cris/arch-v32/kernel/debugport.c | 1 | ||||
| -rw-r--r-- | arch/cris/arch-v32/kernel/entry.S | 147 | ||||
| -rw-r--r-- | arch/cris/arch-v32/kernel/fasttimer.c | 302 | ||||
| -rw-r--r-- | arch/cris/arch-v32/kernel/head.S | 61 | ||||
| -rw-r--r-- | arch/cris/arch-v32/kernel/irq.c | 129 | ||||
| -rw-r--r-- | arch/cris/arch-v32/kernel/kgdb.c | 38 | ||||
| -rw-r--r-- | arch/cris/arch-v32/kernel/kgdb_asm.S | 2 | ||||
| -rw-r--r-- | arch/cris/arch-v32/kernel/pinmux.c | 229 | ||||
| -rw-r--r-- | arch/cris/arch-v32/kernel/process.c | 137 | ||||
| -rw-r--r-- | arch/cris/arch-v32/kernel/ptrace.c | 128 | ||||
| -rw-r--r-- | arch/cris/arch-v32/kernel/setup.c | 74 | ||||
| -rw-r--r-- | arch/cris/arch-v32/kernel/signal.c | 153 | ||||
| -rw-r--r-- | arch/cris/arch-v32/kernel/smp.c | 91 | ||||
| -rw-r--r-- | arch/cris/arch-v32/kernel/time.c | 136 | ||||
| -rw-r--r-- | arch/cris/arch-v32/kernel/traps.c | 6 |
18 files changed, 557 insertions, 1088 deletions
diff --git a/arch/cris/arch-v32/kernel/Makefile b/arch/cris/arch-v32/kernel/Makefile index 993d987b007..40358355d0c 100644 --- a/arch/cris/arch-v32/kernel/Makefile +++ b/arch/cris/arch-v32/kernel/Makefile @@ -9,8 +9,6 @@ obj-y := entry.o traps.o irq.o debugport.o \ process.o ptrace.o setup.o signal.o traps.o time.o \ cache.o cacheflush.o -obj-$(CONFIG_ETRAXFS_SIM) += vcs_hook.o - obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_ETRAX_KGDB) += kgdb.o kgdb_asm.o obj-$(CONFIG_ETRAX_FAST_TIMER) += fasttimer.o diff --git a/arch/cris/arch-v32/kernel/cacheflush.S b/arch/cris/arch-v32/kernel/cacheflush.S index 956e8fb82f0..6fc3d95d702 100644 --- a/arch/cris/arch-v32/kernel/cacheflush.S +++ b/arch/cris/arch-v32/kernel/cacheflush.S @@ -1,4 +1,5 @@ .global cris_flush_cache_range + .type cris_flush_cache_range, @function cris_flush_cache_range: move.d 1024, $r12 cmp.d $r11, $r12 @@ -80,8 +81,10 @@ cris_flush_1KB: addq 32, $r10 ba cris_flush_cache_range sub.d $r12, $r11 + .size cris_flush_cache_range, . - cris_flush_cache_range .global cris_flush_cache + .type cris_flush_cache, @function cris_flush_cache: moveq 0, $r10 cris_flush_line: @@ -92,3 +95,5 @@ cris_flush_line: fidxd [$r10] ret nop + .size cris_flush_cache, . - cris_flush_cache + diff --git a/arch/cris/arch-v32/kernel/crisksyms.c b/arch/cris/arch-v32/kernel/crisksyms.c index 64933e2c0f5..bde8d1a10ca 100644 --- a/arch/cris/arch-v32/kernel/crisksyms.c +++ b/arch/cris/arch-v32/kernel/crisksyms.c @@ -24,5 +24,5 @@ EXPORT_SYMBOL(crisv32_io_get_name); EXPORT_SYMBOL(crisv32_io_get); /* Functions masking/unmasking interrupts */ -EXPORT_SYMBOL(mask_irq); -EXPORT_SYMBOL(unmask_irq); +EXPORT_SYMBOL(crisv32_mask_irq); +EXPORT_SYMBOL(crisv32_unmask_irq); diff --git a/arch/cris/arch-v32/kernel/debugport.c b/arch/cris/arch-v32/kernel/debugport.c index 794b364d9f7..610909b003f 100644 --- a/arch/cris/arch-v32/kernel/debugport.c +++ b/arch/cris/arch-v32/kernel/debugport.c @@ -4,7 +4,6 @@ #include <linux/console.h> #include <linux/init.h> -#include <asm/system.h> #include <hwregs/reg_rdwr.h> #include <hwregs/reg_map.h> #include <hwregs/ser_defs.h> diff --git a/arch/cris/arch-v32/kernel/entry.S b/arch/cris/arch-v32/kernel/entry.S index 5e674c8f7c5..2f19ac6217a 100644 --- a/arch/cris/arch-v32/kernel/entry.S +++ b/arch/cris/arch-v32/kernel/entry.S @@ -31,6 +31,7 @@ .globl system_call .globl ret_from_intr .globl ret_from_fork + .globl ret_from_kernel_thread .globl resume .globl multiple_interrupt .globl nmi_interrupt @@ -76,12 +77,27 @@ _need_resched: ; Called at exit from fork. schedule_tail must be called to drop ; spinlock if CONFIG_PREEMPT. + .type ret_from_fork,@function ret_from_fork: jsr schedule_tail nop ba ret_from_sys_call nop + .size ret_from_fork, . - ret_from_fork + .type ret_from_kernel_thread,@function +ret_from_kernel_thread: + jsr schedule_tail + nop + move.d $r2, $r10 + jsr $r1 + nop + moveq 0, $r9 ; no syscall restarts, TYVM... + ba ret_from_sys_call + nop + .size ret_from_kernel_thread, . - ret_from_kernel_thread + + .type ret_from_intr,@function ret_from_intr: ;; Check for resched if preemptive kernel, or if we're going back to ;; user-mode. This test matches the user_regs(regs) macro. Don't simply @@ -91,9 +107,10 @@ ret_from_intr: move.d [$acr], $r0 btstq 16, $r0 ; User-mode flag. bpl _resume_kernel + .size ret_from_intr, . - ret_from_intr + 2 ; +2 includes the dslot. ; Note that di below is in delay slot. - + .type _resume_userspace,@function _resume_userspace: di ; So need_resched and sigpending don't change. @@ -107,6 +124,7 @@ _resume_userspace: nop ba _Rexit nop + .size _resume_userspace, . - _resume_userspace ;; The system_call is called by a BREAK instruction, which looks pretty ;; much like any other exception. @@ -122,30 +140,28 @@ _resume_userspace: ;; non-used instructions. Only the non-common cases cause the outlined code ;; to run.. + .type system_call,@function system_call: ;; Stack-frame similar to the irq heads, which is reversed in ;; ret_from_sys_call. - subq 12, $sp ; Skip EXS, EDA. - move $erp, [$sp] - subq 4, $sp - move $srp, [$sp] - subq 4, $sp - move $ccs, [$sp] - subq 4, $sp - ei ; Allow IRQs while handling system call - move $spc, [$sp] - subq 4, $sp - move $mof, [$sp] - subq 4, $sp - move $srs, [$sp] - subq 4, $sp - move.d $acr, [$sp] - subq 14*4, $sp ; Make room for R0-R13. - movem $r13, [$sp] ; Push R0-R13 - subq 4, $sp - move.d $r10, [$sp] ; Push orig_r10. -; Set S-bit when kernel debugging to keep hardware breakpoints active. + sub.d 92, $sp ; Skip EXS and EDA. + movem $r13, [$sp] + move.d $sp, $r8 + addq 14*4, $r8 + move.d $acr, $r0 + move $srs, $r1 + move $mof, $r2 + move $spc, $r3 + move $ccs, $r4 + move $srp, $r5 + move $erp, $r6 + subq 4, $sp + movem $r6, [$r8] + ei ; Enable interrupts while processing syscalls. + move.d $r10, [$sp] + + ; Set S-bit when kernel debugging to keep hardware breakpoints active. #ifdef CONFIG_ETRAX_KGDB move $ccs, $r0 or.d (1<<9), $r0 @@ -179,7 +195,7 @@ _syscall_traced: move.d $r0, [$sp] ;; The registers carrying parameters (R10-R13) are intact. The optional - ;; fifth and sixth parameters is in MOF and SRP respectivly. Put them + ;; fifth and sixth parameters is in MOF and SRP respectively. Put them ;; back on the stack. subq 4, $sp move $srp, [$sp] @@ -217,7 +233,9 @@ ret_from_sys_call: and.d _TIF_ALLWORK_MASK, $r1 bne _syscall_exit_work nop + .size system_call, . - system_call + .type _Rexit,@function _Rexit: ;; This epilogue MUST match the prologues in multiple_interrupt, irq.h ;; and ptregs.h. @@ -234,10 +252,12 @@ _Rexit: addq 8, $sp ; Skip EXS, EDA. jump $erp rfe ; Restore condition code stack in delay-slot. + .size _Rexit, . - _Rexit ;; We get here after doing a syscall if extra work might need to be done ;; perform syscall exit tracing if needed. + .type _syscall_exit_work,@function _syscall_exit_work: ;; R0 contains current at this point and irq's are disabled. @@ -253,14 +273,18 @@ _syscall_exit_work: move.d $r1, $r9 ba _resume_userspace nop + .size _syscall_exit_work, . - _syscall_exit_work + .type _work_pending,@function _work_pending: addoq +TI_flags, $r0, $acr move.d [$acr], $r10 btstq TIF_NEED_RESCHED, $r10 ; Need resched? bpl _work_notifysig ; No, must be signal/notify. nop + .size _work_pending, . - _work_pending + .type _work_resched,@function _work_resched: move.d $r9, $r1 ; Preserve R9. jsr schedule @@ -276,7 +300,9 @@ _work_resched: btstq TIF_NEED_RESCHED, $r1 bmi _work_resched ; current->work.need_resched. nop + .size _work_resched, . - _work_resched + .type _work_notifysig,@function _work_notifysig: ;; Deal with pending signals and notify-resume requests. @@ -288,6 +314,7 @@ _work_notifysig: ba _Rexit nop + .size _work_notifysig, . - _work_notifysig ;; We get here as a sidetrack when we've entered a syscall with the ;; trace-bit set. We need to call do_syscall_trace and then continue @@ -329,41 +356,43 @@ _syscall_trace_entry: ;; ;; Returns old current in R10. + .type resume,@function resume: - subq 4, $sp - move $srp, [$sp] ; Keep old/new PC on the stack. + subq 4, $sp ; Make space for srp. + add.d $r12, $r10 ; R10 = current tasks tss. addoq +THREAD_ccs, $r10, $acr + move $srp, [$sp] ; Keep old/new PC on the stack. move $ccs, [$acr] ; Save IRQ enable state. di addoq +THREAD_usp, $r10, $acr + subq 10*4, $sp ; Make room for R9. move $usp, [$acr] ; Save user-mode stackpointer. ;; See copy_thread for the reason why register R9 is saved. - subq 10*4, $sp movem $r9, [$sp] ; Save non-scratch registers and R9. addoq +THREAD_ksp, $r10, $acr + move.d $sp, $r10 ; Return last running task in R10. move.d $sp, [$acr] ; Save kernel SP for old task. - move.d $sp, $r10 ; Return last running task in R10. and.d -8192, $r10 ; Get thread_info from stackpointer. addoq +TI_task, $r10, $acr - move.d [$acr], $r10 ; Get task. add.d $r12, $r11 ; Find the new tasks tss. + move.d [$acr], $r10 ; Get task. addoq +THREAD_ksp, $r11, $acr move.d [$acr], $sp ; Switch to new stackframe. + addoq +THREAD_usp, $r11, $acr movem [$sp+], $r9 ; Restore non-scratch registers and R9. - addoq +THREAD_usp, $r11, $acr move [$acr], $usp ; Restore user-mode stackpointer. addoq +THREAD_ccs, $r11, $acr + move.d [$sp+], $r11 + jump $r11 ; Restore PC. move [$acr], $ccs ; Restore IRQ enable status. - move.d [$sp+], $acr - jump $acr ; Restore PC. - nop + .size resume, . - resume nmi_interrupt: @@ -395,7 +424,7 @@ nmi_interrupt: bpl 1f nop jsr handle_watchdog_bite ; In time.c. - move.d $sp, $r10 ; Pointer to registers + move.d $sp, $r10 ; Pointer to registers 1: btstq REG_BIT(intr_vect, r_nmi, ext), $r0 bpl 1f nop @@ -423,9 +452,10 @@ spurious_interrupt: nop ;; This handles the case when multiple interrupts arrive at the same - ;; time. Jump to the first set interrupt bit in a priotiry fashion. The + ;; time. Jump to the first set interrupt bit in a priority fashion. The ;; hardware will call the unserved interrupts after the handler ;; finishes. + .type multiple_interrupt, @function multiple_interrupt: ;; This prologue MUST match the one in irq.h and the struct in ptregs.h! subq 12, $sp ; Skip EXS, EDA. @@ -458,6 +488,7 @@ multiple_interrupt: move.d $sp, $r10 jump ret_from_intr nop + .size multiple_interrupt, . - multiple_interrupt do_sigtrap: ;; Sigtraps the process that executed the BREAK instruction. Creates a @@ -513,13 +544,6 @@ _ugdb_handle_exception: ba do_sigtrap ; SIGTRAP the offending process. move.d [$sp+], $r0 ; Restore R0 in delay slot. - .global kernel_execve -kernel_execve: - move.d __NR_execve, $r9 - break 13 - ret - nop - .data .section .rodata,"a" @@ -615,7 +639,7 @@ sys_call_table: .long sys_swapon .long sys_reboot .long sys_old_readdir - .long old_mmap /* 90 */ + .long sys_old_mmap /* 90 */ .long sys_munmap .long sys_truncate .long sys_ftruncate @@ -694,7 +718,7 @@ sys_call_table: .long sys_ni_syscall /* sys_vm86 */ .long sys_ni_syscall /* Old sys_query_module */ .long sys_poll - .long sys_nfsservctl + .long sys_ni_syscall /* Old nfsservctl */ .long sys_setresgid16 /* 170 */ .long sys_getresgid16 .long sys_prctl @@ -852,13 +876,38 @@ sys_call_table: .long sys_fallocate .long sys_timerfd_settime /* 325 */ .long sys_timerfd_gettime - - /* - * NOTE!! This doesn't have to be exact - we just have - * to make sure we have _enough_ of the "sys_ni_syscall" - * entries. Don't panic if you notice that this hasn't - * been shrunk every time we add a new system call. - */ + .long sys_signalfd4 + .long sys_eventfd2 + .long sys_epoll_create1 + .long sys_dup3 /* 330 */ + .long sys_pipe2 + .long sys_inotify_init1 + .long sys_preadv + .long sys_pwritev + .long sys_setns /* 335 */ + .long sys_name_to_handle_at + .long sys_open_by_handle_at + .long sys_rt_tgsigqueueinfo + .long sys_perf_event_open + .long sys_recvmmsg /* 340 */ + .long sys_accept4 + .long sys_fanotify_init + .long sys_fanotify_mark + .long sys_prlimit64 + .long sys_clock_adjtime /* 345 */ + .long sys_syncfs + .long sys_sendmmsg + .long sys_process_vm_readv + .long sys_process_vm_writev + .long sys_kcmp /* 350 */ + .long sys_finit_module + + /* + * NOTE!! This doesn't have to be exact - we just have + * to make sure we have _enough_ of the "sys_ni_syscall" + * entries. Don't panic if you notice that this hasn't + * been shrunk every time we add a new system call. + */ .rept NR_syscalls - (.-sys_call_table) / 4 .long sys_ni_syscall diff --git a/arch/cris/arch-v32/kernel/fasttimer.c b/arch/cris/arch-v32/kernel/fasttimer.c index 111caa1a2ef..b130c2c5fdd 100644 --- a/arch/cris/arch-v32/kernel/fasttimer.c +++ b/arch/cris/arch-v32/kernel/fasttimer.c @@ -17,13 +17,13 @@ #include <linux/delay.h> #include <asm/irq.h> -#include <asm/system.h> #include <hwregs/reg_map.h> #include <hwregs/reg_rdwr.h> #include <hwregs/timer_defs.h> #include <asm/fasttimer.h> #include <linux/proc_fs.h> +#include <linux/seq_file.h> /* * timer0 is running at 100MHz and generating jiffies timer ticks @@ -464,195 +464,161 @@ void schedule_usleep(unsigned long us) } #ifdef CONFIG_PROC_FS -static int proc_fasttimer_read(char *buf, char **start, off_t offset, int len - ,int *eof, void *data_unused); -static struct proc_dir_entry *fasttimer_proc_entry; -#endif /* CONFIG_PROC_FS */ - -#ifdef CONFIG_PROC_FS - /* This value is very much based on testing */ #define BIG_BUF_SIZE (500 + NUM_TIMER_STATS * 300) -static int proc_fasttimer_read(char *buf, char **start, off_t offset, int len - ,int *eof, void *data_unused) +static int proc_fasttimer_show(struct seq_file *m, void *v) { - unsigned long flags; - int i = 0; - int num_to_show; + unsigned long flags; + int i = 0; + int num_to_show; struct fasttime_t tv; - struct fast_timer *t, *nextt; - static char *bigbuf = NULL; - static unsigned long used; - - if (!bigbuf) { - bigbuf = vmalloc(BIG_BUF_SIZE); - if (!bigbuf) { - used = 0; - if (buf) - buf[0] = '\0'; - return 0; - } - } - - if (!offset || !used) { - do_gettimeofday_fast(&tv); - - used = 0; - used += sprintf(bigbuf + used, "Fast timers added: %i\n", - fast_timers_added); - used += sprintf(bigbuf + used, "Fast timers started: %i\n", - fast_timers_started); - used += sprintf(bigbuf + used, "Fast timer interrupts: %i\n", - fast_timer_ints); - used += sprintf(bigbuf + used, "Fast timers expired: %i\n", - fast_timers_expired); - used += sprintf(bigbuf + used, "Fast timers deleted: %i\n", - fast_timers_deleted); - used += sprintf(bigbuf + used, "Fast timer running: %s\n", - fast_timer_running ? "yes" : "no"); - used += sprintf(bigbuf + used, "Current time: %lu.%06lu\n", - (unsigned long)tv.tv_jiff, - (unsigned long)tv.tv_usec); + struct fast_timer *t, *nextt; + + do_gettimeofday_fast(&tv); + + seq_printf(m, "Fast timers added: %i\n", fast_timers_added); + seq_printf(m, "Fast timers started: %i\n", fast_timers_started); + seq_printf(m, "Fast timer interrupts: %i\n", fast_timer_ints); + seq_printf(m, "Fast timers expired: %i\n", fast_timers_expired); + seq_printf(m, "Fast timers deleted: %i\n", fast_timers_deleted); + seq_printf(m, "Fast timer running: %s\n", + fast_timer_running ? "yes" : "no"); + seq_printf(m, "Current time: %lu.%06lu\n", + (unsigned long)tv.tv_jiff, + (unsigned long)tv.tv_usec); #ifdef FAST_TIMER_SANITY_CHECKS - used += sprintf(bigbuf + used, "Sanity failed: %i\n", - sanity_failed); + seq_printf(m, "Sanity failed: %i\n", sanity_failed); #endif - used += sprintf(bigbuf + used, "\n"); + seq_putc(m, '\n'); #ifdef DEBUG_LOG_INCLUDED - { - int end_i = debug_log_cnt; - i = 0; - - if (debug_log_cnt_wrapped) - i = debug_log_cnt; - - while ((i != end_i || (debug_log_cnt_wrapped && !used)) && - used+100 < BIG_BUF_SIZE) - { - used += sprintf(bigbuf + used, debug_log_string[i], - debug_log_value[i]); - i = (i+1) % DEBUG_LOG_MAX; - } - } - used += sprintf(bigbuf + used, "\n"); + { + int end_i = debug_log_cnt; + i = 0; + + if (debug_log_cnt_wrapped) + i = debug_log_cnt; + + while ((i != end_i || debug_log_cnt_wrapped)) { + if (seq_printf(m, debug_log_string[i], debug_log_value[i]) < 0) + return 0; + i = (i+1) % DEBUG_LOG_MAX; + } + } + seq_putc(m, '\n'); #endif - num_to_show = (fast_timers_started < NUM_TIMER_STATS ? fast_timers_started: - NUM_TIMER_STATS); - used += sprintf(bigbuf + used, "Timers started: %i\n", fast_timers_started); - for (i = 0; i < num_to_show && (used+100 < BIG_BUF_SIZE) ; i++) - { - int cur = (fast_timers_started - i - 1) % NUM_TIMER_STATS; + num_to_show = (fast_timers_started < NUM_TIMER_STATS ? fast_timers_started: + NUM_TIMER_STATS); + seq_printf(m, "Timers started: %i\n", fast_timers_started); + for (i = 0; i < num_to_show; i++) { + int cur = (fast_timers_started - i - 1) % NUM_TIMER_STATS; #if 1 //ndef FAST_TIMER_LOG - used += sprintf(bigbuf + used, "div: %i delay: %i" - "\n", - timer_div_settings[cur], - timer_delay_settings[cur] - ); + seq_printf(m, "div: %i delay: %i" + "\n", + timer_div_settings[cur], + timer_delay_settings[cur]); #endif #ifdef FAST_TIMER_LOG - t = &timer_started_log[cur]; - used += sprintf(bigbuf + used, "%-14s s: %6lu.%06lu e: %6lu.%06lu " - "d: %6li us data: 0x%08lX" - "\n", - t->name, - (unsigned long)t->tv_set.tv_jiff, - (unsigned long)t->tv_set.tv_usec, - (unsigned long)t->tv_expires.tv_jiff, - (unsigned long)t->tv_expires.tv_usec, - t->delay_us, - t->data - ); + t = &timer_started_log[cur]; + if (seq_printf(m, "%-14s s: %6lu.%06lu e: %6lu.%06lu " + "d: %6li us data: 0x%08lX" + "\n", + t->name, + (unsigned long)t->tv_set.tv_jiff, + (unsigned long)t->tv_set.tv_usec, + (unsigned long)t->tv_expires.tv_jiff, + (unsigned long)t->tv_expires.tv_usec, + t->delay_us, + t->data) < 0) + return 0; #endif - } - used += sprintf(bigbuf + used, "\n"); + } + seq_putc(m, '\n'); #ifdef FAST_TIMER_LOG - num_to_show = (fast_timers_added < NUM_TIMER_STATS ? fast_timers_added: - NUM_TIMER_STATS); - used += sprintf(bigbuf + used, "Timers added: %i\n", fast_timers_added); - for (i = 0; i < num_to_show && (used+100 < BIG_BUF_SIZE); i++) - { - t = &timer_added_log[(fast_timers_added - i - 1) % NUM_TIMER_STATS]; - used += sprintf(bigbuf + used, "%-14s s: %6lu.%06lu e: %6lu.%06lu " - "d: %6li us data: 0x%08lX" - "\n", - t->name, - (unsigned long)t->tv_set.tv_jiff, - (unsigned long)t->tv_set.tv_usec, - (unsigned long)t->tv_expires.tv_jiff, - (unsigned long)t->tv_expires.tv_usec, - t->delay_us, - t->data - ); - } - used += sprintf(bigbuf + used, "\n"); - - num_to_show = (fast_timers_expired < NUM_TIMER_STATS ? fast_timers_expired: - NUM_TIMER_STATS); - used += sprintf(bigbuf + used, "Timers expired: %i\n", fast_timers_expired); - for (i = 0; i < num_to_show && (used+100 < BIG_BUF_SIZE); i++) - { - t = &timer_expired_log[(fast_timers_expired - i - 1) % NUM_TIMER_STATS]; - used += sprintf(bigbuf + used, "%-14s s: %6lu.%06lu e: %6lu.%06lu " - "d: %6li us data: 0x%08lX" - "\n", - t->name, - (unsigned long)t->tv_set.tv_jiff, - (unsigned long)t->tv_set.tv_usec, - (unsigned long)t->tv_expires.tv_jiff, - (unsigned long)t->tv_expires.tv_usec, - t->delay_us, - t->data - ); - } - used += sprintf(bigbuf + used, "\n"); + num_to_show = (fast_timers_added < NUM_TIMER_STATS ? fast_timers_added: + NUM_TIMER_STATS); + seq_printf(m, "Timers added: %i\n", fast_timers_added); + for (i = 0; i < num_to_show; i++) { + t = &timer_added_log[(fast_timers_added - i - 1) % NUM_TIMER_STATS]; + if (seq_printf(m, "%-14s s: %6lu.%06lu e: %6lu.%06lu " + "d: %6li us data: 0x%08lX" + "\n", + t->name, + (unsigned long)t->tv_set.tv_jiff, + (unsigned long)t->tv_set.tv_usec, + (unsigned long)t->tv_expires.tv_jiff, + (unsigned long)t->tv_expires.tv_usec, + t->delay_us, + t->data) < 0) + return 0; + } + seq_putc(m, '\n'); + + num_to_show = (fast_timers_expired < NUM_TIMER_STATS ? fast_timers_expired: + NUM_TIMER_STATS); + seq_printf(m, "Timers expired: %i\n", fast_timers_expired); + for (i = 0; i < num_to_show; i++){ + t = &timer_expired_log[(fast_timers_expired - i - 1) % NUM_TIMER_STATS]; + if (seq_printf(m, "%-14s s: %6lu.%06lu e: %6lu.%06lu " + "d: %6li us data: 0x%08lX" + "\n", + t->name, + (unsigned long)t->tv_set.tv_jiff, + (unsigned long)t->tv_set.tv_usec, + (unsigned long)t->tv_expires.tv_jiff, + (unsigned long)t->tv_expires.tv_usec, + t->delay_us, + t->data) < 0) + return 0; + } + seq_putc(m, '\n'); #endif - used += sprintf(bigbuf + used, "Active timers:\n"); - local_irq_save(flags); - t = fast_timer_list; - while (t != NULL && (used+100 < BIG_BUF_SIZE)) - { - nextt = t->next; - local_irq_restore(flags); - used += sprintf(bigbuf + used, "%-14s s: %6lu.%06lu e: %6lu.%06lu " - "d: %6li us data: 0x%08lX" + seq_puts(m, "Active timers:\n"); + local_irq_save(flags); + t = fast_timer_list; + while (t != NULL){ + nextt = t->next; + local_irq_restore(flags); + if (seq_printf(m, "%-14s s: %6lu.%06lu e: %6lu.%06lu " + "d: %6li us data: 0x%08lX" /* " func: 0x%08lX" */ - "\n", - t->name, - (unsigned long)t->tv_set.tv_jiff, - (unsigned long)t->tv_set.tv_usec, - (unsigned long)t->tv_expires.tv_jiff, - (unsigned long)t->tv_expires.tv_usec, - t->delay_us, - t->data + "\n", + t->name, + (unsigned long)t->tv_set.tv_jiff, + (unsigned long)t->tv_set.tv_usec, + (unsigned long)t->tv_expires.tv_jiff, + (unsigned long)t->tv_expires.tv_usec, + t->delay_us, + t->data /* , t->function */ - ); - local_irq_save(flags); - if (t->next != nextt) - { - printk("timer removed!\n"); - } - t = nextt; - } - local_irq_restore(flags); - } + ) < 0) + return 0; + local_irq_save(flags); + if (t->next != nextt) + printk("timer removed!\n"); + t = nextt; + } + local_irq_restore(flags); + return 0; +} - if (used - offset < len) - { - len = used - offset; - } +static int proc_fasttimer_open(struct inode *inode, struct file *file) +{ + return single_open_size(file, proc_fasttimer_show, PDE_DATA(inode), BIG_BUF_SIZE); +} - memcpy(buf, bigbuf + offset, len); - *start = buf; - *eof = 1; +static const struct file_operations proc_fasttimer_fops = { + .open = proc_fasttimer_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; - return len; -} #endif /* PROC_FS */ #ifdef FAST_TIMER_TEST @@ -817,12 +783,10 @@ int fast_timer_init(void) printk("fast_timer_init()\n"); #ifdef CONFIG_PROC_FS - fasttimer_proc_entry = create_proc_entry("fasttimer", 0, 0); - if (fasttimer_proc_entry) - fasttimer_proc_entry->read_proc = proc_fasttimer_read; + proc_create("fasttimer", 0, NULL, &proc_fasttimer_fops); #endif /* PROC_FS */ if (request_irq(TIMER0_INTR_VECT, timer_trig_interrupt, - IRQF_SHARED | IRQF_DISABLED, + IRQF_SHARED, "fast timer int", &fast_timer_list)) printk(KERN_ERR "err: fasttimer irq\n"); fast_timer_is_init = 1; diff --git a/arch/cris/arch-v32/kernel/head.S b/arch/cris/arch-v32/kernel/head.S index 3db478eb515..51e34165ece 100644 --- a/arch/cris/arch-v32/kernel/head.S +++ b/arch/cris/arch-v32/kernel/head.S @@ -10,7 +10,6 @@ * The macros found in mmu_defs_asm.h uses the ## concatenation operator, so * -traditional must not be used when assembling this file. */ -#include <linux/autoconf.h> #include <arch/memmap.h> #include <hwregs/reg_rdwr.h> #include <hwregs/intr_vect.h> @@ -37,13 +36,6 @@ .global nand_boot .global swapper_pg_dir - ;; Dummy section to make it bootable with current VCS simulator -#ifdef CONFIG_ETRAX_VCS_SIM - .section ".boot", "ax" - ba tstart - nop -#endif - .text tstart: ;; This is the entry point of the kernel. The CPU is currently in @@ -70,17 +62,16 @@ secondary_cpu_entry: /* Entry point for secondary CPUs */ ;; ;; Note; 3 cycles is needed for a bank-select to take effect. Further; ;; bank 1 is the instruction MMU, bank 2 is the data MMU. -#ifndef CONFIG_ETRAX_VCS_SIM + +#ifdef CONFIG_CRIS_MACH_ARTPEC3 move.d REG_FIELD(mmu, rw_mm_kbase_hi, base_e, 8) \ | REG_FIELD(mmu, rw_mm_kbase_hi, base_c, 4) \ + | REG_FIELD(mmu, rw_mm_kbase_hi, base_d, 5) \ | REG_FIELD(mmu, rw_mm_kbase_hi, base_b, 0xb), $r0 #else - ;; Map the virtual DRAM to the RW eprom area at address 0. - ;; Also map 0xa for the hook calls, move.d REG_FIELD(mmu, rw_mm_kbase_hi, base_e, 8) \ | REG_FIELD(mmu, rw_mm_kbase_hi, base_c, 4) \ - | REG_FIELD(mmu, rw_mm_kbase_hi, base_b, 0xb) \ - | REG_FIELD(mmu, rw_mm_kbase_hi, base_a, 0xa), $r0 + | REG_FIELD(mmu, rw_mm_kbase_hi, base_b, 0xb), $r0 #endif ;; Temporary map of 0x40 -> 0x40 and 0x00 -> 0x00. @@ -89,14 +80,25 @@ secondary_cpu_entry: /* Entry point for secondary CPUs */ ;; Enable certain page protections and setup linear mapping ;; for f,e,c,b,4,0. -#ifndef CONFIG_ETRAX_VCS_SIM + + ;; ARTPEC-3: + ;; c,d used for linear kernel mapping, up to 512 MB + ;; e used for vmalloc + ;; f unused, but page mapped to get page faults + + ;; ETRAX FS: + ;; c used for linear kernel mapping, up to 256 MB + ;; d used for vmalloc + ;; e,f used for memory-mapped NOR flash + +#ifdef CONFIG_CRIS_MACH_ARTPEC3 move.d REG_STATE(mmu, rw_mm_cfg, we, on) \ | REG_STATE(mmu, rw_mm_cfg, acc, on) \ | REG_STATE(mmu, rw_mm_cfg, ex, on) \ - | REG_STATE(mmu, rw_mm_cfg, inv, on) \ - | REG_STATE(mmu, rw_mm_cfg, seg_f, linear) \ - | REG_STATE(mmu, rw_mm_cfg, seg_e, linear) \ - | REG_STATE(mmu, rw_mm_cfg, seg_d, page) \ + | REG_STATE(mmu, rw_mm_cfg, inv, on) \ + | REG_STATE(mmu, rw_mm_cfg, seg_f, page) \ + | REG_STATE(mmu, rw_mm_cfg, seg_e, page) \ + | REG_STATE(mmu, rw_mm_cfg, seg_d, linear) \ | REG_STATE(mmu, rw_mm_cfg, seg_c, linear) \ | REG_STATE(mmu, rw_mm_cfg, seg_b, linear) \ | REG_STATE(mmu, rw_mm_cfg, seg_a, page) \ @@ -120,7 +122,7 @@ secondary_cpu_entry: /* Entry point for secondary CPUs */ | REG_STATE(mmu, rw_mm_cfg, seg_d, page) \ | REG_STATE(mmu, rw_mm_cfg, seg_c, linear) \ | REG_STATE(mmu, rw_mm_cfg, seg_b, linear) \ - | REG_STATE(mmu, rw_mm_cfg, seg_a, linear) \ + | REG_STATE(mmu, rw_mm_cfg, seg_a, page) \ | REG_STATE(mmu, rw_mm_cfg, seg_9, page) \ | REG_STATE(mmu, rw_mm_cfg, seg_8, page) \ | REG_STATE(mmu, rw_mm_cfg, seg_7, page) \ @@ -189,7 +191,6 @@ master_cpu: move.d secondary_cpu_entry, $r1 move.d $r1, [$r0] #endif -#ifndef CONFIG_ETRAX_VCS_SIM ; Check if starting from DRAM (network->RAM boot or unpacked ; compressed kernel), or directly from flash. lapcq ., $r0 @@ -197,7 +198,6 @@ master_cpu: cmp.d 0x10000, $r0 ; Arbitrary, something above this code. blo _inflash0 nop -#endif jump _inram ; Jump to cached RAM. nop @@ -289,7 +289,6 @@ move_cramfs: move.d romfs_length, $r1 move.d $r0, [$r1] -#ifndef CONFIG_ETRAX_VCS_SIM ;; The kernel could have been unpacked to DRAM by the loader, but ;; the cramfs image could still be in the flash immediately ;; following the compressed kernel image. The loader passes the address @@ -298,10 +297,6 @@ move_cramfs: cmp.d 0x0ffffff8, $r9 bhs _no_romfs_in_flash ; R9 points outside the flash area. nop -#else - ba _no_romfs_in_flash - nop -#endif ;; cramfs rootfs might to be in flash. Check for it. move.d [$r9], $r0 ; cramfs_super.magic cmp.d CRAMFS_MAGIC, $r0 @@ -330,7 +325,7 @@ _no_romfs_in_flash: ;; For jffs2, a jhead is prepended which contains with magic and length. ;; The jhead is not part of the jffs2 partition however. #ifndef CONFIG_ETRAXFS_SIM - move.d __vmlinux_end, $r0 + move.d __bss_start, $r0 #else move.d __end, $r0 #endif @@ -359,7 +354,6 @@ _no_romfs_in_flash: move.d romfs_length, $r3 move.d $r2, [$r3] ; store size at romfs_length -#ifndef CONFIG_ETRAX_VCS_SIM add.d $r2, $r0 ; copy from end and downwards add.d $r2, $r1 @@ -373,7 +367,6 @@ _no_romfs_in_flash: subq 1, $r2 bne 1b nop -#endif 4: ;; BSS move done. @@ -418,7 +411,6 @@ no_command_line: move.d etrax_irv, $r1 ; Set the exception base register and pointer. move.d $r0, [$r1] -#ifndef CONFIG_ETRAX_VCS_SIM ;; Clear the BSS region from _bss_start to _end. move.d __bss_start, $r0 move.d _end, $r1 @@ -426,15 +418,6 @@ no_command_line: cmp.d $r1, $r0 blo 1b nop -#endif - -#ifdef CONFIG_ETRAX_VCS_SIM - /* Set the watchdog timeout to something big. Will be removed when */ - /* watchdog can be disabled with command line option */ - move.d 0x7fffffff, $r10 - jsr CPU_WATCHDOG_TIMEOUT - nop -#endif ; Initialize registers to increase determinism move.d __bss_start, $r0 diff --git a/arch/cris/arch-v32/kernel/irq.c b/arch/cris/arch-v32/kernel/irq.c index 295131fee71..25437ae2812 100644 --- a/arch/cris/arch-v32/kernel/irq.c +++ b/arch/cris/arch-v32/kernel/irq.c @@ -97,7 +97,11 @@ extern void breakh_BUG(void); /* * Build the IRQ handler stubs using macros from irq.h. */ +#ifdef CONFIG_CRIS_MACH_ARTPEC3 +BUILD_TIMER_IRQ(0x31, 0) +#else BUILD_IRQ(0x31) +#endif BUILD_IRQ(0x32) BUILD_IRQ(0x33) BUILD_IRQ(0x34) @@ -123,7 +127,11 @@ BUILD_IRQ(0x47) BUILD_IRQ(0x48) BUILD_IRQ(0x49) BUILD_IRQ(0x4a) +#ifdef CONFIG_ETRAXFS +BUILD_TIMER_IRQ(0x4b, 0) +#else BUILD_IRQ(0x4b) +#endif BUILD_IRQ(0x4c) BUILD_IRQ(0x4d) BUILD_IRQ(0x4e) @@ -199,25 +207,20 @@ block_irq(int irq, int cpu) unsigned long flags; spin_lock_irqsave(&irq_lock, flags); - if (irq - FIRST_IRQ < 32) + /* Remember, 1 let thru, 0 block. */ + if (irq - FIRST_IRQ < 32) { intr_mask = REG_RD_INT_VECT(intr_vect, irq_regs[cpu], rw_mask, 0); - else - intr_mask = REG_RD_INT_VECT(intr_vect, irq_regs[cpu], - rw_mask, 1); - - /* Remember; 1 let thru, 0 block. */ - if (irq - FIRST_IRQ < 32) intr_mask &= ~(1 << (irq - FIRST_IRQ)); - else - intr_mask &= ~(1 << (irq - FIRST_IRQ - 32)); - - if (irq - FIRST_IRQ < 32) REG_WR_INT_VECT(intr_vect, irq_regs[cpu], rw_mask, 0, intr_mask); - else + } else { + intr_mask = REG_RD_INT_VECT(intr_vect, irq_regs[cpu], + rw_mask, 1); + intr_mask &= ~(1 << (irq - FIRST_IRQ - 32)); REG_WR_INT_VECT(intr_vect, irq_regs[cpu], rw_mask, 1, intr_mask); + } spin_unlock_irqrestore(&irq_lock, flags); } @@ -228,26 +231,20 @@ unblock_irq(int irq, int cpu) unsigned long flags; spin_lock_irqsave(&irq_lock, flags); - if (irq - FIRST_IRQ < 32) + /* Remember, 1 let thru, 0 block. */ + if (irq - FIRST_IRQ < 32) { intr_mask = REG_RD_INT_VECT(intr_vect, irq_regs[cpu], rw_mask, 0); - else - intr_mask = REG_RD_INT_VECT(intr_vect, irq_regs[cpu], - rw_mask, 1); - - /* Remember; 1 let thru, 0 block. */ - if (irq - FIRST_IRQ < 32) intr_mask |= (1 << (irq - FIRST_IRQ)); - else - intr_mask |= (1 << (irq - FIRST_IRQ - 32)); - - if (irq - FIRST_IRQ < 32) REG_WR_INT_VECT(intr_vect, irq_regs[cpu], rw_mask, 0, intr_mask); - else + } else { + intr_mask = REG_RD_INT_VECT(intr_vect, irq_regs[cpu], + rw_mask, 1); + intr_mask |= (1 << (irq - FIRST_IRQ - 32)); REG_WR_INT_VECT(intr_vect, irq_regs[cpu], rw_mask, 1, intr_mask); - + } spin_unlock_irqrestore(&irq_lock, flags); } @@ -269,19 +266,18 @@ static int irq_cpu(int irq) /* Let the interrupt stay if possible */ - if (cpu_isset(cpu, irq_allocations[irq - FIRST_IRQ].mask)) + if (cpumask_test_cpu(cpu, &irq_allocations[irq - FIRST_IRQ].mask)) goto out; /* IRQ must be moved to another CPU. */ - cpu = first_cpu(irq_allocations[irq - FIRST_IRQ].mask); + cpu = cpumask_first(&irq_allocations[irq - FIRST_IRQ].mask); irq_allocations[irq - FIRST_IRQ].cpu = cpu; out: spin_unlock_irqrestore(&irq_lock, flags); return cpu; } -void -mask_irq(int irq) +void crisv32_mask_irq(int irq) { int cpu; @@ -289,59 +285,39 @@ mask_irq(int irq) block_irq(irq, cpu); } -void -unmask_irq(int irq) +void crisv32_unmask_irq(int irq) { unblock_irq(irq, irq_cpu(irq)); } -static unsigned int startup_crisv32_irq(unsigned int irq) +static void enable_crisv32_irq(struct irq_data *data) { - unmask_irq(irq); - return 0; + crisv32_unmask_irq(data->irq); } -static void shutdown_crisv32_irq(unsigned int irq) +static void disable_crisv32_irq(struct irq_data *data) { - mask_irq(irq); + crisv32_mask_irq(data->irq); } -static void enable_crisv32_irq(unsigned int irq) -{ - unmask_irq(irq); -} - -static void disable_crisv32_irq(unsigned int irq) -{ - mask_irq(irq); -} - -static void ack_crisv32_irq(unsigned int irq) -{ -} - -static void end_crisv32_irq(unsigned int irq) -{ -} - -void set_affinity_crisv32_irq(unsigned int irq, const struct cpumask *dest) +static int set_affinity_crisv32_irq(struct irq_data *data, + const struct cpumask *dest, bool force) { unsigned long flags; + spin_lock_irqsave(&irq_lock, flags); - irq_allocations[irq - FIRST_IRQ].mask = *dest; + irq_allocations[data->irq - FIRST_IRQ].mask = *dest; spin_unlock_irqrestore(&irq_lock, flags); + return 0; } -static struct hw_interrupt_type crisv32_irq_type = { - .typename = "CRISv32", - .startup = startup_crisv32_irq, - .shutdown = shutdown_crisv32_irq, - .enable = enable_crisv32_irq, - .disable = disable_crisv32_irq, - .ack = ack_crisv32_irq, - .end = end_crisv32_irq, - .set_affinity = set_affinity_crisv32_irq +static struct irq_chip crisv32_irq_type = { + .name = "CRISv32", + .irq_shutdown = disable_crisv32_irq, + .irq_enable = enable_crisv32_irq, + .irq_disable = disable_crisv32_irq, + .irq_set_affinity = set_affinity_crisv32_irq, }; void @@ -355,11 +331,11 @@ extern void do_IRQ(int irq, struct pt_regs * regs); void crisv32_do_IRQ(int irq, int block, struct pt_regs* regs) { - /* Interrupts that may not be moved to another CPU and - * are IRQF_DISABLED may skip blocking. This is currently - * only valid for the timer IRQ and the IPI and is used - * for the timer interrupt to avoid watchdog starvation. - */ + /* Interrupts that may not be moved to another CPU may + * skip blocking. This is currently only valid for the + * timer IRQ and the IPI and is used for the timer + * interrupt to avoid watchdog starvation. + */ if (!block) { do_IRQ(irq, regs); return; @@ -398,7 +374,7 @@ crisv32_do_multiple(struct pt_regs* regs) irq_enter(); for (i = 0; i < NBR_REGS; i++) { - /* Get which IRQs that happend. */ + /* Get which IRQs that happened. */ masked[i] = REG_RD_INT_VECT(intr_vect, irq_regs[cpu], r_masked_vect, i); @@ -428,8 +404,8 @@ crisv32_do_multiple(struct pt_regs* regs) masked[i] &= ~TIMER_MASK; do_IRQ(TIMER0_INTR_VECT, regs); } - } #endif + } #ifdef IGNORE_MASK /* Remove IRQs that can't be handled as multiple. */ @@ -475,15 +451,16 @@ init_IRQ(void) /* Point all IRQ's to bad handlers. */ for (i = FIRST_IRQ, j = 0; j < NR_IRQS; i++, j++) { - irq_desc[j].chip = &crisv32_irq_type; + irq_set_chip_and_handler(j, &crisv32_irq_type, + handle_simple_irq); set_exception_vector(i, interrupt[j]); } - /* Mark Timer and IPI IRQs as CPU local */ + /* Mark Timer and IPI IRQs as CPU local */ irq_allocations[TIMER0_INTR_VECT - FIRST_IRQ].cpu = CPU_FIXED; - irq_desc[TIMER0_INTR_VECT].status |= IRQ_PER_CPU; + irq_set_status_flags(TIMER0_INTR_VECT, IRQ_PER_CPU); irq_allocations[IPI_INTR_VECT - FIRST_IRQ].cpu = CPU_FIXED; - irq_desc[IPI_INTR_VECT].status |= IRQ_PER_CPU; + irq_set_status_flags(IPI_INTR_VECT, IRQ_PER_CPU); set_exception_vector(0x00, nmi_interrupt); set_exception_vector(0x30, multiple_interrupt); diff --git a/arch/cris/arch-v32/kernel/kgdb.c b/arch/cris/arch-v32/kernel/kgdb.c index c981fd66332..b06813aeb12 100644 --- a/arch/cris/arch-v32/kernel/kgdb.c +++ b/arch/cris/arch-v32/kernel/kgdb.c @@ -174,10 +174,10 @@ #include <asm/ptrace.h> #include <asm/irq.h> -#include <arch/hwregs/reg_map.h> -#include <arch/hwregs/reg_rdwr.h> -#include <arch/hwregs/intr_vect_defs.h> -#include <arch/hwregs/ser_defs.h> +#include <hwregs/reg_map.h> +#include <hwregs/reg_rdwr.h> +#include <hwregs/intr_vect_defs.h> +#include <hwregs/ser_defs.h> /* From entry.S. */ extern void gdb_handle_exception(void); @@ -381,23 +381,9 @@ static int read_register(char regno, unsigned int *valptr); /* Serial port, reads one character. ETRAX 100 specific. from debugport.c */ int getDebugChar(void); -#ifdef CONFIG_ETRAX_VCS_SIM -int getDebugChar(void) -{ - return socketread(); -} -#endif - /* Serial port, writes one character. ETRAX 100 specific. from debugport.c */ void putDebugChar(int val); -#ifdef CONFIG_ETRAX_VCS_SIM -void putDebugChar(int val) -{ - socketwrite((char *)&val, 1); -} -#endif - /* Returns the integer equivalent of a hexadecimal character. */ static int hex(char ch); @@ -677,7 +663,7 @@ mem2hex(char *buf, unsigned char *mem, int count) /* Valid mem address. */ for (i = 0; i < count; i++) { ch = *mem++; - buf = pack_hex_byte(buf, ch); + buf = hex_byte_pack(buf, ch); } } /* Terminate properly. */ @@ -695,7 +681,7 @@ mem2hex_nbo(char *buf, unsigned char *mem, int count) mem += count - 1; for (i = 0; i < count; i++) { ch = *mem--; - buf = pack_hex_byte(buf, ch); + buf = hex_byte_pack(buf, ch); } /* Terminate properly. */ @@ -880,7 +866,7 @@ stub_is_stopped(int sigval) /* Send trap type (converted to signal) */ *ptr++ = 'T'; - ptr = pack_hex_byte(ptr, sigval); + ptr = hex_byte_pack(ptr, sigval); if (((reg.exs & 0xff00) >> 8) == 0xc) { @@ -925,7 +911,7 @@ stub_is_stopped(int sigval) if (reg.eda >= bp_d_regs[bp * 2] && reg.eda <= bp_d_regs[bp * 2 + 1]) { - /* EDA withing range for this BP; it must be the one + /* EDA within range for this BP; it must be the one we're looking for. */ stopped_data_address = reg.eda; break; @@ -988,26 +974,26 @@ stub_is_stopped(int sigval) } /* Only send PC, frame and stack pointer. */ read_register(PC, ®_cont); - ptr = pack_hex_byte(PC); + ptr = hex_byte_pack(ptr, PC); *ptr++ = ':'; ptr = mem2hex(ptr, (unsigned char *)®_cont, register_size[PC]); *ptr++ = ';'; read_register(R8, ®_cont); - ptr = pack_hex_byte(R8); + ptr = hex_byte_pack(ptr, R8); *ptr++ = ':'; ptr = mem2hex(ptr, (unsigned char *)®_cont, register_size[R8]); *ptr++ = ';'; read_register(SP, ®_cont); - ptr = pack_hex_byte(SP); + ptr = hex_byte_pack(ptr, SP); *ptr++ = ':'; ptr = mem2hex(ptr, (unsigned char *)®_cont, register_size[SP]); *ptr++ = ';'; /* Send ERP as well; this will save us an entire register fetch in some cases. */ read_register(ERP, ®_cont); - ptr = pack_hex_byte(ERP); + ptr = hex_byte_pack(ptr, ERP); *ptr++ = ':'; ptr = mem2hex(ptr, (unsigned char *)®_cont, register_size[ERP]); *ptr++ = ';'; diff --git a/arch/cris/arch-v32/kernel/kgdb_asm.S b/arch/cris/arch-v32/kernel/kgdb_asm.S index eba93e7e4aa..f3a47605902 100644 --- a/arch/cris/arch-v32/kernel/kgdb_asm.S +++ b/arch/cris/arch-v32/kernel/kgdb_asm.S @@ -5,7 +5,7 @@ * port exceptions for kernel debugging purposes. */ -#include <arch/hwregs/intr_vect.h> +#include <hwregs/intr_vect.h> ;; Exported functions. .globl kgdb_handle_exception diff --git a/arch/cris/arch-v32/kernel/pinmux.c b/arch/cris/arch-v32/kernel/pinmux.c deleted file mode 100644 index 6eb54ea1c97..00000000000 --- a/arch/cris/arch-v32/kernel/pinmux.c +++ /dev/null @@ -1,229 +0,0 @@ -/* - * Allocator for I/O pins. All pins are allocated to GPIO at bootup. - * Unassigned pins and GPIO pins can be allocated to a fixed interface - * or the I/O processor instead. - * - * Copyright (c) 2004 Axis Communications AB. - */ - -#include <linux/init.h> -#include <linux/errno.h> -#include <linux/kernel.h> -#include <linux/string.h> -#include <linux/spinlock.h> -#include <arch/hwregs/reg_map.h> -#include <arch/hwregs/reg_rdwr.h> -#include <arch/pinmux.h> -#include <arch/hwregs/pinmux_defs.h> - -#undef DEBUG - -#define PORT_PINS 18 -#define PORTS 4 - -static char pins[PORTS][PORT_PINS]; -static DEFINE_SPINLOCK(pinmux_lock); - -static void crisv32_pinmux_set(int port); - -int -crisv32_pinmux_init(void) -{ - static int initialized = 0; - - if (!initialized) { - reg_pinmux_rw_pa pa = REG_RD(pinmux, regi_pinmux, rw_pa); - initialized = 1; - pa.pa0 = pa.pa1 = pa.pa2 = pa.pa3 = - pa.pa4 = pa.pa5 = pa.pa6 = pa.pa7 = regk_pinmux_yes; - REG_WR(pinmux, regi_pinmux, rw_pa, pa); - crisv32_pinmux_alloc(PORT_B, 0, PORT_PINS - 1, pinmux_gpio); - crisv32_pinmux_alloc(PORT_C, 0, PORT_PINS - 1, pinmux_gpio); - crisv32_pinmux_alloc(PORT_D, 0, PORT_PINS - 1, pinmux_gpio); - crisv32_pinmux_alloc(PORT_E, 0, PORT_PINS - 1, pinmux_gpio); - } - - return 0; -} - -int -crisv32_pinmux_alloc(int port, int first_pin, int last_pin, enum pin_mode mode) -{ - int i; - unsigned long flags; - - crisv32_pinmux_init(); - - if (port > PORTS) - return -EINVAL; - - spin_lock_irqsave(&pinmux_lock, flags); - - for (i = first_pin; i <= last_pin; i++) - { - if ((pins[port][i] != pinmux_none) && (pins[port][i] != pinmux_gpio) && - (pins[port][i] != mode)) - { - spin_unlock_irqrestore(&pinmux_lock, flags); -#ifdef DEBUG - panic("Pinmux alloc failed!\n"); -#endif - return -EPERM; - } - } - - for (i = first_pin; i <= last_pin; i++) - pins[port][i] = mode; - - crisv32_pinmux_set(port); - - spin_unlock_irqrestore(&pinmux_lock, flags); - - return 0; -} - -int -crisv32_pinmux_alloc_fixed(enum fixed_function function) -{ - int ret = -EINVAL; - char saved[sizeof pins]; - unsigned long flags; - - spin_lock_irqsave(&pinmux_lock, flags); - - /* Save internal data for recovery */ - memcpy(saved, pins, sizeof pins); - - reg_pinmux_rw_hwprot hwprot = REG_RD(pinmux, regi_pinmux, rw_hwprot); - - switch(function) - { - case pinmux_ser1: - ret = crisv32_pinmux_alloc(PORT_C, 4, 7, pinmux_fixed); - hwprot.ser1 = regk_pinmux_yes; - break; - case pinmux_ser2: - ret = crisv32_pinmux_alloc(PORT_C, 8, 11, pinmux_fixed); - hwprot.ser2 = regk_pinmux_yes; - break; - case pinmux_ser3: - ret = crisv32_pinmux_alloc(PORT_C, 12, 15, pinmux_fixed); - hwprot.ser3 = regk_pinmux_yes; - break; - case pinmux_sser0: - ret = crisv32_pinmux_alloc(PORT_C, 0, 3, pinmux_fixed); - ret |= crisv32_pinmux_alloc(PORT_C, 16, 16, pinmux_fixed); - hwprot.sser0 = regk_pinmux_yes; - break; - case pinmux_sser1: - ret = crisv32_pinmux_alloc(PORT_D, 0, 4, pinmux_fixed); - hwprot.sser1 = regk_pinmux_yes; - break; - case pinmux_ata0: - ret = crisv32_pinmux_alloc(PORT_D, 5, 7, pinmux_fixed); - ret |= crisv32_pinmux_alloc(PORT_D, 15, 17, pinmux_fixed); - hwprot.ata0 = regk_pinmux_yes; - break; - case pinmux_ata1: - ret = crisv32_pinmux_alloc(PORT_D, 0, 4, pinmux_fixed); - ret |= crisv32_pinmux_alloc(PORT_E, 17, 17, pinmux_fixed); - hwprot.ata1 = regk_pinmux_yes; - break; - case pinmux_ata2: - ret = crisv32_pinmux_alloc(PORT_C, 11, 15, pinmux_fixed); - ret |= crisv32_pinmux_alloc(PORT_E, 3, 3, pinmux_fixed); - hwprot.ata2 = regk_pinmux_yes; - break; - case pinmux_ata3: - ret = crisv32_pinmux_alloc(PORT_C, 8, 10, pinmux_fixed); - ret |= crisv32_pinmux_alloc(PORT_C, 0, 2, pinmux_fixed); - hwprot.ata2 = regk_pinmux_yes; - break; - case pinmux_ata: - ret = crisv32_pinmux_alloc(PORT_B, 0, 15, pinmux_fixed); - ret |= crisv32_pinmux_alloc(PORT_D, 8, 15, pinmux_fixed); - hwprot.ata = regk_pinmux_yes; - break; - case pinmux_eth1: - ret = crisv32_pinmux_alloc(PORT_E, 0, 17, pinmux_fixed); - hwprot.eth1 = regk_pinmux_yes; - hwprot.eth1_mgm = regk_pinmux_yes; - break; - case pinmux_timer: - ret = crisv32_pinmux_alloc(PORT_C, 16, 16, pinmux_fixed); - hwprot.timer = regk_pinmux_yes; - spin_unlock_irqrestore(&pinmux_lock, flags); - return ret; - } - - if (!ret) - REG_WR(pinmux, regi_pinmux, rw_hwprot, hwprot); - else - memcpy(pins, saved, sizeof pins); - - spin_unlock_irqrestore(&pinmux_lock, flags); - - return ret; -} - -void -crisv32_pinmux_set(int port) -{ - int i; - int gpio_val = 0; - int iop_val = 0; - - for (i = 0; i < PORT_PINS; i++) - { - if (pins[port][i] == pinmux_gpio) - gpio_val |= (1 << i); - else if (pins[port][i] == pinmux_iop) - iop_val |= (1 << i); - } - - REG_WRITE(int, regi_pinmux + REG_RD_ADDR_pinmux_rw_pb_gio + 8*port, gpio_val); - REG_WRITE(int, regi_pinmux + REG_RD_ADDR_pinmux_rw_pb_iop + 8*port, iop_val); - -#ifdef DEBUG - crisv32_pinmux_dump(); -#endif -} - -int -crisv32_pinmux_dealloc(int port, int first_pin, int last_pin) -{ - int i; - unsigned long flags; - - crisv32_pinmux_init(); - - if (port > PORTS) - return -EINVAL; - - spin_lock_irqsave(&pinmux_lock, flags); - - for (i = first_pin; i <= last_pin; i++) - pins[port][i] = pinmux_none; - - crisv32_pinmux_set(port); - spin_unlock_irqrestore(&pinmux_lock, flags); - - return 0; -} - -void -crisv32_pinmux_dump(void) -{ - int i, j; - - crisv32_pinmux_init(); - - for (i = 0; i < PORTS; i++) - { - printk("Port %c\n", 'B'+i); - for (j = 0; j < PORT_PINS; j++) - printk(" Pin %d = %d\n", j, pins[i][j]); - } -} - -__initcall(crisv32_pinmux_init); diff --git a/arch/cris/arch-v32/kernel/process.c b/arch/cris/arch-v32/kernel/process.c index ced5b725d9b..cebd32e2a8f 100644 --- a/arch/cris/arch-v32/kernel/process.c +++ b/arch/cris/arch-v32/kernel/process.c @@ -9,28 +9,23 @@ */ #include <linux/sched.h> +#include <linux/slab.h> #include <linux/err.h> #include <linux/fs.h> -#include <linux/slab.h> #include <hwregs/reg_rdwr.h> #include <hwregs/reg_map.h> #include <hwregs/timer_defs.h> #include <hwregs/intr_vect_defs.h> +#include <linux/ptrace.h> extern void stop_watchdog(void); -extern int cris_hlt_counter; - /* We use this if we don't have any better idle routine. */ void default_idle(void) { - local_irq_disable(); - if (!need_resched() && !cris_hlt_counter) { - /* Halt until exception. */ - __asm__ volatile("ei \n\t" - "halt "); - } - local_irq_enable(); + /* Halt until exception. */ + __asm__ volatile("ei \n\t" + "halt "); } /* @@ -94,31 +89,6 @@ unsigned long thread_saved_pc(struct task_struct *t) return task_pt_regs(t)->erp; } -static void -kernel_thread_helper(void* dummy, int (*fn)(void *), void * arg) -{ - fn(arg); - do_exit(-1); /* Should never be called, return bad exit value. */ -} - -/* Create a kernel thread. */ -int -kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) -{ - struct pt_regs regs; - - memset(®s, 0, sizeof(regs)); - - /* Don't use r10 since that is set to 0 in copy_thread. */ - regs.r11 = (unsigned long) fn; - regs.r12 = (unsigned long) arg; - regs.erp = (unsigned long) kernel_thread_helper; - regs.ccs = 1 << (I_CCS_BITNR + CCS_SHIFT); - - /* Create the new process. */ - return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, NULL); -} - /* * Setup the child's kernel stack with a pt_regs and call switch_stack() on it. * It will be unnested during _resume and _ret_from_sys_call when the new thread @@ -129,34 +99,42 @@ kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) */ extern asmlinkage void ret_from_fork(void); +extern asmlinkage void ret_from_kernel_thread(void); int -copy_thread(int nr, unsigned long clone_flags, unsigned long usp, - unsigned long unused, - struct task_struct *p, struct pt_regs *regs) +copy_thread(unsigned long clone_flags, unsigned long usp, + unsigned long arg, struct task_struct *p) { - struct pt_regs *childregs; - struct switch_stack *swstack; + struct pt_regs *childregs = task_pt_regs(p); + struct switch_stack *swstack = ((struct switch_stack *) childregs) - 1; /* * Put the pt_regs structure at the end of the new kernel stack page and * fix it up. Note: the task_struct doubles as the kernel stack for the * task. */ - childregs = task_pt_regs(p); - *childregs = *regs; /* Struct copy of pt_regs. */ - p->set_child_tid = p->clear_child_tid = NULL; + if (unlikely(p->flags & PF_KTHREAD)) { + memset(swstack, 0, + sizeof(struct switch_stack) + sizeof(struct pt_regs)); + swstack->r1 = usp; + swstack->r2 = arg; + childregs->ccs = 1 << (I_CCS_BITNR + CCS_SHIFT); + swstack->return_ip = (unsigned long) ret_from_kernel_thread; + p->thread.ksp = (unsigned long) swstack; + p->thread.usp = 0; + return 0; + } + *childregs = *current_pt_regs(); /* Struct copy of pt_regs. */ childregs->r10 = 0; /* Child returns 0 after a fork/clone. */ /* Set a new TLS ? - * The TLS is in $mof beacuse it is the 5th argument to sys_clone. + * The TLS is in $mof because it is the 5th argument to sys_clone. */ if (p->mm && (clone_flags & CLONE_SETTLS)) { - task_thread_info(p)->tls = regs->mof; + task_thread_info(p)->tls = childregs->mof; } /* Put the switch stack right below the pt_regs. */ - swstack = ((struct switch_stack *) childregs) - 1; /* Parameter to ret_from_sys_call. 0 is don't restart the syscall. */ swstack->r9 = 0; @@ -168,74 +146,12 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long usp, swstack->return_ip = (unsigned long) ret_from_fork; /* Fix the user-mode and kernel-mode stackpointer. */ - p->thread.usp = usp; + p->thread.usp = usp ?: rdusp(); p->thread.ksp = (unsigned long) swstack; return 0; } -/* - * Be aware of the "magic" 7th argument in the four system-calls below. - * They need the latest stackframe, which is put as the 7th argument by - * entry.S. The previous arguments are dummies or actually used, but need - * to be defined to reach the 7th argument. - * - * N.B.: Another method to get the stackframe is to use current_regs(). But - * it returns the latest stack-frame stacked when going from _user mode_ and - * some of these (at least sys_clone) are called from kernel-mode sometimes - * (for example during kernel_thread, above) and thus cannot use it. Thus, - * to be sure not to get any surprises, we use the method for the other calls - * as well. - */ -asmlinkage int -sys_fork(long r10, long r11, long r12, long r13, long mof, long srp, - struct pt_regs *regs) -{ - return do_fork(SIGCHLD, rdusp(), regs, 0, NULL, NULL); -} - -/* FIXME: Is parent_tid/child_tid really third/fourth argument? Update lib? */ -asmlinkage int -sys_clone(unsigned long newusp, unsigned long flags, int *parent_tid, int *child_tid, - unsigned long tls, long srp, struct pt_regs *regs) -{ - if (!newusp) - newusp = rdusp(); - - return do_fork(flags, newusp, regs, 0, parent_tid, child_tid); -} - -/* - * vfork is a system call in i386 because of register-pressure - maybe - * we can remove it and handle it in libc but we put it here until then. - */ -asmlinkage int -sys_vfork(long r10, long r11, long r12, long r13, long mof, long srp, - struct pt_regs *regs) -{ - return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, rdusp(), regs, 0, NULL, NULL); -} - -/* sys_execve() executes a new program. */ -asmlinkage int -sys_execve(const char *fname, char **argv, char **envp, long r13, long mof, long srp, - struct pt_regs *regs) -{ - int error; - char *filename; - - filename = getname(fname); - error = PTR_ERR(filename); - - if (IS_ERR(filename)) - goto out; - - error = do_execve(filename, argv, envp, regs); - putname(filename); - out: - return error; -} - unsigned long get_wchan(struct task_struct *p) { @@ -248,6 +164,9 @@ get_wchan(struct task_struct *p) void show_regs(struct pt_regs * regs) { unsigned long usp = rdusp(); + + show_regs_print_info(KERN_DEFAULT); + printk("ERP: %08lx SRP: %08lx CCS: %08lx USP: %08lx MOF: %08lx\n", regs->erp, regs->srp, regs->ccs, usp, regs->mof); diff --git a/arch/cris/arch-v32/kernel/ptrace.c b/arch/cris/arch-v32/kernel/ptrace.c index dd401473f5b..f085229cf87 100644 --- a/arch/cris/arch-v32/kernel/ptrace.c +++ b/arch/cris/arch-v32/kernel/ptrace.c @@ -15,7 +15,6 @@ #include <asm/uaccess.h> #include <asm/page.h> #include <asm/pgtable.h> -#include <asm/system.h> #include <asm/processor.h> #include <arch/hwregs/supp_reg.h> @@ -78,6 +77,35 @@ int put_reg(struct task_struct *task, unsigned int regno, unsigned long data) return 0; } +void user_enable_single_step(struct task_struct *child) +{ + unsigned long tmp; + + /* + * Set up SPC if not set already (in which case we have no other + * choice but to trust it). + */ + if (!get_reg(child, PT_SPC)) { + /* In case we're stopped in a delay slot. */ + tmp = get_reg(child, PT_ERP) & ~1; + put_reg(child, PT_SPC, tmp); + } + tmp = get_reg(child, PT_CCS) | SBIT_USER; + put_reg(child, PT_CCS, tmp); +} + +void user_disable_single_step(struct task_struct *child) +{ + put_reg(child, PT_SPC, 0); + + if (!get_debugreg(child->pid, PT_BP_CTRL)) { + unsigned long tmp; + /* If no h/w bp configured, disable S bit. */ + tmp = get_reg(child, PT_CCS) & ~SBIT_USER; + put_reg(child, PT_CCS, tmp); + } +} + /* * Called by kernel/ptrace.c when detaching. * @@ -86,11 +114,8 @@ int put_reg(struct task_struct *task, unsigned int regno, unsigned long data) void ptrace_disable(struct task_struct *child) { - unsigned long tmp; - /* Deconfigure SPC and S-bit. */ - tmp = get_reg(child, PT_CCS) & ~SBIT_USER; - put_reg(child, PT_CCS, tmp); + user_disable_single_step(child); put_reg(child, PT_SPC, 0); /* Deconfigure any watchpoints associated with the child. */ @@ -98,9 +123,11 @@ ptrace_disable(struct task_struct *child) } -long arch_ptrace(struct task_struct *child, long request, long addr, long data) +long arch_ptrace(struct task_struct *child, long request, + unsigned long addr, unsigned long data) { int ret; + unsigned int regno = addr >> 2; unsigned long __user *datap = (unsigned long __user *)data; switch (request) { @@ -135,10 +162,10 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) unsigned long tmp; ret = -EIO; - if ((addr & 3) || addr < 0 || addr > PT_MAX << 2) + if ((addr & 3) || regno > PT_MAX) break; - tmp = get_reg(child, addr >> 2); + tmp = get_reg(child, regno); ret = put_user(tmp, datap); break; } @@ -152,100 +179,21 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) /* Write the word at location address in the USER area. */ case PTRACE_POKEUSR: ret = -EIO; - if ((addr & 3) || addr < 0 || addr > PT_MAX << 2) + if ((addr & 3) || regno > PT_MAX) break; - addr >>= 2; - - if (addr == PT_CCS) { + if (regno == PT_CCS) { /* don't allow the tracing process to change stuff like * interrupt enable, kernel/user bit, dma enables etc. */ data &= CCS_MASK; data |= get_reg(child, PT_CCS) & ~CCS_MASK; } - if (put_reg(child, addr, data)) + if (put_reg(child, regno, data)) break; ret = 0; break; - case PTRACE_SYSCALL: - case PTRACE_CONT: - ret = -EIO; - - if (!valid_signal(data)) - break; - - /* Continue means no single-step. */ - put_reg(child, PT_SPC, 0); - - if (!get_debugreg(child->pid, PT_BP_CTRL)) { - unsigned long tmp; - /* If no h/w bp configured, disable S bit. */ - tmp = get_reg(child, PT_CCS) & ~SBIT_USER; - put_reg(child, PT_CCS, tmp); - } - - if (request == PTRACE_SYSCALL) { - set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); - } - else { - clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); - } - - child->exit_code = data; - - /* TODO: make sure any pending breakpoint is killed */ - wake_up_process(child); - ret = 0; - - break; - - /* Make the child exit by sending it a sigkill. */ - case PTRACE_KILL: - ret = 0; - - if (child->exit_state == EXIT_ZOMBIE) - break; - - child->exit_code = SIGKILL; - - /* Deconfigure single-step and h/w bp. */ - ptrace_disable(child); - - /* TODO: make sure any pending breakpoint is killed */ - wake_up_process(child); - break; - - /* Set the trap flag. */ - case PTRACE_SINGLESTEP: { - unsigned long tmp; - ret = -EIO; - - /* Set up SPC if not set already (in which case we have - no other choice but to trust it). */ - if (!get_reg(child, PT_SPC)) { - /* In case we're stopped in a delay slot. */ - tmp = get_reg(child, PT_ERP) & ~1; - put_reg(child, PT_SPC, tmp); - } - tmp = get_reg(child, PT_CCS) | SBIT_USER; - put_reg(child, PT_CCS, tmp); - - if (!valid_signal(data)) - break; - - clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); - - /* TODO: set some clever breakpoint mechanism... */ - - child->exit_code = data; - wake_up_process(child); - ret = 0; - break; - - } - /* Get all GP registers from the child. */ case PTRACE_GETREGS: { int i; diff --git a/arch/cris/arch-v32/kernel/setup.c b/arch/cris/arch-v32/kernel/setup.c index 72e9e8331f6..61e10ae6529 100644 --- a/arch/cris/arch-v32/kernel/setup.c +++ b/arch/cris/arch-v32/kernel/setup.c @@ -9,6 +9,9 @@ #include <linux/delay.h> #include <linux/param.h> +#include <linux/i2c.h> +#include <linux/platform_device.h> + #ifdef CONFIG_PROC_FS #define HAS_FPU 0x0001 @@ -43,14 +46,15 @@ static struct cpu_info cpinfo[] = { {"ETRAX 100LX v2", 11, 8, HAS_ETHERNET100 | HAS_SCSI | HAS_ATA | HAS_USB | HAS_MMU}, - +#ifdef CONFIG_ETRAXFS {"ETRAX FS", 32, 32, HAS_ETHERNET100 | HAS_ATA | HAS_MMU}, - +#else + {"ARTPEC-3", 32, 32, HAS_ETHERNET100 | HAS_MMU}, +#endif {"Unknown", 0, 0, 0} }; -int -show_cpuinfo(struct seq_file *m, void *v) +int show_cpuinfo(struct seq_file *m, void *v) { int i; int cpu = (int)v - 1; @@ -107,9 +111,63 @@ show_cpuinfo(struct seq_file *m, void *v) #endif /* CONFIG_PROC_FS */ -void -show_etrax_copyright(void) +void show_etrax_copyright(void) +{ +#ifdef CONFIG_ETRAXFS + printk(KERN_INFO "Linux/CRISv32 port on ETRAX FS " + "(C) 2003, 2004 Axis Communications AB\n"); +#else + printk(KERN_INFO "Linux/CRISv32 port on ARTPEC-3 " + "(C) 2003-2009 Axis Communications AB\n"); +#endif +} + +static struct i2c_board_info __initdata i2c_info[] = { + {I2C_BOARD_INFO("camblock", 0x43)}, + {I2C_BOARD_INFO("tmp100", 0x48)}, + {I2C_BOARD_INFO("tmp100", 0x4A)}, + {I2C_BOARD_INFO("tmp100", 0x4C)}, + {I2C_BOARD_INFO("tmp100", 0x4D)}, + {I2C_BOARD_INFO("tmp100", 0x4E)}, +#ifdef CONFIG_RTC_DRV_PCF8563 + {I2C_BOARD_INFO("pcf8563", 0x51)}, +#endif +#ifdef CONFIG_ETRAX_VIRTUAL_GPIO + {I2C_BOARD_INFO("vgpio", 0x20)}, + {I2C_BOARD_INFO("vgpio", 0x21)}, +#endif + {I2C_BOARD_INFO("pca9536", 0x41)}, + {I2C_BOARD_INFO("fnp300", 0x40)}, + {I2C_BOARD_INFO("fnp300", 0x42)}, + {I2C_BOARD_INFO("adc101", 0x54)}, +}; + +static struct i2c_board_info __initdata i2c_info2[] = { + {I2C_BOARD_INFO("camblock", 0x43)}, + {I2C_BOARD_INFO("tmp100", 0x48)}, + {I2C_BOARD_INFO("tmp100", 0x4A)}, + {I2C_BOARD_INFO("tmp100", 0x4C)}, + {I2C_BOARD_INFO("tmp100", 0x4D)}, + {I2C_BOARD_INFO("tmp100", 0x4E)}, +#ifdef CONFIG_ETRAX_VIRTUAL_GPIO + {I2C_BOARD_INFO("vgpio", 0x20)}, + {I2C_BOARD_INFO("vgpio", 0x21)}, +#endif + {I2C_BOARD_INFO("pca9536", 0x41)}, + {I2C_BOARD_INFO("fnp300", 0x40)}, + {I2C_BOARD_INFO("fnp300", 0x42)}, + {I2C_BOARD_INFO("adc101", 0x54)}, +}; + +static struct i2c_board_info __initdata i2c_info3[] = { + {I2C_BOARD_INFO("adc101", 0x54)}, +}; + +static int __init etrax_init(void) { - printk(KERN_INFO - "Linux/CRISv32 port on ETRAX FS (C) 2003, 2004 Axis Communications AB\n"); + i2c_register_board_info(0, i2c_info, ARRAY_SIZE(i2c_info)); + i2c_register_board_info(1, i2c_info2, ARRAY_SIZE(i2c_info2)); + i2c_register_board_info(2, i2c_info3, ARRAY_SIZE(i2c_info3)); + return 0; } +arch_initcall(etrax_init); diff --git a/arch/cris/arch-v32/kernel/signal.c b/arch/cris/arch-v32/kernel/signal.c index 372d0ca6efb..01d1375c900 100644 --- a/arch/cris/arch-v32/kernel/signal.c +++ b/arch/cris/arch-v32/kernel/signal.c @@ -4,6 +4,7 @@ #include <linux/sched.h> #include <linux/mm.h> +#include <linux/slab.h> #include <linux/kernel.h> #include <linux/signal.h> #include <linux/errno.h> @@ -23,9 +24,6 @@ extern unsigned long cris_signal_return_page; -/* Flag to check if a signal is blockable. */ -#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) - /* * A syscall in CRIS is really a "break 13" instruction, which is 2 * bytes. The registers is manipulated so upon return the instruction @@ -53,67 +51,6 @@ struct rt_signal_frame { void do_signal(int restart, struct pt_regs *regs); void keep_debug_flags(unsigned long oldccs, unsigned long oldspc, struct pt_regs *regs); -/* - * Swap in the new signal mask, and wait for a signal. Define some - * dummy arguments to be able to reach the regs argument. - */ -int -sys_sigsuspend(old_sigset_t mask, long r11, long r12, long r13, long mof, - long srp, struct pt_regs *regs) -{ - mask &= _BLOCKABLE; - spin_lock_irq(¤t->sighand->siglock); - current->saved_sigmask = current->blocked; - siginitset(¤t->blocked, mask); - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); - current->state = TASK_INTERRUPTIBLE; - schedule(); - set_thread_flag(TIF_RESTORE_SIGMASK); - return -ERESTARTNOHAND; -} - -int -sys_sigaction(int signal, const struct old_sigaction *act, - struct old_sigaction *oact) -{ - int retval; - struct k_sigaction newk; - struct k_sigaction oldk; - - if (act) { - old_sigset_t mask; - - if (!access_ok(VERIFY_READ, act, sizeof(*act)) || - __get_user(newk.sa.sa_handler, &act->sa_handler) || - __get_user(newk.sa.sa_restorer, &act->sa_restorer)) - return -EFAULT; - - __get_user(newk.sa.sa_flags, &act->sa_flags); - __get_user(mask, &act->sa_mask); - siginitset(&newk.sa.sa_mask, mask); - } - - retval = do_sigaction(signal, act ? &newk : NULL, oact ? &oldk : NULL); - - if (!retval && oact) { - if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || - __put_user(oldk.sa.sa_handler, &oact->sa_handler) || - __put_user(oldk.sa.sa_restorer, &oact->sa_restorer)) - return -EFAULT; - - __put_user(oldk.sa.sa_flags, &oact->sa_flags); - __put_user(oldk.sa.sa_mask.sig[0], &oact->sa_mask); - } - - return retval; -} - -int -sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss) -{ - return do_sigaltstack(uss, uoss, rdusp()); -} static int restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc) @@ -145,11 +82,9 @@ badframe: return 1; } -/* Define some dummy arguments to be able to reach the regs argument. */ -asmlinkage int -sys_sigreturn(long r10, long r11, long r12, long r13, long mof, long srp, - struct pt_regs *regs) +asmlinkage int sys_sigreturn(void) { + struct pt_regs *regs = current_pt_regs(); sigset_t set; struct signal_frame __user *frame; unsigned long oldspc = regs->spc; @@ -174,13 +109,7 @@ sys_sigreturn(long r10, long r11, long r12, long r13, long mof, long srp, sizeof(frame->extramask)))) goto badframe; - sigdelsetmask(&set, ~_BLOCKABLE); - spin_lock_irq(¤t->sighand->siglock); - - current->blocked = set; - - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); + set_current_blocked(&set); if (restore_sigcontext(regs, &frame->sc)) goto badframe; @@ -194,11 +123,9 @@ badframe: return 0; } -/* Define some dummy variables to be able to reach the regs argument. */ -asmlinkage int -sys_rt_sigreturn(long r10, long r11, long r12, long r13, long mof, long srp, - struct pt_regs *regs) +asmlinkage int sys_rt_sigreturn(void) { + struct pt_regs *regs = current_pt_regs(); sigset_t set; struct rt_signal_frame __user *frame; unsigned long oldspc = regs->spc; @@ -220,18 +147,12 @@ sys_rt_sigreturn(long r10, long r11, long r12, long r13, long mof, long srp, if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) goto badframe; - sigdelsetmask(&set, ~_BLOCKABLE); - spin_lock_irq(¤t->sighand->siglock); - - current->blocked = set; - - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); + set_current_blocked(&set); if (restore_sigcontext(regs, &frame->uc.uc_mcontext)) goto badframe; - if (do_sigaltstack(&frame->uc.uc_stack, NULL, rdusp()) == -EFAULT) + if (restore_altstack(&frame->uc.uc_stack)) goto badframe; keep_debug_flags(oldccs, oldspc, regs); @@ -362,10 +283,7 @@ setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, return 0; give_sigsegv: - if (sig == SIGSEGV) - ka->sa.sa_handler = SIG_DFL; - - force_sig(SIGSEGV, current); + force_sigsegv(sig, current); return -EFAULT; } @@ -396,6 +314,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, err |= __clear_user(&frame->uc, offsetof(struct ucontext, uc_mcontext)); err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, set->sig[0]); err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); + err |= __save_altstack(&frame->uc.uc_stack, rdusp()); if (err) goto give_sigsegv; @@ -449,19 +368,17 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, return 0; give_sigsegv: - if (sig == SIGSEGV) - ka->sa.sa_handler = SIG_DFL; - - force_sig(SIGSEGV, current); + force_sigsegv(sig, current); return -EFAULT; } /* Invoke a signal handler to, well, handle the signal. */ -static inline int +static inline void handle_signal(int canrestart, unsigned long sig, siginfo_t *info, struct k_sigaction *ka, - sigset_t *oldset, struct pt_regs * regs) + struct pt_regs * regs) { + sigset_t *oldset = sigmask_to_save(); int ret; /* Check if this got called from a system call. */ @@ -511,20 +428,8 @@ handle_signal(int canrestart, unsigned long sig, else ret = setup_frame(sig, ka, oldset, regs); - if (ka->sa.sa_flags & SA_ONESHOT) - ka->sa.sa_handler = SIG_DFL; - - if (ret == 0) { - spin_lock_irq(¤t->sighand->siglock); - sigorsets(¤t->blocked, ¤t->blocked, - &ka->sa.sa_mask); - if (!(ka->sa.sa_flags & SA_NODEFER)) - sigaddset(¤t->blocked, sig); - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); - } - - return ret; + if (ret == 0) + signal_delivered(sig, info, ka, regs, 0); } /* @@ -544,7 +449,6 @@ do_signal(int canrestart, struct pt_regs *regs) int signr; siginfo_t info; struct k_sigaction ka; - sigset_t *oldset; /* * The common case should go fast, which is why this point is @@ -554,25 +458,11 @@ do_signal(int canrestart, struct pt_regs *regs) if (!user_mode(regs)) return; - if (test_thread_flag(TIF_RESTORE_SIGMASK)) - oldset = ¤t->saved_sigmask; - else - oldset = ¤t->blocked; - signr = get_signal_to_deliver(&info, &ka, regs, NULL); if (signr > 0) { /* Whee! Actually deliver the signal. */ - if (handle_signal(canrestart, signr, &info, &ka, - oldset, regs)) { - /* a signal was successfully delivered; the saved - * sigmask will have been stored in the signal frame, - * and will be restored by sigreturn, so we can simply - * clear the TIF_RESTORE_SIGMASK flag */ - if (test_thread_flag(TIF_RESTORE_SIGMASK)) - clear_thread_flag(TIF_RESTORE_SIGMASK); - } - + handle_signal(canrestart, signr, &info, &ka, regs); return; } @@ -586,17 +476,14 @@ do_signal(int canrestart, struct pt_regs *regs) } if (regs->r10 == -ERESTART_RESTARTBLOCK){ - regs->r10 = __NR_restart_syscall; + regs->r9 = __NR_restart_syscall; regs->erp -= 2; } } /* if there's no signal to deliver, we just put the saved sigmask * back */ - if (test_thread_flag(TIF_RESTORE_SIGMASK)) { - clear_thread_flag(TIF_RESTORE_SIGMASK); - sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); - } + restore_saved_sigmask(); } asmlinkage void @@ -609,7 +496,7 @@ ugdb_trap_user(struct thread_info *ti, int sig) user_regs(ti)->spc = 0; } /* FIXME: Filter out false h/w breakpoint hits (i.e. EDA - not withing any configured h/w breakpoint range). Synchronize with + not within any configured h/w breakpoint range). Synchronize with what already exists for kernel debugging. */ if (((user_regs(ti)->exs & 0xff00) >> 8) == BREAK_8_INTR_VECT) { /* Break 8: subtract 2 from ERP unless in a delay slot. */ diff --git a/arch/cris/arch-v32/kernel/smp.c b/arch/cris/arch-v32/kernel/smp.c index 9dac1733464..0698582467c 100644 --- a/arch/cris/arch-v32/kernel/smp.c +++ b/arch/cris/arch-v32/kernel/smp.c @@ -7,7 +7,7 @@ #include <asm/mmu_context.h> #include <hwregs/asm/mmu_defs_asm.h> #include <hwregs/supp_reg.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <linux/err.h> #include <linux/init.h> @@ -26,7 +26,9 @@ #define FLUSH_ALL (void*)0xffffffff /* Vector of locks used for various atomic operations */ -spinlock_t cris_atomic_locks[] = { [0 ... LOCK_COUNT - 1] = SPIN_LOCK_UNLOCKED}; +spinlock_t cris_atomic_locks[] = { + [0 ... LOCK_COUNT - 1] = __SPIN_LOCK_UNLOCKED(cris_atomic_locks) +}; /* CPU masks */ cpumask_t phys_cpu_present_map = CPU_MASK_NONE; @@ -52,8 +54,6 @@ static struct mm_struct* flush_mm; static struct vm_area_struct* flush_vma; static unsigned long flush_addr; -extern int setup_irq(int, struct irqaction *); - /* Mode registers */ static unsigned long irq_regs[NR_CPUS] = { regi_irq, @@ -64,8 +64,7 @@ static irqreturn_t crisv32_ipi_interrupt(int irq, void *dev_id); static int send_ipi(int vector, int wait, cpumask_t cpu_mask); static struct irqaction irq_ipi = { .handler = crisv32_ipi_interrupt, - .flags = IRQF_DISABLED, - .mask = CPU_MASK_NONE, + .flags = 0, .name = "ipi", }; @@ -82,10 +81,10 @@ void __init smp_prepare_cpus(unsigned int max_cpus) /* Mark all possible CPUs as present */ for (i = 0; i < max_cpus; i++) - cpu_set(i, phys_cpu_present_map); + cpumask_set_cpu(i, &phys_cpu_present_map); } -void __devinit smp_prepare_boot_cpu(void) +void smp_prepare_boot_cpu(void) { /* PGD pointer has moved after per_cpu initialization so * update the MMU. @@ -98,9 +97,9 @@ void __devinit smp_prepare_boot_cpu(void) SUPP_BANK_SEL(2); SUPP_REG_WR(RW_MM_TLB_PGD, pgd); - cpu_set(0, cpu_online_map); - cpu_set(0, phys_cpu_present_map); - cpu_set(0, cpu_possible_map); + set_cpu_online(0, true); + cpumask_set_cpu(0, &phys_cpu_present_map); + set_cpu_possible(0, true); } void __init smp_cpus_done(unsigned int max_cpus) @@ -109,16 +108,12 @@ void __init smp_cpus_done(unsigned int max_cpus) /* Bring one cpu online.*/ static int __init -smp_boot_one_cpu(int cpuid) +smp_boot_one_cpu(int cpuid, struct task_struct idle) { unsigned timeout; - struct task_struct *idle; - cpumask_t cpu_mask = CPU_MASK_NONE; - - idle = fork_idle(cpuid); - if (IS_ERR(idle)) - panic("SMP: fork failed for CPU:%d", cpuid); + cpumask_t cpu_mask; + cpumask_clear(&cpu_mask); task_thread_info(idle)->cpu = cpuid; /* Information to the CPU that is about to boot */ @@ -126,10 +121,10 @@ smp_boot_one_cpu(int cpuid) cpu_now_booting = cpuid; /* Kick it */ - cpu_set(cpuid, cpu_online_map); - cpu_set(cpuid, cpu_mask); + set_cpu_online(cpuid, true); + cpumask_set_cpu(cpuid, &cpu_mask); send_ipi(IPI_BOOT, 0, cpu_mask); - cpu_clear(cpuid, cpu_online_map); + set_cpu_online(cpuid, false); /* Wait for CPU to come online */ for (timeout = 0; timeout < 10000; timeout++) { @@ -142,9 +137,6 @@ smp_boot_one_cpu(int cpuid) barrier(); } - put_task_struct(idle); - idle = NULL; - printk(KERN_CRIT "SMP: CPU:%d is stuck.\n", cpuid); return -1; } @@ -153,8 +145,6 @@ smp_boot_one_cpu(int cpuid) * specific stuff such as the local timer and the MMU. */ void __init smp_callin(void) { - extern void cpu_idle(void); - int cpu = cpu_now_booting; reg_intr_vect_rw_mask vect_mask = {0}; @@ -171,14 +161,14 @@ void __init smp_callin(void) /* Enable IRQ and idle */ REG_WR(intr_vect, irq_regs[cpu], rw_mask, vect_mask); - unmask_irq(IPI_INTR_VECT); - unmask_irq(TIMER0_INTR_VECT); + crisv32_unmask_irq(IPI_INTR_VECT); + crisv32_unmask_irq(TIMER0_INTR_VECT); preempt_disable(); notify_cpu_starting(cpu); local_irq_enable(); - cpu_set(cpu, cpu_online_map); - cpu_idle(); + set_cpu_online(cpu, true); + cpu_startup_entry(CPUHP_ONLINE); } /* Stop execution on this CPU.*/ @@ -207,16 +197,17 @@ int setup_profiling_timer(unsigned int multiplier) */ unsigned long cache_decay_ticks = 1; -int __cpuinit __cpu_up(unsigned int cpu) +int __cpu_up(unsigned int cpu, struct task_struct *tidle) { - smp_boot_one_cpu(cpu); + smp_boot_one_cpu(cpu, tidle); return cpu_online(cpu) ? 0 : -ENOSYS; } void smp_send_reschedule(int cpu) { - cpumask_t cpu_mask = CPU_MASK_NONE; - cpu_set(cpu, cpu_mask); + cpumask_t cpu_mask; + cpumask_clear(&cpu_mask); + cpumask_set_cpu(cpu, &cpu_mask); send_ipi(IPI_SCHEDULE, 0, cpu_mask); } @@ -232,8 +223,8 @@ void flush_tlb_common(struct mm_struct* mm, struct vm_area_struct* vma, unsigned cpumask_t cpu_mask; spin_lock_irqsave(&tlbstate_lock, flags); - cpu_mask = (mm == FLUSH_ALL ? CPU_MASK_ALL : mm->cpu_vm_mask); - cpu_clear(smp_processor_id(), cpu_mask); + cpu_mask = (mm == FLUSH_ALL ? cpu_all_mask : *mm_cpumask(mm)); + cpumask_clear_cpu(smp_processor_id(), &cpu_mask); flush_mm = mm; flush_vma = vma; flush_addr = addr; @@ -252,8 +243,8 @@ void flush_tlb_mm(struct mm_struct *mm) __flush_tlb_mm(mm); flush_tlb_common(mm, FLUSH_ALL, 0); /* No more mappings in other CPUs */ - cpus_clear(mm->cpu_vm_mask); - cpu_set(smp_processor_id(), mm->cpu_vm_mask); + cpumask_clear(mm_cpumask(mm)); + cpumask_set_cpu(smp_processor_id(), mm_cpumask(mm)); } void flush_tlb_page(struct vm_area_struct *vma, @@ -278,10 +269,10 @@ int send_ipi(int vector, int wait, cpumask_t cpu_mask) int ret = 0; /* Calculate CPUs to send to. */ - cpus_and(cpu_mask, cpu_mask, cpu_online_map); + cpumask_and(&cpu_mask, &cpu_mask, cpu_online_mask); /* Send the IPI. */ - for_each_cpu_mask(i, cpu_mask) + for_each_cpu(i, &cpu_mask) { ipi.vector |= vector; REG_WR(intr_vect, irq_regs[i], rw_ipi, ipi); @@ -289,7 +280,7 @@ int send_ipi(int vector, int wait, cpumask_t cpu_mask) /* Wait for IPI to finish on other CPUS */ if (wait) { - for_each_cpu_mask(i, cpu_mask) { + for_each_cpu(i, &cpu_mask) { int j; for (j = 0 ; j < 1000; j++) { ipi = REG_RD(intr_vect, irq_regs[i], rw_ipi); @@ -315,11 +306,12 @@ int send_ipi(int vector, int wait, cpumask_t cpu_mask) */ int smp_call_function(void (*func)(void *info), void *info, int wait) { - cpumask_t cpu_mask = CPU_MASK_ALL; + cpumask_t cpu_mask; struct call_data_struct data; int ret; - cpu_clear(smp_processor_id(), cpu_mask); + cpumask_setall(&cpu_mask); + cpumask_clear_cpu(smp_processor_id(), &cpu_mask); WARN_ON(irqs_disabled()); @@ -343,15 +335,18 @@ irqreturn_t crisv32_ipi_interrupt(int irq, void *dev_id) ipi = REG_RD(intr_vect, irq_regs[smp_processor_id()], rw_ipi); + if (ipi.vector & IPI_SCHEDULE) { + scheduler_ipi(); + } if (ipi.vector & IPI_CALL) { - func(info); + func(info); } if (ipi.vector & IPI_FLUSH_TLB) { - if (flush_mm == FLUSH_ALL) - __flush_tlb_all(); - else if (flush_vma == FLUSH_ALL) + if (flush_mm == FLUSH_ALL) + __flush_tlb_all(); + else if (flush_vma == FLUSH_ALL) __flush_tlb_mm(flush_mm); - else + else __flush_tlb_page(flush_vma, flush_addr); } diff --git a/arch/cris/arch-v32/kernel/time.c b/arch/cris/arch-v32/kernel/time.c index 3a13dd6e0a9..ee66866538f 100644 --- a/arch/cris/arch-v32/kernel/time.c +++ b/arch/cris/arch-v32/kernel/time.c @@ -1,13 +1,13 @@ /* * linux/arch/cris/arch-v32/kernel/time.c * - * Copyright (C) 2003-2007 Axis Communications AB + * Copyright (C) 2003-2010 Axis Communications AB * */ #include <linux/timex.h> #include <linux/time.h> -#include <linux/jiffies.h> +#include <linux/clocksource.h> #include <linux/interrupt.h> #include <linux/swap.h> #include <linux/sched.h> @@ -18,7 +18,6 @@ #include <asm/signal.h> #include <asm/io.h> #include <asm/delay.h> -#include <asm/rtc.h> #include <asm/irq.h> #include <asm/irq_regs.h> @@ -36,6 +35,28 @@ /* Number of 763 counts before watchdog bites */ #define ETRAX_WD_CNT ((2*ETRAX_WD_HZ)/HZ + 1) +/* Register the continuos readonly timer available in FS and ARTPEC-3. */ +static cycle_t read_cont_rotime(struct clocksource *cs) +{ + return (u32)REG_RD(timer, regi_timer0, r_time); +} + +static struct clocksource cont_rotime = { + .name = "crisv32_rotime", + .rating = 300, + .read = read_cont_rotime, + .mask = CLOCKSOURCE_MASK(32), + .flags = CLOCK_SOURCE_IS_CONTINUOUS, +}; + +static int __init etrax_init_cont_rotime(void) +{ + clocksource_register_khz(&cont_rotime, 100000); + return 0; +} +arch_initcall(etrax_init_cont_rotime); + + unsigned long timer_regs[NR_CPUS] = { regi_timer0, @@ -44,10 +65,7 @@ unsigned long timer_regs[NR_CPUS] = #endif }; -extern void update_xtime_from_cmos(void); extern int set_rtc_mmss(unsigned long nowtime); -extern int setup_irq(int, struct irqaction *); -extern int have_rtc; #ifdef CONFIG_CPU_FREQ static int @@ -69,43 +87,6 @@ unsigned long get_ns_in_jiffie(void) return ns; } -unsigned long do_slow_gettimeoffset(void) -{ - unsigned long count; - unsigned long usec_count = 0; - - /* For the first call after boot */ - static unsigned long count_p = TIMER0_DIV; - static unsigned long jiffies_p = 0; - - /* Cache volatile jiffies temporarily; we have IRQs turned off. */ - unsigned long jiffies_t; - - /* The timer interrupt comes from Etrax timer 0. In order to get - * better precision, we check the current value. It might have - * underflowed already though. */ - count = REG_RD(timer, regi_timer0, r_tmr0_data); - jiffies_t = jiffies; - - /* Avoiding timer inconsistencies (they are rare, but they happen) - * There is one problem that must be avoided here: - * 1. the timer counter underflows - */ - if( jiffies_t == jiffies_p ) { - if( count > count_p ) { - /* Timer wrapped, use new count and prescale. - * Increase the time corresponding to one jiffy. - */ - usec_count = 1000000/HZ; - } - } else - jiffies_p = jiffies_t; - count_p = count; - /* Convert timer value to usec */ - /* 100 MHz timer, divide by 100 to get usec */ - usec_count += (TIMER0_DIV - count) / 100; - return usec_count; -} /* From timer MDS describing the hardware watchdog: * 4.3.1 Watchdog Operation @@ -128,8 +109,7 @@ static short int watchdog_key = 42; /* arbitrary 7 bit number */ * is used though, so set this really low. */ #define WATCHDOG_MIN_FREE_PAGES 8 -void -reset_watchdog(void) +void reset_watchdog(void) { #if defined(CONFIG_ETRAX_WATCHDOG) reg_timer_rw_wd_ctrl wd_ctrl = { 0 }; @@ -149,8 +129,7 @@ reset_watchdog(void) /* stop the watchdog - we still need the correct key */ -void -stop_watchdog(void) +void stop_watchdog(void) { #if defined(CONFIG_ETRAX_WATCHDOG) reg_timer_rw_wd_ctrl wd_ctrl = { 0 }; @@ -164,8 +143,7 @@ stop_watchdog(void) extern void show_registers(struct pt_regs *regs); -void -handle_watchdog_bite(struct pt_regs* regs) +void handle_watchdog_bite(struct pt_regs *regs) { #if defined(CONFIG_ETRAX_WATCHDOG) extern int cause_of_death; @@ -199,17 +177,13 @@ handle_watchdog_bite(struct pt_regs* regs) #endif } -/* Last time the cmos clock got updated. */ -static long last_rtc_update = 0; - /* * timer_interrupt() needs to keep up the real-time clock, - * as well as call the "do_timer()" routine every clocktick. + * as well as call the "xtime_update()" routine every clocktick. */ extern void cris_do_profile(struct pt_regs *regs); -static inline irqreturn_t -timer_interrupt(int irq, void *dev_id) +static inline irqreturn_t timer_interrupt(int irq, void *dev_id) { struct pt_regs *regs = get_irq_regs(); int cpu = smp_processor_id(); @@ -238,41 +212,18 @@ timer_interrupt(int irq, void *dev_id) return IRQ_HANDLED; /* Call the real timer interrupt handler */ - do_timer(1); - - /* - * If we have an externally synchronized Linux clock, then update - * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be - * called as close as possible to 500 ms before the new second starts. - * - * The division here is not time critical since it will run once in - * 11 minutes - */ - if ((time_status & STA_UNSYNC) == 0 && - xtime.tv_sec > last_rtc_update + 660 && - (xtime.tv_nsec / 1000) >= 500000 - (tick_nsec / 1000) / 2 && - (xtime.tv_nsec / 1000) <= 500000 + (tick_nsec / 1000) / 2) { - if (set_rtc_mmss(xtime.tv_sec) == 0) - last_rtc_update = xtime.tv_sec; - else - /* Do it again in 60 s */ - last_rtc_update = xtime.tv_sec - 600; - } + xtime_update(1); return IRQ_HANDLED; } -/* Timer is IRQF_SHARED so drivers can add stuff to the timer irq chain. - * It needs to be IRQF_DISABLED to make the jiffies update work properly. - */ +/* Timer is IRQF_SHARED so drivers can add stuff to the timer irq chain. */ static struct irqaction irq_timer = { .handler = timer_interrupt, - .flags = IRQF_SHARED | IRQF_DISABLED, - .mask = CPU_MASK_NONE, + .flags = IRQF_SHARED, .name = "timer" }; -void __init -cris_timer_init(void) +void __init cris_timer_init(void) { int cpu = smp_processor_id(); reg_timer_rw_tmr0_ctrl tmr0_ctrl = { 0 }; @@ -298,8 +249,7 @@ cris_timer_init(void) REG_WR(timer, timer_regs[cpu], rw_intr_mask, timer_intr_mask); } -void __init -time_init(void) +void __init time_init(void) { reg_intr_vect_rw_mask intr_mask; @@ -311,24 +261,6 @@ time_init(void) */ loops_per_usec = 50; - if(RTC_INIT() < 0) { - /* No RTC, start at 1980 */ - xtime.tv_sec = 0; - xtime.tv_nsec = 0; - have_rtc = 0; - } else { - /* Get the current time */ - have_rtc = 1; - update_xtime_from_cmos(); - } - - /* - * Initialize wall_to_monotonic such that adding it to - * xtime will yield zero, the tv_nsec field must be normalized - * (i.e., 0 <= nsec < NSEC_PER_SEC). - */ - set_normalized_timespec(&wall_to_monotonic, -xtime.tv_sec, -xtime.tv_nsec); - /* Start CPU local timer. */ cris_timer_init(); diff --git a/arch/cris/arch-v32/kernel/traps.c b/arch/cris/arch-v32/kernel/traps.c index 9003e382cad..8bbe09c9313 100644 --- a/arch/cris/arch-v32/kernel/traps.c +++ b/arch/cris/arch-v32/kernel/traps.c @@ -9,8 +9,7 @@ #include <hwregs/intr_vect_defs.h> #include <asm/irq.h> -void -show_registers(struct pt_regs *regs) +void show_registers(struct pt_regs *regs) { /* * It's possible to use either the USP register or current->thread.usp. @@ -101,8 +100,7 @@ bad_value: } } -void -arch_enable_nmi(void) +void arch_enable_nmi(void) { unsigned long flags; |
