Blackfin arch: merge adeos blackfin part to arch/blackfin/
authorYi Li <yi.li@analog.com>
Wed, 7 Jan 2009 15:14:39 +0000 (23:14 +0800)
committerBryan Wu <cooloney@kernel.org>
Wed, 7 Jan 2009 15:14:39 +0000 (23:14 +0800)
[Mike Frysinger <vapier.adi@gmail.com>:
 - handle bf531/bf532/bf534/bf536 variants in ipipe.h
 - cleanup IPIPE logic for bfin_set_irq_handler()
 - cleanup ipipe asm code a bit and add missing ENDPROC()
 - simplify IPIPE code in trap_c
 - unify some of the IPIPE code and fix style
 - simplify DO_IRQ_L1 handling with ipipe code
 - revert IRQ_SW_INT# addition from ipipe merge
 - remove duplicate get_{c,s}clk() prototypes
]

Signed-off-by: Yi Li <yi.li@analog.com>
Signed-off-by: Mike Frysinger <vapier.adi@gmail.com>
Signed-off-by: Bryan Wu <cooloney@kernel.org>
58 files changed:
arch/blackfin/configs/BF518F-EZBRD_defconfig
arch/blackfin/configs/BF526-EZBRD_defconfig
arch/blackfin/configs/BF527-EZKIT_defconfig
arch/blackfin/configs/BF537-STAMP_defconfig
arch/blackfin/configs/BF538-EZKIT_defconfig
arch/blackfin/configs/CM-BF527_defconfig
arch/blackfin/configs/CM-BF537E_defconfig
arch/blackfin/configs/CM-BF537U_defconfig
arch/blackfin/configs/PNAV-10_defconfig
arch/blackfin/configs/SRV1_defconfig
arch/blackfin/configs/TCM-BF537_defconfig
arch/blackfin/include/asm/atomic.h
arch/blackfin/include/asm/bitops.h
arch/blackfin/include/asm/entry.h
arch/blackfin/include/asm/ipipe.h [new file with mode: 0644]
arch/blackfin/include/asm/ipipe_base.h [new file with mode: 0644]
arch/blackfin/include/asm/irq.h
arch/blackfin/include/asm/system.h
arch/blackfin/kernel/Makefile
arch/blackfin/kernel/bfin_gpio.c
arch/blackfin/kernel/cplb-mpu/cplbmgr.c
arch/blackfin/kernel/entry.S
arch/blackfin/kernel/ipipe.c [new file with mode: 0644]
arch/blackfin/kernel/irqchip.c
arch/blackfin/kernel/mcount.S [new file with mode: 0644]
arch/blackfin/kernel/process.c
arch/blackfin/kernel/time.c
arch/blackfin/kernel/traps.c
arch/blackfin/lib/ins.S
arch/blackfin/mach-bf518/Kconfig
arch/blackfin/mach-bf518/include/mach/cdefBF51x_base.h
arch/blackfin/mach-bf518/include/mach/irq.h
arch/blackfin/mach-bf518/ints-priority.c
arch/blackfin/mach-bf527/Kconfig
arch/blackfin/mach-bf527/include/mach/cdefBF52x_base.h
arch/blackfin/mach-bf527/include/mach/irq.h
arch/blackfin/mach-bf527/ints-priority.c
arch/blackfin/mach-bf533/Kconfig
arch/blackfin/mach-bf533/include/mach/cdefBF532.h
arch/blackfin/mach-bf533/include/mach/irq.h
arch/blackfin/mach-bf537/Kconfig
arch/blackfin/mach-bf537/include/mach/cdefBF534.h
arch/blackfin/mach-bf537/include/mach/irq.h
arch/blackfin/mach-bf537/ints-priority.c
arch/blackfin/mach-bf538/Kconfig
arch/blackfin/mach-bf538/include/mach/cdefBF538.h
arch/blackfin/mach-bf538/include/mach/irq.h
arch/blackfin/mach-bf538/ints-priority.c
arch/blackfin/mach-bf548/Kconfig
arch/blackfin/mach-bf548/include/mach/cdefBF54x_base.h
arch/blackfin/mach-bf548/include/mach/irq.h
arch/blackfin/mach-bf561/Kconfig
arch/blackfin/mach-bf561/include/mach/cdefBF561.h
arch/blackfin/mach-common/cpufreq.c
arch/blackfin/mach-common/interrupt.S
arch/blackfin/mach-common/ints-priority.c
arch/blackfin/mach-common/pm.c
arch/blackfin/mach-common/smp.c

index 98cf7c3..699781c 100644 (file)
@@ -204,14 +204,14 @@ CONFIG_IRQ_MAC_RX=11
 CONFIG_IRQ_PORTH_INTA=11
 CONFIG_IRQ_MAC_TX=11
 CONFIG_IRQ_PORTH_INTB=11
-CONFIG_IRQ_TMR0=12
-CONFIG_IRQ_TMR1=12
-CONFIG_IRQ_TMR2=12
-CONFIG_IRQ_TMR3=12
-CONFIG_IRQ_TMR4=12
-CONFIG_IRQ_TMR5=12
-CONFIG_IRQ_TMR6=12
-CONFIG_IRQ_TMR7=12
+CONFIG_IRQ_TIMER0=12
+CONFIG_IRQ_TIMER1=12
+CONFIG_IRQ_TIMER2=12
+CONFIG_IRQ_TIMER3=12
+CONFIG_IRQ_TIMER4=12
+CONFIG_IRQ_TIMER5=12
+CONFIG_IRQ_TIMER6=12
+CONFIG_IRQ_TIMER7=12
 CONFIG_IRQ_PORTG_INTA=12
 CONFIG_IRQ_PORTG_INTB=12
 CONFIG_IRQ_MEM_DMA0=13
index 667af6b..6dfcd27 100644 (file)
@@ -199,14 +199,14 @@ CONFIG_IRQ_MAC_RX=11
 CONFIG_IRQ_PORTH_INTA=11
 CONFIG_IRQ_MAC_TX=11
 CONFIG_IRQ_PORTH_INTB=11
-CONFIG_IRQ_TMR0=12
-CONFIG_IRQ_TMR1=12
-CONFIG_IRQ_TMR2=12
-CONFIG_IRQ_TMR3=12
-CONFIG_IRQ_TMR4=12
-CONFIG_IRQ_TMR5=12
-CONFIG_IRQ_TMR6=12
-CONFIG_IRQ_TMR7=12
+CONFIG_IRQ_TIMER0=12
+CONFIG_IRQ_TIMER1=12
+CONFIG_IRQ_TIMER2=12
+CONFIG_IRQ_TIMER3=12
+CONFIG_IRQ_TIMER4=12
+CONFIG_IRQ_TIMER5=12
+CONFIG_IRQ_TIMER6=12
+CONFIG_IRQ_TIMER7=12
 CONFIG_IRQ_PORTG_INTA=12
 CONFIG_IRQ_PORTG_INTB=12
 CONFIG_IRQ_MEM_DMA0=13
index 70b50d0..2947dcb 100644 (file)
@@ -188,14 +188,14 @@ CONFIG_IRQ_MAC_RX=11
 CONFIG_IRQ_PORTH_INTA=11
 CONFIG_IRQ_MAC_TX=11
 CONFIG_IRQ_PORTH_INTB=11
-CONFIG_IRQ_TMR0=12
-CONFIG_IRQ_TMR1=12
-CONFIG_IRQ_TMR2=12
-CONFIG_IRQ_TMR3=12
-CONFIG_IRQ_TMR4=12
-CONFIG_IRQ_TMR5=12
-CONFIG_IRQ_TMR6=12
-CONFIG_IRQ_TMR7=12
+CONFIG_IRQ_TIMER0=8
+CONFIG_IRQ_TIMER1=12
+CONFIG_IRQ_TIMER2=12
+CONFIG_IRQ_TIMER3=12
+CONFIG_IRQ_TIMER4=12
+CONFIG_IRQ_TIMER5=12
+CONFIG_IRQ_TIMER6=12
+CONFIG_IRQ_TIMER7=12
 CONFIG_IRQ_PORTG_INTA=12
 CONFIG_IRQ_PORTG_INTB=12
 CONFIG_IRQ_MEM_DMA0=13
index ed84c62..4aa6687 100644 (file)
@@ -148,14 +148,14 @@ CONFIG_IRQ_UART1_RX=10
 CONFIG_IRQ_UART1_TX=10
 CONFIG_IRQ_MAC_RX=11
 CONFIG_IRQ_MAC_TX=11
-CONFIG_IRQ_TMR0=12
-CONFIG_IRQ_TMR1=12
-CONFIG_IRQ_TMR2=12
-CONFIG_IRQ_TMR3=12
-CONFIG_IRQ_TMR4=12
-CONFIG_IRQ_TMR5=12
-CONFIG_IRQ_TMR6=12
-CONFIG_IRQ_TMR7=12
+CONFIG_IRQ_TIMER0=8
+CONFIG_IRQ_TIMER1=12
+CONFIG_IRQ_TIMER2=12
+CONFIG_IRQ_TIMER3=12
+CONFIG_IRQ_TIMER4=12
+CONFIG_IRQ_TIMER5=12
+CONFIG_IRQ_TIMER6=12
+CONFIG_IRQ_TIMER7=12
 CONFIG_IRQ_PORTG_INTB=12
 CONFIG_IRQ_MEM_DMA0=13
 CONFIG_IRQ_MEM_DMA1=13
index f1d2b36..baf33e6 100644 (file)
@@ -163,9 +163,9 @@ CONFIG_IRQ_UART0_RX=10
 CONFIG_IRQ_UART0_TX=10
 CONFIG_IRQ_UART1_RX=10
 CONFIG_IRQ_UART1_TX=10
-CONFIG_IRQ_TMR0=12
-CONFIG_IRQ_TMR1=12
-CONFIG_IRQ_TMR2=12
+CONFIG_IRQ_TIMER0=12
+CONFIG_IRQ_TIMER1=12
+CONFIG_IRQ_TIMER2=12
 CONFIG_IRQ_WATCH=13
 CONFIG_IRQ_PORTF_INTA=12
 CONFIG_IRQ_PORTF_INTB=12
index 0043da5..7195385 100644 (file)
@@ -190,14 +190,14 @@ CONFIG_IRQ_MAC_RX=11
 CONFIG_IRQ_PORTH_INTA=11
 CONFIG_IRQ_MAC_TX=11
 CONFIG_IRQ_PORTH_INTB=11
-CONFIG_IRQ_TMR0=12
-CONFIG_IRQ_TMR1=12
-CONFIG_IRQ_TMR2=12
-CONFIG_IRQ_TMR3=12
-CONFIG_IRQ_TMR4=12
-CONFIG_IRQ_TMR5=12
-CONFIG_IRQ_TMR6=12
-CONFIG_IRQ_TMR7=12
+CONFIG_IRQ_TIMER0=12
+CONFIG_IRQ_TIMER1=12
+CONFIG_IRQ_TIMER2=12
+CONFIG_IRQ_TIMER3=12
+CONFIG_IRQ_TIMER4=12
+CONFIG_IRQ_TIMER5=12
+CONFIG_IRQ_TIMER6=12
+CONFIG_IRQ_TIMER7=12
 CONFIG_IRQ_PORTG_INTA=12
 CONFIG_IRQ_PORTG_INTB=12
 CONFIG_IRQ_MEM_DMA0=13
index 1b50d38..cbf4803 100644 (file)
@@ -157,14 +157,14 @@ CONFIG_IRQ_UART1_RX=10
 CONFIG_IRQ_UART1_TX=10
 CONFIG_IRQ_MAC_RX=11
 CONFIG_IRQ_MAC_TX=11
-CONFIG_IRQ_TMR0=12
-CONFIG_IRQ_TMR1=12
-CONFIG_IRQ_TMR2=12
-CONFIG_IRQ_TMR3=12
-CONFIG_IRQ_TMR4=12
-CONFIG_IRQ_TMR5=12
-CONFIG_IRQ_TMR6=12
-CONFIG_IRQ_TMR7=12
+CONFIG_IRQ_TIMER0=12
+CONFIG_IRQ_TIMER1=12
+CONFIG_IRQ_TIMER2=12
+CONFIG_IRQ_TIMER3=12
+CONFIG_IRQ_TIMER4=12
+CONFIG_IRQ_TIMER5=12
+CONFIG_IRQ_TIMER6=12
+CONFIG_IRQ_TIMER7=12
 CONFIG_IRQ_PORTG_INTB=12
 CONFIG_IRQ_MEM_DMA0=13
 CONFIG_IRQ_MEM_DMA1=13
index 2ca768d..f2ac0cc 100644 (file)
@@ -157,14 +157,14 @@ CONFIG_IRQ_UART1_RX=10
 CONFIG_IRQ_UART1_TX=10
 CONFIG_IRQ_MAC_RX=11
 CONFIG_IRQ_MAC_TX=11
-CONFIG_IRQ_TMR0=12
-CONFIG_IRQ_TMR1=12
-CONFIG_IRQ_TMR2=12
-CONFIG_IRQ_TMR3=12
-CONFIG_IRQ_TMR4=12
-CONFIG_IRQ_TMR5=12
-CONFIG_IRQ_TMR6=12
-CONFIG_IRQ_TMR7=12
+CONFIG_IRQ_TIMER0=12
+CONFIG_IRQ_TIMER1=12
+CONFIG_IRQ_TIMER2=12
+CONFIG_IRQ_TIMER3=12
+CONFIG_IRQ_TIMER4=12
+CONFIG_IRQ_TIMER5=12
+CONFIG_IRQ_TIMER6=12
+CONFIG_IRQ_TIMER7=12
 CONFIG_IRQ_PORTG_INTB=12
 CONFIG_IRQ_MEM_DMA0=13
 CONFIG_IRQ_MEM_DMA1=13
index 648edd9..834fb8c 100644 (file)
@@ -153,14 +153,14 @@ CONFIG_IRQ_UART1_RX=10
 CONFIG_IRQ_UART1_TX=10
 CONFIG_IRQ_MAC_RX=11
 CONFIG_IRQ_MAC_TX=11
-CONFIG_IRQ_TMR0=12
-CONFIG_IRQ_TMR1=12
-CONFIG_IRQ_TMR2=12
-CONFIG_IRQ_TMR3=12
-CONFIG_IRQ_TMR4=12
-CONFIG_IRQ_TMR5=12
-CONFIG_IRQ_TMR6=12
-CONFIG_IRQ_TMR7=12
+CONFIG_IRQ_TIMER0=12
+CONFIG_IRQ_TIMER1=12
+CONFIG_IRQ_TIMER2=12
+CONFIG_IRQ_TIMER3=12
+CONFIG_IRQ_TIMER4=12
+CONFIG_IRQ_TIMER5=12
+CONFIG_IRQ_TIMER6=12
+CONFIG_IRQ_TIMER7=12
 CONFIG_IRQ_PORTG_INTB=12
 CONFIG_IRQ_MEM_DMA0=13
 CONFIG_IRQ_MEM_DMA1=13
index ffa2396..010f0aa 100644 (file)
@@ -172,14 +172,14 @@ CONFIG_IRQ_UART1_RX=10
 CONFIG_IRQ_UART1_TX=10
 CONFIG_IRQ_MAC_RX=11
 CONFIG_IRQ_MAC_TX=11
-CONFIG_IRQ_TMR0=12
-CONFIG_IRQ_TMR1=12
-CONFIG_IRQ_TMR2=12
-CONFIG_IRQ_TMR3=12
-CONFIG_IRQ_TMR4=12
-CONFIG_IRQ_TMR5=12
-CONFIG_IRQ_TMR6=12
-CONFIG_IRQ_TMR7=12
+CONFIG_IRQ_TIMER0=12
+CONFIG_IRQ_TIMER1=12
+CONFIG_IRQ_TIMER2=12
+CONFIG_IRQ_TIMER3=12
+CONFIG_IRQ_TIMER4=12
+CONFIG_IRQ_TIMER5=12
+CONFIG_IRQ_TIMER6=12
+CONFIG_IRQ_TIMER7=12
 CONFIG_IRQ_PORTG_INTB=12
 CONFIG_IRQ_MEM_DMA0=13
 CONFIG_IRQ_MEM_DMA1=13
index 6431192..0ba4aa8 100644 (file)
@@ -144,14 +144,14 @@ CONFIG_IRQ_UART1_RX=10
 CONFIG_IRQ_UART1_TX=10
 CONFIG_IRQ_MAC_RX=11
 CONFIG_IRQ_MAC_TX=11
-CONFIG_IRQ_TMR0=12
-CONFIG_IRQ_TMR1=12
-CONFIG_IRQ_TMR2=12
-CONFIG_IRQ_TMR3=12
-CONFIG_IRQ_TMR4=12
-CONFIG_IRQ_TMR5=12
-CONFIG_IRQ_TMR6=12
-CONFIG_IRQ_TMR7=12
+CONFIG_IRQ_TIMER0=12
+CONFIG_IRQ_TIMER1=12
+CONFIG_IRQ_TIMER2=12
+CONFIG_IRQ_TIMER3=12
+CONFIG_IRQ_TIMER4=12
+CONFIG_IRQ_TIMER5=12
+CONFIG_IRQ_TIMER6=12
+CONFIG_IRQ_TIMER7=12
 CONFIG_IRQ_PORTG_INTB=12
 CONFIG_IRQ_MEM_DMA0=13
 CONFIG_IRQ_MEM_DMA1=13
index d76275e..94b2a9b 100644 (file)
@@ -92,18 +92,18 @@ static inline void atomic_add(int i, atomic_t *v)
 {
        long flags;
 
-       local_irq_save(flags);
+       local_irq_save_hw(flags);
        v->counter += i;
-       local_irq_restore(flags);
+       local_irq_restore_hw(flags);
 }
 
 static inline void atomic_sub(int i, atomic_t *v)
 {
        long flags;
 
-       local_irq_save(flags);
+       local_irq_save_hw(flags);
        v->counter -= i;
-       local_irq_restore(flags);
+       local_irq_restore_hw(flags);
 
 }
 
@@ -112,10 +112,10 @@ static inline int atomic_add_return(int i, atomic_t *v)
        int __temp = 0;
        long flags;
 
-       local_irq_save(flags);
+       local_irq_save_hw(flags);
        v->counter += i;
        __temp = v->counter;
-       local_irq_restore(flags);
+       local_irq_restore_hw(flags);
 
 
        return __temp;
@@ -126,10 +126,10 @@ static inline int atomic_sub_return(int i, atomic_t *v)
        int __temp = 0;
        long flags;
 
-       local_irq_save(flags);
+       local_irq_save_hw(flags);
        v->counter -= i;
        __temp = v->counter;
-       local_irq_restore(flags);
+       local_irq_restore_hw(flags);
 
        return __temp;
 }
@@ -138,36 +138,36 @@ static inline void atomic_inc(volatile atomic_t *v)
 {
        long flags;
 
-       local_irq_save(flags);
+       local_irq_save_hw(flags);
        v->counter++;
-       local_irq_restore(flags);
+       local_irq_restore_hw(flags);
 }
 
 static inline void atomic_dec(volatile atomic_t *v)
 {
        long flags;
 
-       local_irq_save(flags);
+       local_irq_save_hw(flags);
        v->counter--;
-       local_irq_restore(flags);
+       local_irq_restore_hw(flags);
 }
 
 static inline void atomic_clear_mask(unsigned int mask, atomic_t *v)
 {
        long flags;
 
-       local_irq_save(flags);
+       local_irq_save_hw(flags);
        v->counter &= ~mask;
-       local_irq_restore(flags);
+       local_irq_restore_hw(flags);
 }
 
 static inline void atomic_set_mask(unsigned int mask, atomic_t *v)
 {
        long flags;
 
-       local_irq_save(flags);
+       local_irq_save_hw(flags);
        v->counter |= mask;
-       local_irq_restore(flags);
+       local_irq_restore_hw(flags);
 }
 
 /* Atomic operations are already serializing */
index 9964e17..21b036e 100644 (file)
@@ -90,9 +90,9 @@ static inline void set_bit(int nr, volatile unsigned long *addr)
        unsigned long flags;
        a += nr >> 5;
        mask = 1 << (nr & 0x1f);
-       local_irq_save(flags);
+       local_irq_save_hw(flags);
        *a |= mask;
-       local_irq_restore(flags);
+       local_irq_restore_hw(flags);
 }
 
 static inline void clear_bit(int nr, volatile unsigned long *addr)
@@ -102,9 +102,9 @@ static inline void clear_bit(int nr, volatile unsigned long *addr)
        unsigned long flags;
        a += nr >> 5;
        mask = 1 << (nr & 0x1f);
-       local_irq_save(flags);
+       local_irq_save_hw(flags);
        *a &= ~mask;
-       local_irq_restore(flags);
+       local_irq_restore_hw(flags);
 }
 
 static inline void change_bit(int nr, volatile unsigned long *addr)
@@ -114,9 +114,9 @@ static inline void change_bit(int nr, volatile unsigned long *addr)
 
        ADDR += nr >> 5;
        mask = 1 << (nr & 31);
-       local_irq_save(flags);
+       local_irq_save_hw(flags);
        *ADDR ^= mask;
-       local_irq_restore(flags);
+       local_irq_restore_hw(flags);
 }
 
 static inline int test_and_set_bit(int nr, volatile unsigned long *addr)
@@ -127,10 +127,10 @@ static inline int test_and_set_bit(int nr, volatile unsigned long *addr)
 
        a += nr >> 5;
        mask = 1 << (nr & 0x1f);
-       local_irq_save(flags);
+       local_irq_save_hw(flags);
        retval = (mask & *a) != 0;
        *a |= mask;
-       local_irq_restore(flags);
+       local_irq_restore_hw(flags);
 
        return retval;
 }
@@ -143,10 +143,10 @@ static inline int test_and_clear_bit(int nr, volatile unsigned long *addr)
 
        a += nr >> 5;
        mask = 1 << (nr & 0x1f);
-       local_irq_save(flags);
+       local_irq_save_hw(flags);
        retval = (mask & *a) != 0;
        *a &= ~mask;
-       local_irq_restore(flags);
+       local_irq_restore_hw(flags);
 
        return retval;
 }
@@ -159,10 +159,10 @@ static inline int test_and_change_bit(int nr, volatile unsigned long *addr)
 
        a += nr >> 5;
        mask = 1 << (nr & 0x1f);
-       local_irq_save(flags);
+       local_irq_save_hw(flags);
        retval = (mask & *a) != 0;
        *a ^= mask;
-       local_irq_restore(flags);
+       local_irq_restore_hw(flags);
        return retval;
 }
 
index d94e4f5..b30a296 100644 (file)
 #define SAVE_ALL_SYS           save_context_no_interrupts
 /* This is used for all normal interrupts.  It saves a minimum of registers
    to the stack, loads the IRQ number, and jumps to common code.  */
+#ifdef CONFIG_IPIPE
+# define LOAD_IPIPE_IPEND \
+       P0.l = lo(IPEND); \
+       P0.h = hi(IPEND); \
+       R1 = [P0];
+#else
+# define LOAD_IPIPE_IPEND
+#endif
 #define INTERRUPT_ENTRY(N)                                             \
     [--sp] = SYSCFG;                                                   \
                                                                        \
@@ -34,6 +42,7 @@
     [--sp] = R0;       /*orig_r0*/                                     \
     [--sp] = (R7:0,P5:0);                                              \
     R0 = (N);                                                          \
+    LOAD_IPIPE_IPEND                                                   \
     jump __common_int_entry;
 
 /* For timer interrupts, we need to save IPEND, since the user_mode
diff --git a/arch/blackfin/include/asm/ipipe.h b/arch/blackfin/include/asm/ipipe.h
new file mode 100644 (file)
index 0000000..76f53d8
--- /dev/null
@@ -0,0 +1,278 @@
+/*   -*- linux-c -*-
+ *   include/asm-blackfin/ipipe.h
+ *
+ *   Copyright (C) 2002-2007 Philippe Gerum.
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139,
+ *   USA; either version 2 of the License, or (at your option) any later
+ *   version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __ASM_BLACKFIN_IPIPE_H
+#define __ASM_BLACKFIN_IPIPE_H
+
+#ifdef CONFIG_IPIPE
+
+#include <linux/cpumask.h>
+#include <linux/list.h>
+#include <linux/threads.h>
+#include <linux/irq.h>
+#include <linux/ipipe_percpu.h>
+#include <asm/ptrace.h>
+#include <asm/irq.h>
+#include <asm/bitops.h>
+#include <asm/atomic.h>
+#include <asm/traps.h>
+
+#define IPIPE_ARCH_STRING     "1.8-00"
+#define IPIPE_MAJOR_NUMBER    1
+#define IPIPE_MINOR_NUMBER    8
+#define IPIPE_PATCH_NUMBER    0
+
+#ifdef CONFIG_SMP
+#error "I-pipe/blackfin: SMP not implemented"
+#else /* !CONFIG_SMP */
+#define ipipe_processor_id()   0
+#endif /* CONFIG_SMP */
+
+#define prepare_arch_switch(next)              \
+do {                                           \
+       ipipe_schedule_notify(current, next);   \
+       local_irq_disable_hw();                 \
+} while (0)
+
+#define task_hijacked(p)                                               \
+       ({                                                              \
+               int __x__ = ipipe_current_domain != ipipe_root_domain;  \
+               /* We would need to clear the SYNC flag for the root domain */ \
+               /* over the current processor in SMP mode. */           \
+               local_irq_enable_hw(); __x__;                           \
+       })
+
+struct ipipe_domain;
+
+struct ipipe_sysinfo {
+
+       int ncpus;              /* Number of CPUs on board */
+       u64 cpufreq;            /* CPU frequency (in Hz) */
+
+       /* Arch-dependent block */
+
+       struct {
+               unsigned tmirq; /* Timer tick IRQ */
+               u64 tmfreq;     /* Timer frequency */
+       } archdep;
+};
+
+#define ipipe_read_tsc(t)                                      \
+       ({                                                      \
+       unsigned long __cy2;                                    \
+       __asm__ __volatile__ ("1: %0 = CYCLES2\n"               \
+                               "%1 = CYCLES\n"                 \
+                               "%2 = CYCLES2\n"                \
+                               "CC = %2 == %0\n"               \
+                               "if ! CC jump 1b\n"             \
+                               : "=r" (((unsigned long *)&t)[1]),      \
+                                 "=r" (((unsigned long *)&t)[0]),      \
+                                 "=r" (__cy2)                          \
+                               : /*no input*/ : "CC");                 \
+       t;                                                              \
+       })
+
+#define ipipe_cpu_freq()       __ipipe_core_clock
+#define ipipe_tsc2ns(_t)       (((unsigned long)(_t)) * __ipipe_freq_scale)
+#define ipipe_tsc2us(_t)       (ipipe_tsc2ns(_t) / 1000 + 1)
+
+/* Private interface -- Internal use only */
+
+#define __ipipe_check_platform()       do { } while (0)
+
+#define __ipipe_init_platform()                do { } while (0)
+
+extern atomic_t __ipipe_irq_lvdepth[IVG15 + 1];
+
+extern unsigned long __ipipe_irq_lvmask;
+
+extern struct ipipe_domain ipipe_root;
+
+/* enable/disable_irqdesc _must_ be used in pairs. */
+
+void __ipipe_enable_irqdesc(struct ipipe_domain *ipd,
+                           unsigned irq);
+
+void __ipipe_disable_irqdesc(struct ipipe_domain *ipd,
+                            unsigned irq);
+
+#define __ipipe_enable_irq(irq)                (irq_desc[irq].chip->unmask(irq))
+
+#define __ipipe_disable_irq(irq)       (irq_desc[irq].chip->mask(irq))
+
+#define __ipipe_lock_root()                                    \
+       set_bit(IPIPE_ROOTLOCK_FLAG, &ipipe_root_domain->flags)
+
+#define __ipipe_unlock_root()                                  \
+       clear_bit(IPIPE_ROOTLOCK_FLAG, &ipipe_root_domain->flags)
+
+void __ipipe_enable_pipeline(void);
+
+#define __ipipe_hook_critical_ipi(ipd) do { } while (0)
+
+#define __ipipe_sync_pipeline(syncmask)                                        \
+       do {                                                            \
+               struct ipipe_domain *ipd = ipipe_current_domain;        \
+               if (likely(ipd != ipipe_root_domain || !test_bit(IPIPE_ROOTLOCK_FLAG, &ipd->flags))) \
+                       __ipipe_sync_stage(syncmask);                   \
+       } while (0)
+
+void __ipipe_handle_irq(unsigned irq, struct pt_regs *regs);
+
+int __ipipe_get_irq_priority(unsigned irq);
+
+int __ipipe_get_irqthread_priority(unsigned irq);
+
+void __ipipe_stall_root_raw(void);
+
+void __ipipe_unstall_root_raw(void);
+
+void __ipipe_serial_debug(const char *fmt, ...);
+
+DECLARE_PER_CPU(struct pt_regs, __ipipe_tick_regs);
+
+extern unsigned long __ipipe_core_clock;
+
+extern unsigned long __ipipe_freq_scale;
+
+extern unsigned long __ipipe_irq_tail_hook;
+
+static inline unsigned long __ipipe_ffnz(unsigned long ul)
+{
+       return ffs(ul) - 1;
+}
+
+#define __ipipe_run_irqtail()  /* Must be a macro */                   \
+       do {                                                            \
+               asmlinkage void __ipipe_call_irqtail(void);             \
+               unsigned long __pending;                                \
+               CSYNC();                                        \
+               __pending = bfin_read_IPEND();                          \
+               if (__pending & 0x8000) {                               \
+                       __pending &= ~0x8010;                           \
+                       if (__pending && (__pending & (__pending - 1)) == 0) \
+                               __ipipe_call_irqtail();                 \
+               }                                                       \
+       } while (0)
+
+#define __ipipe_run_isr(ipd, irq)                                      \
+       do {                                                            \
+               if (ipd == ipipe_root_domain) {                         \
+                       /*                                              \
+                        * Note: the I-pipe implements a threaded interrupt model on \
+                        * this arch for Linux external IRQs. The interrupt handler we \
+                        * call here only wakes up the associated IRQ thread. \
+                        */                                             \
+                       if (ipipe_virtual_irq_p(irq)) {                 \
+                               /* No irqtail here; virtual interrupts have no effect \
+                                  on IPEND so there is no need for processing \
+                                  deferral. */                         \
+                               local_irq_enable_nohead(ipd);           \
+                               ipd->irqs[irq].handler(irq, ipd->irqs[irq].cookie); \
+                               local_irq_disable_nohead(ipd);          \
+                       } else                                          \
+                               /*                                      \
+                                * No need to run the irqtail here either; \
+                                * we can't be preempted by hw IRQs, so \
+                                * non-Linux IRQs cannot stack over the short \
+                                * thread wakeup code. Which in turn means \
+                                * that no irqtail condition could be pending \
+                                * for domains above Linux in the pipeline. \
+                                */                                     \
+                               ipd->irqs[irq].handler(irq, &__raw_get_cpu_var(__ipipe_tick_regs)); \
+               } else {                                                \
+                       __clear_bit(IPIPE_SYNC_FLAG, &ipipe_cpudom_var(ipd, status)); \
+                       local_irq_enable_nohead(ipd);                   \
+                       ipd->irqs[irq].handler(irq, ipd->irqs[irq].cookie); \
+                       /* Attempt to exit the outer interrupt level before \
+                        * starting the deferred IRQ processing. */     \
+                       local_irq_disable_nohead(ipd);                  \
+                       __ipipe_run_irqtail();                          \
+                       __set_bit(IPIPE_SYNC_FLAG, &ipipe_cpudom_var(ipd, status)); \
+               }                                                       \
+       } while (0)
+
+#define __ipipe_syscall_watched_p(p, sc)       \
+       (((p)->flags & PF_EVNOTIFY) || (unsigned long)sc >= NR_syscalls)
+
+void ipipe_init_irq_threads(void);
+
+int ipipe_start_irq_thread(unsigned irq, struct irq_desc *desc);
+
+#define IS_SYSIRQ(irq)         ((irq) > IRQ_CORETMR && (irq) <= SYS_IRQS)
+#define IS_GPIOIRQ(irq)                ((irq) >= GPIO_IRQ_BASE && (irq) < NR_IRQS)
+
+#define IRQ_SYSTMR             IRQ_TIMER0
+#define IRQ_PRIOTMR            CONFIG_IRQ_TIMER0
+
+#if defined(CONFIG_BF531) || defined(CONFIG_BF532) || defined(CONFIG_BF533)
+#define PRIO_GPIODEMUX(irq)    CONFIG_PFA
+#elif defined(CONFIG_BF534) || defined(CONFIG_BF536) || defined(CONFIG_BF537)
+#define PRIO_GPIODEMUX(irq)    CONFIG_IRQ_PROG_INTA
+#elif defined(CONFIG_BF52x)
+#define PRIO_GPIODEMUX(irq)    ((irq) == IRQ_PORTF_INTA ? CONFIG_IRQ_PORTF_INTA : \
+                                (irq) == IRQ_PORTG_INTA ? CONFIG_IRQ_PORTG_INTA : \
+                                (irq) == IRQ_PORTH_INTA ? CONFIG_IRQ_PORTH_INTA : \
+                                -1)
+#elif defined(CONFIG_BF561)
+#define PRIO_GPIODEMUX(irq)    ((irq) == IRQ_PROG0_INTA ? CONFIG_IRQ_PROG0_INTA : \
+                                (irq) == IRQ_PROG1_INTA ? CONFIG_IRQ_PROG1_INTA : \
+                                (irq) == IRQ_PROG2_INTA ? CONFIG_IRQ_PROG2_INTA : \
+                                -1)
+#define bfin_write_TIMER_DISABLE(val)  bfin_write_TMRS8_DISABLE(val)
+#define bfin_write_TIMER_ENABLE(val)   bfin_write_TMRS8_ENABLE(val)
+#define bfin_write_TIMER_STATUS(val)   bfin_write_TMRS8_STATUS(val)
+#define bfin_read_TIMER_STATUS()       bfin_read_TMRS8_STATUS()
+#elif defined(CONFIG_BF54x)
+#define PRIO_GPIODEMUX(irq)    ((irq) == IRQ_PINT0 ? CONFIG_IRQ_PINT0 : \
+                                (irq) == IRQ_PINT1 ? CONFIG_IRQ_PINT1 : \
+                                (irq) == IRQ_PINT2 ? CONFIG_IRQ_PINT2 : \
+                                (irq) == IRQ_PINT3 ? CONFIG_IRQ_PINT3 : \
+                                -1)
+#define bfin_write_TIMER_DISABLE(val)  bfin_write_TIMER_DISABLE0(val)
+#define bfin_write_TIMER_ENABLE(val)   bfin_write_TIMER_ENABLE0(val)
+#define bfin_write_TIMER_STATUS(val)   bfin_write_TIMER_STATUS0(val)
+#define bfin_read_TIMER_STATUS(val)    bfin_read_TIMER_STATUS0(val)
+#else
+# error "no PRIO_GPIODEMUX() for this part"
+#endif
+
+#define __ipipe_root_tick_p(regs)      ((regs->ipend & 0x10) != 0)
+
+#else /* !CONFIG_IPIPE */
+
+#define task_hijacked(p)               0
+#define ipipe_trap_notify(t, r)        0
+
+#define __ipipe_stall_root_raw()       do { } while (0)
+#define __ipipe_unstall_root_raw()     do { } while (0)
+
+#define ipipe_init_irq_threads()               do { } while (0)
+#define ipipe_start_irq_thread(irq, desc)      0
+
+#define IRQ_SYSTMR             IRQ_CORETMR
+#define IRQ_PRIOTMR            IRQ_CORETMR
+
+#define __ipipe_root_tick_p(regs)      1
+
+#endif /* !CONFIG_IPIPE */
+
+#endif /* !__ASM_BLACKFIN_IPIPE_H */
diff --git a/arch/blackfin/include/asm/ipipe_base.h b/arch/blackfin/include/asm/ipipe_base.h
new file mode 100644 (file)
index 0000000..cb1025a
--- /dev/null
@@ -0,0 +1,80 @@
+/*   -*- linux-c -*-
+ *   include/asm-blackfin/_baseipipe.h
+ *
+ *   Copyright (C) 2007 Philippe Gerum.
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139,
+ *   USA; either version 2 of the License, or (at your option) any later
+ *   version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __ASM_BLACKFIN_IPIPE_BASE_H
+#define __ASM_BLACKFIN_IPIPE_BASE_H
+
+#ifdef CONFIG_IPIPE
+
+#define IPIPE_NR_XIRQS         NR_IRQS
+#define IPIPE_IRQ_ISHIFT       5       /* 2^5 for 32bits arch. */
+
+/* Blackfin-specific, global domain flags */
+#define IPIPE_ROOTLOCK_FLAG    1       /* Lock pipeline for root */
+
+ /* Blackfin traps -- i.e. exception vector numbers */
+#define IPIPE_NR_FAULTS                52 /* We leave a gap after VEC_ILL_RES. */
+/* Pseudo-vectors used for kernel events */
+#define IPIPE_FIRST_EVENT      IPIPE_NR_FAULTS
+#define IPIPE_EVENT_SYSCALL    (IPIPE_FIRST_EVENT)
+#define IPIPE_EVENT_SCHEDULE   (IPIPE_FIRST_EVENT + 1)
+#define IPIPE_EVENT_SIGWAKE    (IPIPE_FIRST_EVENT + 2)
+#define IPIPE_EVENT_SETSCHED   (IPIPE_FIRST_EVENT + 3)
+#define IPIPE_EVENT_INIT       (IPIPE_FIRST_EVENT + 4)
+#define IPIPE_EVENT_EXIT       (IPIPE_FIRST_EVENT + 5)
+#define IPIPE_EVENT_CLEANUP    (IPIPE_FIRST_EVENT + 6)
+#define IPIPE_LAST_EVENT       IPIPE_EVENT_CLEANUP
+#define IPIPE_NR_EVENTS                (IPIPE_LAST_EVENT + 1)
+
+#define IPIPE_TIMER_IRQ                IRQ_CORETMR
+
+#ifndef __ASSEMBLY__
+
+#include <linux/bitops.h>
+
+extern int test_bit(int nr, const void *addr);
+
+
+extern unsigned long __ipipe_root_status; /* Alias to ipipe_root_cpudom_var(status) */
+
+static inline void __ipipe_stall_root(void)
+{
+       volatile unsigned long *p = &__ipipe_root_status;
+       set_bit(0, p);
+}
+
+static inline unsigned long __ipipe_test_and_stall_root(void)
+{
+       volatile unsigned long *p = &__ipipe_root_status;
+       return test_and_set_bit(0, p);
+}
+
+static inline unsigned long __ipipe_test_root(void)
+{
+       const unsigned long *p = &__ipipe_root_status;
+       return test_bit(0, p);
+}
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* CONFIG_IPIPE */
+
+#endif /* !__ASM_BLACKFIN_IPIPE_BASE_H */
index 21e25f7..3d97790 100644 (file)
 #include <asm/pda.h>
 #include <asm/processor.h>
 
-static __inline__ int irq_canonicalize(int irq)
+#ifdef CONFIG_SMP
+/* Forward decl needed due to cdef inter dependencies */
+static inline uint32_t __pure bfin_dspid(void);
+# define blackfin_core_id() (bfin_dspid() & 0xff)
+# define bfin_irq_flags cpu_pda[blackfin_core_id()].imask
+#else
+extern unsigned long bfin_irq_flags;
+#endif
+
+#ifdef CONFIG_IPIPE
+
+#include <linux/ipipe_trace.h>
+
+void __ipipe_unstall_root(void);
+
+void __ipipe_restore_root(unsigned long flags);
+
+#ifdef CONFIG_DEBUG_HWERR
+# define __all_masked_irq_flags 0x3f
+# define __save_and_cli_hw(x) \
+       __asm__ __volatile__( \
+               "cli %0;" \
+               "sti %1;" \
+               : "=&d"(x) \
+               : "d" (0x3F) \
+       )
+#else
+# define __all_masked_irq_flags 0x1f
+# define __save_and_cli_hw(x) \
+       __asm__ __volatile__( \
+               "cli %0;" \
+               : "=&d"(x) \
+       )
+#endif
+
+#define irqs_enabled_from_flags_hw(x)  ((x) != __all_masked_irq_flags)
+#define raw_irqs_disabled_flags(flags) (!irqs_enabled_from_flags_hw(flags))
+#define local_test_iflag_hw(x)         irqs_enabled_from_flags_hw(x)
+
+#define local_save_flags(x)                                            \
+       do {                                                            \
+               (x) = __ipipe_test_root() ? \
+                       __all_masked_irq_flags : bfin_irq_flags; \
+       } while (0)
+
+#define local_irq_save(x)                              \
+       do {                                            \
+               (x) = __ipipe_test_and_stall_root();    \
+       } while (0)
+
+#define local_irq_restore(x)   __ipipe_restore_root(x)
+#define local_irq_disable()    __ipipe_stall_root()
+#define local_irq_enable()     __ipipe_unstall_root()
+#define irqs_disabled()                __ipipe_test_root()
+
+#define local_save_flags_hw(x) \
+       __asm__ __volatile__( \
+               "cli %0;" \
+               "sti %0;" \
+               : "=d"(x) \
+       )
+
+#define        irqs_disabled_hw()                              \
+       ({                                              \
+               unsigned long flags;                    \
+               local_save_flags_hw(flags);             \
+               !irqs_enabled_from_flags_hw(flags);     \
+       })
+
+static inline unsigned long raw_mangle_irq_bits(int virt, unsigned long real)
 {
-       return irq;
+       /* Merge virtual and real interrupt mask bits into a single
+          32bit word. */
+       return (real & ~(1 << 31)) | ((virt != 0) << 31);
 }
 
+static inline int raw_demangle_irq_bits(unsigned long *x)
+{
+       int virt = (*x & (1 << 31)) != 0;
+       *x &= ~(1L << 31);
+       return virt;
+}
+
+#ifdef CONFIG_IPIPE_TRACE_IRQSOFF
+
+#define local_irq_disable_hw()                                         \
+       do {                                                            \
+               int _tmp_dummy;                                         \
+               if (!irqs_disabled_hw())                                \
+                       ipipe_trace_begin(0x80000000);                  \
+               __asm__ __volatile__ ("cli %0;" : "=d" (_tmp_dummy) : );        \
+       } while (0)
+
+#define local_irq_enable_hw()                                          \
+       do {                                                            \
+               if (irqs_disabled_hw())                                 \
+                       ipipe_trace_end(0x80000000);                    \
+               __asm__ __volatile__ ("sti %0;" : : "d"(bfin_irq_flags));       \
+       } while (0)
+
+#define local_irq_save_hw(x)                           \
+       do {                                            \
+               __save_and_cli_hw(x);                   \
+               if (local_test_iflag_hw(x))             \
+                       ipipe_trace_begin(0x80000001);  \
+       } while (0)
+
+#define local_irq_restore_hw(x)                                \
+       do {                                            \
+               if (local_test_iflag_hw(x)) {           \
+                       ipipe_trace_end(0x80000001);    \
+                       local_irq_enable_hw_notrace();  \
+               }                                       \
+       } while (0)
+
+#define local_irq_disable_hw_notrace()                                 \
+       do {                                                            \
+               int _tmp_dummy;                                         \
+               __asm__ __volatile__ ("cli %0;" : "=d" (_tmp_dummy) : );        \
+       } while (0)
+
+#define local_irq_enable_hw_notrace() \
+       __asm__ __volatile__( \
+               "sti %0;" \
+               : \
+               : "d"(bfin_irq_flags) \
+       )
+
+#define local_irq_save_hw_notrace(x) __save_and_cli_hw(x)
+
+#define local_irq_restore_hw_notrace(x)                        \
+       do {                                            \
+               if (local_test_iflag_hw(x))             \
+                       local_irq_enable_hw_notrace();  \
+       } while (0)
+
+#else /* CONFIG_IPIPE_TRACE_IRQSOFF */
+
+#define local_irq_enable_hw() \
+       __asm__ __volatile__( \
+               "sti %0;" \
+               : \
+               : "d"(bfin_irq_flags) \
+       )
+
+#define local_irq_disable_hw()                 \
+       do {                                    \
+               int _tmp_dummy;                 \
+               __asm__ __volatile__ (          \
+                       "cli %0;"               \
+                       : "=d" (_tmp_dummy));   \
+       } while (0)
+
+#define local_irq_restore_hw(x) \
+       do { \
+               if (irqs_enabled_from_flags_hw(x)) \
+                       local_irq_enable_hw(); \
+       } while (0)
+
+#define local_irq_save_hw(x)           __save_and_cli_hw(x)
+
+#define local_irq_disable_hw_notrace() local_irq_disable_hw()
+#define local_irq_enable_hw_notrace()  local_irq_enable_hw()
+#define local_irq_save_hw_notrace(x)   local_irq_save_hw(x)
+#define local_irq_restore_hw_notrace(x)        local_irq_restore_hw(x)
+
+#endif  /* CONFIG_IPIPE_TRACE_IRQSOFF */
+
+#else /* !CONFIG_IPIPE */
+
 /*
  * Interrupt configuring macros.
  */
@@ -39,21 +204,6 @@ static __inline__ int irq_canonicalize(int irq)
                ); \
        } while (0)
 
-#if ANOMALY_05000244 && defined(CONFIG_BFIN_ICACHE)
-# define NOP_PAD_ANOMALY_05000244 "nop; nop;"
-#else
-# define NOP_PAD_ANOMALY_05000244
-#endif
-
-#ifdef CONFIG_SMP
-/* Forward decl needed due to cdef inter dependencies */
-static inline uint32_t __pure bfin_dspid(void);
-# define blackfin_core_id() (bfin_dspid() & 0xff)
-# define bfin_irq_flags cpu_pda[blackfin_core_id()].imask
-#else
-extern unsigned long bfin_irq_flags;
-#endif
-
 #define local_irq_enable() \
        __asm__ __volatile__( \
                "sti %0;" \
@@ -61,16 +211,6 @@ extern unsigned long bfin_irq_flags;
                : "d" (bfin_irq_flags) \
        )
 
-#define idle_with_irq_disabled() \
-       __asm__ __volatile__( \
-               NOP_PAD_ANOMALY_05000244 \
-               ".align 8;" \
-               "sti %0;" \
-               "idle;" \
-               : \
-               : "d" (bfin_irq_flags) \
-       )
-
 #ifdef CONFIG_DEBUG_HWERR
 # define __save_and_cli(x) \
        __asm__ __volatile__( \
@@ -116,4 +256,33 @@ extern unsigned long bfin_irq_flags;
        !irqs_enabled_from_flags(flags);        \
 })
 
+#define local_irq_save_hw(x)           local_irq_save(x)
+#define local_irq_restore_hw(x)                local_irq_restore(x)
+#define local_irq_enable_hw()          local_irq_enable()
+#define local_irq_disable_hw()         local_irq_disable()
+#define irqs_disabled_hw()             irqs_disabled()
+
+#endif /* !CONFIG_IPIPE */
+
+#if ANOMALY_05000244 && defined(CONFIG_BFIN_ICACHE)
+# define NOP_PAD_ANOMALY_05000244 "nop; nop;"
+#else
+# define NOP_PAD_ANOMALY_05000244
+#endif
+
+#define idle_with_irq_disabled() \
+       __asm__ __volatile__( \
+               NOP_PAD_ANOMALY_05000244 \
+               ".align 8;" \
+               "sti %0;" \
+               "idle;" \
+               : \
+               : "d" (bfin_irq_flags) \
+       )
+
+static inline int irq_canonicalize(int irq)
+{
+       return irq;
+}
+
 #endif                         /* _BFIN_IRQ_H_ */
index 812e6e6..a4c8254 100644 (file)
@@ -141,7 +141,7 @@ static inline unsigned long __xchg(unsigned long x, volatile void *ptr,
        unsigned long tmp = 0;
        unsigned long flags = 0;
 
-       local_irq_save(flags);
+       local_irq_save_hw(flags);
 
        switch (size) {
        case 1:
@@ -163,7 +163,7 @@ static inline unsigned long __xchg(unsigned long x, volatile void *ptr,
                         : "=&d" (tmp) : "d" (x), "m" (*__xg(ptr)) : "memory");
                break;
        }
-       local_irq_restore(flags);
+       local_irq_restore_hw(flags);
        return tmp;
 }
 
index f0902c1..38a2333 100644 (file)
@@ -15,6 +15,8 @@ else
     obj-y += time.o
 endif
 
+obj-$(CONFIG_IPIPE)                  += ipipe.o
+obj-$(CONFIG_IPIPE_TRACE_MCOUNT)     += mcount.o
 obj-$(CONFIG_BFIN_GPTIMERS)          += gptimers.o
 obj-$(CONFIG_CPLB_INFO)              += cplbinfo.o
 obj-$(CONFIG_MODULES)                += module.o
index 2c72b15..4c14331 100644 (file)
@@ -422,13 +422,13 @@ arch_initcall(bfin_gpio_init);
 void set_gpio_ ## name(unsigned gpio, unsigned short arg) \
 { \
        unsigned long flags; \
-       local_irq_save(flags); \
+       local_irq_save_hw(flags); \
        if (arg) \
                gpio_bankb[gpio_bank(gpio)]->name |= gpio_bit(gpio); \
        else \
                gpio_bankb[gpio_bank(gpio)]->name &= ~gpio_bit(gpio); \
        AWA_DUMMY_READ(name); \
-       local_irq_restore(flags); \
+       local_irq_restore_hw(flags); \
 } \
 EXPORT_SYMBOL(set_gpio_ ## name);
 
@@ -444,13 +444,13 @@ SET_GPIO(both)
 void set_gpio_ ## name(unsigned gpio, unsigned short arg) \
 { \
        unsigned long flags; \
-       local_irq_save(flags); \
+       local_irq_save_hw(flags); \
        if (arg) \
                gpio_bankb[gpio_bank(gpio)]->name ## _set = gpio_bit(gpio); \
        else \
                gpio_bankb[gpio_bank(gpio)]->name ## _clear = gpio_bit(gpio); \
        AWA_DUMMY_READ(name); \
-       local_irq_restore(flags); \
+       local_irq_restore_hw(flags); \
 } \
 EXPORT_SYMBOL(set_gpio_ ## name);
 #else
@@ -473,10 +473,10 @@ SET_GPIO_SC(data)
 void set_gpio_toggle(unsigned gpio)
 {
        unsigned long flags;
-       local_irq_save(flags);
+       local_irq_save_hw(flags);
        gpio_bankb[gpio_bank(gpio)]->toggle = gpio_bit(gpio);
        AWA_DUMMY_READ(toggle);
-       local_irq_restore(flags);
+       local_irq_restore_hw(flags);
 }
 #else
 void set_gpio_toggle(unsigned gpio)
@@ -494,10 +494,10 @@ EXPORT_SYMBOL(set_gpio_toggle);
 void set_gpiop_ ## name(unsigned gpio, unsigned short arg) \
 { \
        unsigned long flags; \
-       local_irq_save(flags); \
+       local_irq_save_hw(flags); \
        gpio_bankb[gpio_bank(gpio)]->name = arg; \
        AWA_DUMMY_READ(name); \
-       local_irq_restore(flags); \
+       local_irq_restore_hw(flags); \
 } \
 EXPORT_SYMBOL(set_gpiop_ ## name);
 #else
@@ -525,10 +525,10 @@ unsigned short get_gpio_ ## name(unsigned gpio) \
 { \
        unsigned long flags; \
        unsigned short ret; \
-       local_irq_save(flags); \
+       local_irq_save_hw(flags); \
        ret = 0x01 & (gpio_bankb[gpio_bank(gpio)]->name >> gpio_sub_n(gpio)); \
        AWA_DUMMY_READ(name); \
-       local_irq_restore(flags); \
+       local_irq_restore_hw(flags); \
        return ret; \
 } \
 EXPORT_SYMBOL(get_gpio_ ## name);
@@ -558,10 +558,10 @@ unsigned short get_gpiop_ ## name(unsigned gpio) \
 { \
        unsigned long flags; \
        unsigned short ret; \
-       local_irq_save(flags); \
+       local_irq_save_hw(flags); \
        ret = (gpio_bankb[gpio_bank(gpio)]->name); \
        AWA_DUMMY_READ(name); \
-       local_irq_restore(flags); \
+       local_irq_restore_hw(flags); \
        return ret; \
 } \
 EXPORT_SYMBOL(get_gpiop_ ## name);
@@ -611,10 +611,10 @@ int gpio_pm_wakeup_request(unsigned gpio, unsigned char type)
        if ((check_gpio(gpio) < 0) || !type)
                return -EINVAL;
 
-       local_irq_save(flags);
+       local_irq_save_hw(flags);
        wakeup_map[gpio_bank(gpio)] |= gpio_bit(gpio);
        wakeup_flags_map[gpio] = type;
-       local_irq_restore(flags);
+       local_irq_restore_hw(flags);
 
        return 0;
 }
@@ -627,11 +627,11 @@ void gpio_pm_wakeup_free(unsigned gpio)
        if (check_gpio(gpio) < 0)
                return;
 
-       local_irq_save(flags);
+       local_irq_save_hw(flags);
 
        wakeup_map[gpio_bank(gpio)] &= ~gpio_bit(gpio);
 
-       local_irq_restore(flags);
+       local_irq_restore_hw(flags);
 }
 EXPORT_SYMBOL(gpio_pm_wakeup_free);
 
@@ -882,7 +882,7 @@ int peripheral_request(unsigned short per, const char *label)
        if (!(per & P_DEFINED))
                return -ENODEV;
 
-       local_irq_save(flags);
+       local_irq_save_hw(flags);
 
        /* If a pin can be muxed as either GPIO or peripheral, make
         * sure it is not already a GPIO pin when we request it.
@@ -893,7 +893,7 @@ int peripheral_request(unsigned short per, const char *label)
                printk(KERN_ERR
                       "%s: Peripheral %d is already reserved as GPIO by %s !\n",
                       __func__, ident, get_label(ident));
-               local_irq_restore(flags);
+               local_irq_restore_hw(flags);
                return -EBUSY;
        }
 
@@ -923,7 +923,7 @@ int peripheral_request(unsigned short per, const char *label)
                        printk(KERN_ERR
                               "%s: Peripheral %d function %d is already reserved by %s !\n",
                               __func__, ident, P_FUNCT2MUX(per), get_label(ident));
-                       local_irq_restore(flags);
+                       local_irq_restore_hw(flags);
                        return -EBUSY;
                }
        }
@@ -938,7 +938,7 @@ int peripheral_request(unsigned short per, const char *label)
 #endif
        port_setup(ident, PERIPHERAL_USAGE);
 
-       local_irq_restore(flags);
+       local_irq_restore_hw(flags);
        set_label(ident, label);
 
        return 0;
@@ -980,10 +980,10 @@ void peripheral_free(unsigned short per)
        if (check_gpio(ident) < 0)
                return;
 
-       local_irq_save(flags);
+       local_irq_save_hw(flags);
 
        if (unlikely(!(reserved_peri_map[gpio_bank(ident)] & gpio_bit(ident)))) {
-               local_irq_restore(flags);
+               local_irq_restore_hw(flags);
                return;
        }
 
@@ -994,7 +994,7 @@ void peripheral_free(unsigned short per)
 
        set_label(ident, "free");
 
-       local_irq_restore(flags);
+       local_irq_restore_hw(flags);
 }
 EXPORT_SYMBOL(peripheral_free);
 
@@ -1028,7 +1028,7 @@ int bfin_gpio_request(unsigned gpio, const char *label)
        if (check_gpio(gpio) < 0)
                return -EINVAL;
 
-       local_irq_save(flags);
+       local_irq_save_hw(flags);
 
        /*
         * Allow that the identical GPIO can
@@ -1037,7 +1037,7 @@ int bfin_gpio_request(unsigned gpio, const char *label)
         */
 
        if (cmp_label(gpio, label) == 0) {
-               local_irq_restore(flags);
+               local_irq_restore_hw(flags);
                return 0;
        }
 
@@ -1045,7 +1045,7 @@ int bfin_gpio_request(unsigned gpio, const char *label)
                dump_stack();
                printk(KERN_ERR "bfin-gpio: GPIO %d is already reserved by %s !\n",
                       gpio, get_label(gpio));
-               local_irq_restore(flags);
+               local_irq_restore_hw(flags);
                return -EBUSY;
        }
        if (unlikely(reserved_peri_map[gpio_bank(gpio)] & gpio_bit(gpio))) {
@@ -1053,7 +1053,7 @@ int bfin_gpio_request(unsigned gpio, const char *label)
                printk(KERN_ERR
                       "bfin-gpio: GPIO %d is already reserved as Peripheral by %s !\n",
                       gpio, get_label(gpio));
-               local_irq_restore(flags);
+               local_irq_restore_hw(flags);
                return -EBUSY;
        }
        if (unlikely(reserved_gpio_irq_map[gpio_bank(gpio)] & gpio_bit(gpio)))
@@ -1063,7 +1063,7 @@ int bfin_gpio_request(unsigned gpio, const char *label)
        reserved_gpio_map[gpio_bank(gpio)] |= gpio_bit(gpio);
        set_label(gpio, label);
 
-       local_irq_restore(flags);
+       local_irq_restore_hw(flags);
 
        port_setup(gpio, GPIO_USAGE);
 
@@ -1078,12 +1078,12 @@ void bfin_gpio_free(unsigned gpio)
        if (check_gpio(gpio) < 0)
                return;
 
-       local_irq_save(flags);
+       local_irq_save_hw(flags);
 
        if (unlikely(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio)))) {
                dump_stack();
                gpio_error(gpio);
-               local_irq_restore(flags);
+               local_irq_restore_hw(flags);
                return;
        }
 
@@ -1091,7 +1091,7 @@ void bfin_gpio_free(unsigned gpio)
 
        set_label(gpio, "free");
 
-       local_irq_restore(flags);
+       local_irq_restore_hw(flags);
 }
 EXPORT_SYMBOL(bfin_gpio_free);
 
@@ -1102,14 +1102,14 @@ int bfin_gpio_irq_request(unsigned gpio, const char *label)
        if (check_gpio(gpio) < 0)
                return -EINVAL;
 
-       local_irq_save(flags);
+       local_irq_save_hw(flags);
 
        if (unlikely(reserved_gpio_irq_map[gpio_bank(gpio)] & gpio_bit(gpio))) {
                dump_stack();
                printk(KERN_ERR
                       "bfin-gpio: GPIO %d is already reserved as gpio-irq !\n",
                       gpio);
-               local_irq_restore(flags);
+               local_irq_restore_hw(flags);
                return -EBUSY;
        }
        if (unlikely(reserved_peri_map[gpio_bank(gpio)] & gpio_bit(gpio))) {
@@ -1117,7 +1117,7 @@ int bfin_gpio_irq_request(unsigned gpio, const char *label)
                printk(KERN_ERR
                       "bfin-gpio: GPIO %d is already reserved as Peripheral by %s !\n",
                       gpio, get_label(gpio));
-               local_irq_restore(flags);
+               local_irq_restore_hw(flags);
                return -EBUSY;
        }
        if (unlikely(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio)))
@@ -1128,7 +1128,7 @@ int bfin_gpio_irq_request(unsigned gpio, const char *label)
        reserved_gpio_irq_map[gpio_bank(gpio)] |= gpio_bit(gpio);
        set_label(gpio, label);
 
-       local_irq_restore(flags);
+       local_irq_restore_hw(flags);
 
        port_setup(gpio, GPIO_USAGE);
 
@@ -1142,12 +1142,12 @@ void bfin_gpio_irq_free(unsigned gpio)
        if (check_gpio(gpio) < 0)
                return;
 
-       local_irq_save(flags);
+       local_irq_save_hw(flags);
 
        if (unlikely(!(reserved_gpio_irq_map[gpio_bank(gpio)] & gpio_bit(gpio)))) {
                dump_stack();
                gpio_error(gpio);
-               local_irq_restore(flags);
+               local_irq_restore_hw(flags);
                return;
        }
 
@@ -1155,7 +1155,7 @@ void bfin_gpio_irq_free(unsigned gpio)
 
        set_label(gpio, "free");
 
-       local_irq_restore(flags);
+       local_irq_restore_hw(flags);
 }
 
 
@@ -1169,10 +1169,10 @@ int bfin_gpio_direction_input(unsigned gpio)
                return -EINVAL;
        }
 
-       local_irq_save(flags);
+       local_irq_save_hw(flags);
        gpio_array[gpio_bank(gpio)]->port_dir_clear = gpio_bit(gpio);
        gpio_array[gpio_bank(gpio)]->port_inen |= gpio_bit(gpio);
-       local_irq_restore(flags);
+       local_irq_restore_hw(flags);
 
        return 0;
 }
@@ -1187,11 +1187,11 @@ int bfin_gpio_direction_output(unsigned gpio, int value)
                return -EINVAL;
        }
 
-       local_irq_save(flags);
+       local_irq_save_hw(flags);
        gpio_array[gpio_bank(gpio)]->port_inen &= ~gpio_bit(gpio);
        gpio_set_value(gpio, value);
        gpio_array[gpio_bank(gpio)]->port_dir_set = gpio_bit(gpio);
-       local_irq_restore(flags);
+       local_irq_restore_hw(flags);
 
        return 0;
 }
@@ -1218,10 +1218,10 @@ void bfin_gpio_irq_prepare(unsigned gpio)
 
        port_setup(gpio, GPIO_USAGE);
 
-       local_irq_save(flags);
+       local_irq_save_hw(flags);
        gpio_array[gpio_bank(gpio)]->port_dir_clear = gpio_bit(gpio);
        gpio_array[gpio_bank(gpio)]->port_inen |= gpio_bit(gpio);
-       local_irq_restore(flags);
+       local_irq_restore_hw(flags);
 }
 
 #else
@@ -1232,11 +1232,11 @@ int bfin_gpio_get_value(unsigned gpio)
        int ret;
 
        if (unlikely(get_gpio_edge(gpio))) {
-               local_irq_save(flags);
+               local_irq_save_hw(flags);
                set_gpio_edge(gpio, 0);
                ret = get_gpio_data(gpio);
                set_gpio_edge(gpio, 1);
-               local_irq_restore(flags);
+               local_irq_restore_hw(flags);
 
                return ret;
        } else
@@ -1254,11 +1254,11 @@ int bfin_gpio_direction_input(unsigned gpio)
                return -EINVAL;
        }
 
-       local_irq_save(flags);
+       local_irq_save_hw(flags);
        gpio_bankb[gpio_bank(gpio)]->dir &= ~gpio_bit(gpio);
        gpio_bankb[gpio_bank(gpio)]->inen |= gpio_bit(gpio);
        AWA_DUMMY_READ(inen);
-       local_irq_restore(flags);
+       local_irq_restore_hw(flags);
 
        return 0;
 }
@@ -1273,7 +1273,7 @@ int bfin_gpio_direction_output(unsigned gpio, int value)
                return -EINVAL;
        }
 
-       local_irq_save(flags);
+       local_irq_save_hw(flags);
        gpio_bankb[gpio_bank(gpio)]->inen &= ~gpio_bit(gpio);
 
        if (value)
@@ -1283,7 +1283,7 @@ int bfin_gpio_direction_output(unsigned gpio, int value)
 
        gpio_bankb[gpio_bank(gpio)]->dir |= gpio_bit(gpio);
        AWA_DUMMY_READ(dir);
-       local_irq_restore(flags);
+       local_irq_restore_hw(flags);
 
        return 0;
 }
index 5ef5d1a..87463ce 100644 (file)
@@ -332,7 +332,7 @@ void flush_switched_cplbs(unsigned int cpu)
 
        nr_cplb_flush[cpu]++;
 
-       local_irq_save(flags);
+       local_irq_save_hw(flags);
        disable_icplb();
        for (i = first_switched_icplb; i < MAX_CPLBS; i++) {
                icplb_tbl[cpu][i].data = 0;
@@ -346,7 +346,7 @@ void flush_switched_cplbs(unsigned int cpu)
                bfin_write32(DCPLB_DATA0 + i * 4, 0);
        }
        enable_dcplb();
-       local_irq_restore(flags);
+       local_irq_restore_hw(flags);
 
 }
 
@@ -362,7 +362,7 @@ void set_mask_dcplbs(unsigned long *masks, unsigned int cpu)
                return;
        }
 
-       local_irq_save(flags);
+       local_irq_save_hw(flags);
        current_rwx_mask[cpu] = masks;
 
        d_data = CPLB_SUPV_WR | CPLB_VALID | CPLB_DIRTY | PAGE_SIZE_4KB;
@@ -382,5 +382,5 @@ void set_mask_dcplbs(unsigned long *masks, unsigned int cpu)
                addr += PAGE_SIZE;
        }
        enable_dcplb();
-       local_irq_restore(flags);
+       local_irq_restore_hw(flags);
 }
index c0c3fe8..a9cfba9 100644 (file)
 #endif
 
 ENTRY(_ret_from_fork)
+#ifdef CONFIG_IPIPE
+       [--sp] = reti;          /* IRQs on. */
+       SP += 4;
+#endif /* CONFIG_IPIPE */
        SP += -12;
        call _schedule_tail;
        SP += 12;
diff --git a/arch/blackfin/kernel/ipipe.c b/arch/blackfin/kernel/ipipe.c
new file mode 100644 (file)
index 0000000..339be5a
--- /dev/null
@@ -0,0 +1,428 @@
+/* -*- linux-c -*-
+ * linux/arch/blackfin/kernel/ipipe.c
+ *
+ * Copyright (C) 2005-2007 Philippe Gerum.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139,
+ * USA; either version 2 of the License, or (at your option) any later
+ * version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Architecture-dependent I-pipe support for the Blackfin.
+ */
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/percpu.h>
+#include <linux/bitops.h>
+#include <linux/slab.h>
+#include <linux/errno.h>
+#include <linux/kthread.h>
+#include <asm/unistd.h>
+#include <asm/system.h>
+#include <asm/atomic.h>
+#include <asm/io.h>
+
+static int create_irq_threads;
+
+DEFINE_PER_CPU(struct pt_regs, __ipipe_tick_regs);
+
+static DEFINE_PER_CPU(unsigned long, pending_irqthread_mask);
+
+static DEFINE_PER_CPU(int [IVG13 + 1], pending_irq_count);
+
+asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs);
+
+static void __ipipe_no_irqtail(void);
+
+unsigned long __ipipe_irq_tail_hook = (unsigned long)&__ipipe_no_irqtail;
+EXPORT_SYMBOL(__ipipe_irq_tail_hook);
+
+unsigned long __ipipe_core_clock;
+EXPORT_SYMBOL(__ipipe_core_clock);
+
+unsigned long __ipipe_freq_scale;
+EXPORT_SYMBOL(__ipipe_freq_scale);
+
+atomic_t __ipipe_irq_lvdepth[IVG15 + 1];
+
+unsigned long __ipipe_irq_lvmask = __all_masked_irq_flags;
+EXPORT_SYMBOL(__ipipe_irq_lvmask);
+
+static void __ipipe_ack_irq(unsigned irq, struct irq_desc *desc)
+{
+       desc->ipipe_ack(irq, desc);
+}
+
+/*
+ * __ipipe_enable_pipeline() -- We are running on the boot CPU, hw
+ * interrupts are off, and secondary CPUs are still lost in space.
+ */
+void __ipipe_enable_pipeline(void)
+{
+       unsigned irq;
+
+       __ipipe_core_clock = get_cclk(); /* Fetch this once. */
+       __ipipe_freq_scale = 1000000000UL / __ipipe_core_clock;
+
+       for (irq = 0; irq < NR_IRQS; ++irq)
+               ipipe_virtualize_irq(ipipe_root_domain,
+                                    irq,
+                                    (ipipe_irq_handler_t)&asm_do_IRQ,
+                                    NULL,
+                                    &__ipipe_ack_irq,
+                                    IPIPE_HANDLE_MASK | IPIPE_PASS_MASK);
+}
+
+/*
+ * __ipipe_handle_irq() -- IPIPE's generic IRQ handler. An optimistic
+ * interrupt protection log is maintained here for each domain. Hw
+ * interrupts are masked on entry.
+ */
+void __ipipe_handle_irq(unsigned irq, struct pt_regs *regs)
+{
+       struct ipipe_domain *this_domain, *next_domain;
+       struct list_head *head, *pos;
+       int m_ack, s = -1;
+
+       /*
+        * Software-triggered IRQs do not need any ack.  The contents
+        * of the register frame should only be used when processing
+        * the timer interrupt, but not for handling any other
+        * interrupt.
+        */
+       m_ack = (regs == NULL || irq == IRQ_SYSTMR || irq == IRQ_CORETMR);
+
+       this_domain = ipipe_current_domain;
+
+       if (unlikely(test_bit(IPIPE_STICKY_FLAG, &this_domain->irqs[irq].control)))
+               head = &this_domain->p_link;
+       else {
+               head = __ipipe_pipeline.next;
+               next_domain = list_entry(head, struct ipipe_domain, p_link);
+               if (likely(test_bit(IPIPE_WIRED_FLAG, &next_domain->irqs[irq].control))) {
+                       if (!m_ack && next_domain->irqs[irq].acknowledge != NULL)
+                               next_domain->irqs[irq].acknowledge(irq, irq_desc + irq);
+                       if (test_bit(IPIPE_ROOTLOCK_FLAG, &ipipe_root_domain->flags))
+                               s = __test_and_set_bit(IPIPE_STALL_FLAG,
+                                                      &ipipe_root_cpudom_var(status));
+                       __ipipe_dispatch_wired(next_domain, irq);
+                               goto finalize;
+                       return;
+               }
+       }
+
+       /* Ack the interrupt. */
+
+       pos = head;
+
+       while (pos != &__ipipe_pipeline) {
+               next_domain = list_entry(pos, struct ipipe_domain, p_link);
+               /*
+                * For each domain handling the incoming IRQ, mark it
+                * as pending in its log.
+                */
+               if (test_bit(IPIPE_HANDLE_FLAG, &next_domain->irqs[irq].control)) {
+                       /*
+                        * Domains that handle this IRQ are polled for
+                        * acknowledging it by decreasing priority
+                        * order. The interrupt must be made pending
+                        * _first_ in the domain's status flags before
+                        * the PIC is unlocked.
+                        */
+                       __ipipe_set_irq_pending(next_domain, irq);
+
+                       if (!m_ack && next_domain->irqs[irq].acknowledge != NULL) {
+                               next_domain->irqs[irq].acknowledge(irq, irq_desc + irq);
+                               m_ack = 1;
+                       }
+               }
+
+               /*
+                * If the domain does not want the IRQ to be passed
+                * down the interrupt pipe, exit the loop now.
+                */
+               if (!test_bit(IPIPE_PASS_FLAG, &next_domain->irqs[irq].control))
+                       break;
+
+               pos = next_domain->p_link.next;
+       }
+
+       /*
+        * Now walk the pipeline, yielding control to the highest
+        * priority domain that has pending interrupt(s) or
+        * immediately to the current domain if the interrupt has been
+        * marked as 'sticky'. This search does not go beyond the
+        * current domain in the pipeline. We also enforce the
+        * additional root stage lock (blackfin-specific). */
+
+       if (test_bit(IPIPE_ROOTLOCK_FLAG, &ipipe_root_domain->flags))
+               s = __test_and_set_bit(IPIPE_STALL_FLAG,
+                                      &ipipe_root_cpudom_var(status));
+finalize:
+
+       __ipipe_walk_pipeline(head);
+
+       if (!s)
+               __clear_bit(IPIPE_STALL_FLAG,
+                           &ipipe_root_cpudom_var(status));
+}
+
+int __ipipe_check_root(void)
+{
+       return ipipe_root_domain_p;
+}
+
+void __ipipe_enable_irqdesc(struct ipipe_domain *ipd, unsigned irq)
+{
+       struct irq_desc *desc = irq_desc + irq;
+       int prio = desc->ic_prio;
+
+       desc->depth = 0;
+       if (ipd != &ipipe_root &&
+           atomic_inc_return(&__ipipe_irq_lvdepth[prio]) == 1)
+               __set_bit(prio, &__ipipe_irq_lvmask);
+}
+EXPORT_SYMBOL(__ipipe_enable_irqdesc);
+
+void __ipipe_disable_irqdesc(struct ipipe_domain *ipd, unsigned irq)
+{
+       struct irq_desc *desc = irq_desc + irq;
+       int prio = desc->ic_prio;
+
+       if (ipd != &ipipe_root &&
+           atomic_dec_and_test(&__ipipe_irq_lvdepth[prio]))
+               __clear_bit(prio, &__ipipe_irq_lvmask);
+}
+EXPORT_SYMBOL(__ipipe_disable_irqdesc);
+
+void __ipipe_stall_root_raw(void)
+{
+       /*
+        * This code is called by the ins{bwl} routines (see
+        * arch/blackfin/lib/ins.S), which are heavily used by the
+        * network stack. It masks all interrupts but those handled by
+        * non-root domains, so that we keep decent network transfer
+        * rates for Linux without inducing pathological jitter for
+        * the real-time domain.
+        */
+       __asm__ __volatile__ ("sti %0;" : : "d"(__ipipe_irq_lvmask));
+
+       __set_bit(IPIPE_STALL_FLAG,
+                 &ipipe_root_cpudom_var(status));
+}
+
+void __ipipe_unstall_root_raw(void)
+{
+       __clear_bit(IPIPE_STALL_FLAG,
+                   &ipipe_root_cpudom_var(status));
+
+       __asm__ __volatile__ ("sti %0;" : : "d"(bfin_irq_flags));
+}
+
+int __ipipe_syscall_root(struct pt_regs *regs)
+{
+       unsigned long flags;
+
+       /* We need to run the IRQ tail hook whenever we don't
+        * propagate a syscall to higher domains, because we know that
+        * important operations might be pending there (e.g. Xenomai
+        * deferred rescheduling). */
+
+       if (!__ipipe_syscall_watched_p(current, regs->orig_p0)) {
+               void (*hook)(void) = (void (*)(void))__ipipe_irq_tail_hook;
+               hook();
+               return 0;
+       }
+
+       /*
+        * This routine either returns:
+        * 0 -- if the syscall is to be passed to Linux;
+        * 1 -- if the syscall should not be passed to Linux, and no
+        * tail work should be performed;
+        * -1 -- if the syscall should not be passed to Linux but the
+        * tail work has to be performed (for handling signals etc).
+        */
+
+       if (__ipipe_event_monitored_p(IPIPE_EVENT_SYSCALL) &&
+           __ipipe_dispatch_event(IPIPE_EVENT_SYSCALL, regs) > 0) {
+               if (ipipe_root_domain_p && !in_atomic()) {
+                       /*
+                        * Sync pending VIRQs before _TIF_NEED_RESCHED
+                        * is tested.
+                        */
+                       local_irq_save_hw(flags);
+                       if ((ipipe_root_cpudom_var(irqpend_himask) & IPIPE_IRQMASK_VIRT) != 0)
+                               __ipipe_sync_pipeline(IPIPE_IRQMASK_VIRT);
+                       local_irq_restore_hw(flags);
+                       return -1;
+               }
+               return 1;
+       }
+
+       return 0;
+}
+
+unsigned long ipipe_critical_enter(void (*syncfn) (void))
+{
+       unsigned long flags;
+
+       local_irq_save_hw(flags);
+
+       return flags;
+}
+
+void ipipe_critical_exit(unsigned long flags)
+{
+       local_irq_restore_hw(flags);
+}
+
+static void __ipipe_no_irqtail(void)
+{
+}
+
+int ipipe_get_sysinfo(struct ipipe_sysinfo *info)
+{
+       info->ncpus = num_online_cpus();
+       info->cpufreq = ipipe_cpu_freq();
+       info->archdep.tmirq = IPIPE_TIMER_IRQ;
+       info->archdep.tmfreq = info->cpufreq;
+
+       return 0;
+}
+
+/*
+ * ipipe_trigger_irq() -- Push the interrupt at front of the pipeline
+ * just like if it has been actually received from a hw source. Also
+ * works for virtual interrupts.
+ */
+int ipipe_trigger_irq(unsigned irq)
+{
+       unsigned long flags;
+
+       if (irq >= IPIPE_NR_IRQS ||
+           (ipipe_virtual_irq_p(irq)
+            && !test_bit(irq - IPIPE_VIRQ_BASE, &__ipipe_virtual_irq_map)))
+               return -EINVAL;
+
+       local_irq_save_hw(flags);
+
+       __ipipe_handle_irq(irq, NULL);
+
+       local_irq_restore_hw(flags);
+
+       return 1;
+}
+
+/* Move Linux IRQ to threads. */
+
+static int do_irqd(void *__desc)
+{
+       struct irq_desc *desc = __desc;
+       unsigned irq = desc - irq_desc;
+       int thrprio = desc->thr_prio;
+       int thrmask = 1 << thrprio;
+       int cpu = smp_processor_id();
+       cpumask_t cpumask;
+
+       sigfillset(&current->blocked);
+       current->flags |= PF_NOFREEZE;
+       cpumask = cpumask_of_cpu(cpu);
+       set_cpus_allowed(current, cpumask);
+       ipipe_setscheduler_root(current, SCHED_FIFO, 50 + thrprio);
+
+       while (!kthread_should_stop()) {
+               local_irq_disable();
+               if (!(desc->status & IRQ_SCHEDULED)) {
+                       set_current_state(TASK_INTERRUPTIBLE);
+resched:
+                       local_irq_enable();
+                       schedule();
+                       local_irq_disable();
+               }
+               __set_current_state(TASK_RUNNING);
+               /*
+                * If higher priority interrupt servers are ready to
+                * run, reschedule immediately. We need this for the
+                * GPIO demux IRQ handler to unmask the interrupt line
+                * _last_, after all GPIO IRQs have run.
+                */
+               if (per_cpu(pending_irqthread_mask, cpu) & ~(thrmask|(thrmask-1)))
+                       goto resched;
+               if (--per_cpu(pending_irq_count[thrprio], cpu) == 0)
+                       per_cpu(pending_irqthread_mask, cpu) &= ~thrmask;
+               desc->status &= ~IRQ_SCHEDULED;
+               desc->thr_handler(irq, &__raw_get_cpu_var(__ipipe_tick_regs));
+               local_irq_enable();
+       }
+       __set_current_state(TASK_RUNNING);
+       return 0;
+}
+
+static void kick_irqd(unsigned irq, void *cookie)
+{
+       struct irq_desc *desc = irq_desc + irq;
+       int thrprio = desc->thr_prio;
+       int thrmask = 1 << thrprio;
+       int cpu = smp_processor_id();
+
+       if (!(desc->status & IRQ_SCHEDULED)) {
+               desc->status |= IRQ_SCHEDULED;
+               per_cpu(pending_irqthread_mask, cpu) |= thrmask;
+               ++per_cpu(pending_irq_count[thrprio], cpu);
+               wake_up_process(desc->thread);
+       }
+}
+
+int ipipe_start_irq_thread(unsigned irq, struct irq_desc *desc)
+{
+       if (desc->thread || !create_irq_threads)
+               return 0;
+
+       desc->thread = kthread_create(do_irqd, desc, "IRQ %d", irq);
+       if (desc->thread == NULL) {
+               printk(KERN_ERR "irqd: could not create IRQ thread %d!\n", irq);
+               return -ENOMEM;
+       }
+
+       wake_up_process(desc->thread);
+
+       desc->thr_handler = ipipe_root_domain->irqs[irq].handler;
+       ipipe_root_domain->irqs[irq].handler = &kick_irqd;
+
+       return 0;
+}
+
+void __init ipipe_init_irq_threads(void)
+{
+       unsigned irq;
+       struct irq_desc *desc;
+
+       create_irq_threads = 1;
+
+       for (irq = 0; irq < NR_IRQS; irq++) {
+               desc = irq_desc + irq;
+               if (desc->action != NULL ||
+                       (desc->status & IRQ_NOREQUEST) != 0)
+                       ipipe_start_irq_thread(irq, desc);
+       }
+}
+
+EXPORT_SYMBOL(show_stack);
+
+#ifdef CONFIG_IPIPE_TRACE_MCOUNT
+void notrace _mcount(void);
+EXPORT_SYMBOL(_mcount);
+#endif /* CONFIG_IPIPE_TRACE_MCOUNT */
index 1624e11..ab8209c 100644 (file)
@@ -108,8 +108,9 @@ asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs)
 {
        struct pt_regs *old_regs;
        struct irq_desc *desc = irq_desc + irq;
+#ifndef CONFIG_IPIPE
        unsigned short pending, other_ints;
-
+#endif
        old_regs = set_irq_regs(regs);
 
        /*
@@ -137,6 +138,7 @@ asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs)
 #endif
        generic_handle_irq(irq);
 
+#ifndef CONFIG_IPIPE   /* Useless and bugous over the I-pipe: IRQs are threaded. */
        /* If we're the only interrupt running (ignoring IRQ15 which is for
           syscalls), lower our priority to IRQ14 so that softirqs run at
           that level.  If there's another, lower-level interrupt, irq_exit
@@ -146,6 +148,7 @@ asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs)
        other_ints = pending & (pending - 1);
        if (other_ints == 0)
                lower_to_irq14();
+#endif /* !CONFIG_IPIPE */
        irq_exit();
 
        set_irq_regs(old_regs);
diff --git a/arch/blackfin/kernel/mcount.S b/arch/blackfin/kernel/mcount.S
new file mode 100644 (file)
index 0000000..edcfb38
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * linux/arch/blackfin/mcount.S
+ *
+ * Copyright (C) 2006 Analog Devices Inc.
+ *
+ * 2007/04/12 Save index, length, modify and base registers. --rpm
+ */
+
+#include <linux/linkage.h>
+#include <asm/blackfin.h>
+
+.text
+
+.align 4       /* just in case */
+
+ENTRY(__mcount)
+       [--sp] = i0;
+       [--sp] = i1;
+       [--sp] = i2;
+       [--sp] = i3;
+       [--sp] = l0;
+       [--sp] = l1;
+       [--sp] = l2;
+       [--sp] = l3;
+       [--sp] = m0;
+       [--sp] = m1;
+       [--sp] = m2;
+       [--sp] = m3;
+       [--sp] = b0;
+       [--sp] = b1;
+       [--sp] = b2;
+       [--sp] = b3;
+       [--sp] = ( r7:0, p5:0 );
+       [--sp] = ASTAT;
+
+       p1.L = _ipipe_trace_enable;
+       p1.H = _ipipe_trace_enable;
+       r7 = [p1];
+       CC = r7 == 0;
+       if CC jump out;
+       link 0x10;
+       r0 = 0x0;
+       [sp + 0xc] = r0; /* v */
+       r0 = 0x0;       /* type: IPIPE_TRACE_FN */
+       r1 = rets;
+       p0 = [fp];      /* p0: Prior FP */
+       r2 = [p0 + 4];  /* r2: Prior RETS */
+       call ___ipipe_trace;
+       unlink;
+out:
+       ASTAT = [sp++];
+       ( r7:0, p5:0 ) = [sp++];
+       b3 = [sp++];
+       b2 = [sp++];
+       b1 = [sp++];
+       b0 = [sp++];
+       m3 = [sp++];
+       m2 = [sp++];
+       m1 = [sp++];
+       m0 = [sp++];
+       l3 = [sp++];
+       l2 = [sp++];
+       l1 = [sp++];
+       l0 = [sp++];
+       i3 = [sp++];
+       i2 = [sp++];
+       i1 = [sp++];
+       i0 = [sp++];
+       rts;
+ENDPROC(__mcount)
index 1ec0faa..33e2e89 100644 (file)
@@ -82,11 +82,14 @@ void cpu_idle(void)__attribute__((l1_text));
  */
 static void default_idle(void)
 {
-       local_irq_disable();
+#ifdef CONFIG_IPIPE
+       ipipe_suspend_domain();
+#endif
+       local_irq_disable_hw();
        if (!need_resched())
                idle_with_irq_disabled();
 
-       local_irq_enable();
+       local_irq_enable_hw();
 }
 
 /*
index ec4dfa3..172b4c5 100644 (file)
@@ -31,7 +31,7 @@ static struct irqaction bfin_timer_irq = {
 #endif
 };
 
-#ifdef CONFIG_TICK_SOURCE_SYSTMR0
+#if defined(CONFIG_TICK_SOURCE_SYSTMR0) || defined(CONFIG_IPIPE)
 void __init setup_system_timer0(void)
 {
        /* Power down the core timer, just to play safe. */
@@ -74,7 +74,7 @@ void __init setup_core_timer(void)
 static void __init
 time_sched_init(irqreturn_t(*timer_routine) (int, void *))
 {
-#ifdef CONFIG_TICK_SOURCE_SYSTMR0
+#if defined(CONFIG_TICK_SOURCE_SYSTMR0) || defined(CONFIG_IPIPE)
        setup_system_timer0();
        bfin_timer_irq.handler = timer_routine;
        setup_irq(IRQ_TIMER0, &bfin_timer_irq);
@@ -94,7 +94,7 @@ static unsigned long gettimeoffset(void)
        unsigned long offset;
        unsigned long clocks_per_jiffy;
 
-#ifdef CONFIG_TICK_SOURCE_SYSTMR0
+#if defined(CONFIG_TICK_SOURCE_SYSTMR0) || defined(CONFIG_IPIPE)
        clocks_per_jiffy = bfin_read_TIMER0_PERIOD();
        offset = bfin_read_TIMER0_COUNTER() / \
                (((clocks_per_jiffy + 1) * HZ) / USEC_PER_SEC);
@@ -133,7 +133,8 @@ irqreturn_t timer_interrupt(int irq, void *dummy)
        static long last_rtc_update;
 
        write_seqlock(&xtime_lock);
-#ifdef CONFIG_TICK_SOURCE_SYSTMR0
+#if defined(CONFIG_TICK_SOURCE_SYSTMR0) && !defined(CONFIG_IPIPE)
+/* FIXME: Here TIMIL0 is not set when IPIPE enabled, why? */
        if (get_gptimer_status(0) & TIMER_STATUS_TIMIL0) {
 #endif
                do_timer(1);
@@ -155,13 +156,17 @@ irqreturn_t timer_interrupt(int irq, void *dummy)
                                /* Do it again in 60s. */
                                last_rtc_update = xtime.tv_sec - 600;
                }
-#ifdef CONFIG_TICK_SOURCE_SYSTMR0
+#if defined(CONFIG_TICK_SOURCE_SYSTMR0) && !defined(CONFIG_IPIPE)
                set_gptimer_status(0, TIMER_STATUS_TIMIL0);
        }
 #endif
        write_sequnlock(&xtime_lock);
 
+#ifdef CONFIG_IPIPE
+       update_root_process_times(get_irq_regs());
+#else
        update_process_times(user_mode(get_irq_regs()));
+#endif
        profile_tick(CPU_PROFILING);
 
        return IRQ_HANDLED;
index 950cc82..956aefb 100644 (file)
@@ -577,10 +577,15 @@ asmlinkage void trap_c(struct pt_regs *fp)
                }
        }
 
-       info.si_signo = sig;
-       info.si_errno = 0;
-       info.si_addr = (void __user *)fp->pc;
-       force_sig_info(sig, &info, current);
+#ifdef CONFIG_IPIPE
+       if (!ipipe_trap_notify(fp->seqstat & 0x3f, fp))
+#endif
+       {
+               info.si_signo = sig;
+               info.si_errno = 0;
+               info.si_addr = (void __user *)fp->pc;
+               force_sig_info(sig, &info, current);
+       }
 
        trace_buffer_restore(j);
        return;
index d60554d..1b84b21 100644 (file)
 ENTRY(_insl)
 #ifdef CONFIG_BFIN_INS_LOWOVERHEAD
        P0 = R0;        /* P0 = port */
+#ifdef CONFIG_IPIPE
+       [--sp] = rets
+       [--sp] = (P5:0);
+       sp += -12
+       call ___ipipe_stall_root_raw
+       sp += 12
+       (P5:0) = [sp++];
+#else
        cli R3;
+#endif
        P1 = R1;        /* P1 = address */
        P2 = R2;        /* P2 = count */
        SSYNC;
@@ -65,7 +74,14 @@ ENTRY(_insl)
                [P1++] = R0;
                NOP;
 .Llong_loop_e:         NOP;
+#ifdef CONFIG_IPIPE
+       sp += -12
+       call ___ipipe_unstall_root_raw
+       sp += 12
+       rets = [sp++]
+#else
        sti R3;
+#endif
        RTS;
 #else
        P0 = R0;        /* P0 = port */
@@ -74,13 +90,28 @@ ENTRY(_insl)
        SSYNC;
        LSETUP( .Llong_loop_s, .Llong_loop_e) LC0 = P2;
 .Llong_loop_s:
+#ifdef CONFIG_IPIPE
+       [--sp] = rets
+       [--sp] = (P5:0);
+       sp += -12
+       call ___ipipe_stall_root_raw
+       sp += 12
+       (P5:0) = [sp++];
+#else
        CLI R3;
+#endif
        NOP; NOP; NOP;
        R0 = [P0];
        [P1++] = R0;
 .Llong_loop_e:
+#ifdef CONFIG_IPIPE
+       sp += -12
+       call ___ipipe_unstall_root_raw
+       sp += 12
+       rets = [sp++]
+#else
        STI R3;
-
+#endif
        RTS;
 #endif
 ENDPROC(_insl)
@@ -88,7 +119,16 @@ ENDPROC(_insl)
 ENTRY(_insw)
 #ifdef CONFIG_BFIN_INS_LOWOVERHEAD
        P0 = R0;        /* P0 = port */
+#ifdef CONFIG_IPIPE
+       [--sp] = rets
+       [--sp] = (P5:0);
+       sp += -12
+       call ___ipipe_stall_root_raw
+       sp += 12
+       (P5:0) = [sp++];
+#else
        cli R3;
+#endif
        P1 = R1;        /* P1 = address */
        P2 = R2;        /* P2 = count */
        SSYNC;
@@ -97,7 +137,14 @@ ENTRY(_insw)
                W[P1++] = R0;
                NOP;
 .Lword_loop_e:         NOP;
+#ifdef CONFIG_IPIPE
+       sp += -12
+       call ___ipipe_unstall_root_raw
+       sp += 12
+       rets = [sp++]
+#else
        sti R3;
+#endif
        RTS;
 #else
        P0 = R0;        /* P0 = port */
@@ -106,12 +153,28 @@ ENTRY(_insw)
        SSYNC;
        LSETUP( .Lword_loop_s, .Lword_loop_e) LC0 = P2;
 .Lword_loop_s:
+#ifdef CONFIG_IPIPE
+       [--sp] = rets
+       [--sp] = (P5:0);
+       sp += -12
+       call ___ipipe_stall_root_raw
+       sp += 12
+       (P5:0) = [sp++];
+#else
        CLI R3;
+#endif
        NOP; NOP; NOP;
        R0 = W[P0];
        W[P1++] = R0;
 .Lword_loop_e:
+#ifdef CONFIG_IPIPE
+       sp += -12
+       call ___ipipe_unstall_root_raw
+       sp += 12
+       rets = [sp++]
+#else
        STI R3;
+#endif
        RTS;
 
 #endif
@@ -120,7 +183,16 @@ ENDPROC(_insw)
 ENTRY(_insw_8)
 #ifdef CONFIG_BFIN_INS_LOWOVERHEAD
        P0 = R0;        /* P0 = port */
+#ifdef CONFIG_IPIPE
+       [--sp] = rets
+       [--sp] = (P5:0);
+       sp += -12
+       call ___ipipe_stall_root_raw
+       sp += 12
+       (P5:0) = [sp++];
+#else
        cli R3;
+#endif
        P1 = R1;        /* P1 = address */
        P2 = R2;        /* P2 = count */
        SSYNC;
@@ -131,7 +203,14 @@ ENTRY(_insw_8)
                B[P1++] = R0;
                NOP;
 .Lword8_loop_e: NOP;
+#ifdef CONFIG_IPIPE
+       sp += -12
+       call ___ipipe_unstall_root_raw
+       sp += 12
+       rets = [sp++]
+#else
        sti R3;
+#endif
        RTS;
 #else
        P0 = R0;        /* P0 = port */
@@ -140,7 +219,16 @@ ENTRY(_insw_8)
        SSYNC;
        LSETUP( .Lword8_loop_s, .Lword8_loop_e) LC0 = P2;
 .Lword8_loop_s:
+#ifdef CONFIG_IPIPE
+       [--sp] = rets
+       [--sp] = (P5:0);
+       sp += -12
+       call ___ipipe_stall_root_raw
+       sp += 12
+       (P5:0) = [sp++];
+#else
        CLI R3;
+#endif
        NOP; NOP; NOP;
        R0 = W[P0];
        B[P1++] = R0;
@@ -148,8 +236,14 @@ ENTRY(_insw_8)
        B[P1++] = R0;
        NOP;
 .Lword8_loop_e:
+#ifdef CONFIG_IPIPE
+       sp += -12
+       call ___ipipe_unstall_root_raw
+       sp += 12
+       rets = [sp++]
+#else
        STI R3;
-
+#endif
        RTS;
 #endif
 ENDPROC(_insw_8)
@@ -157,7 +251,16 @@ ENDPROC(_insw_8)
 ENTRY(_insb)
 #ifdef CONFIG_BFIN_INS_LOWOVERHEAD
        P0 = R0;        /* P0 = port */
+#ifdef CONFIG_IPIPE
+       [--sp] = rets
+       [--sp] = (P5:0);
+       sp += -12
+       call ___ipipe_stall_root_raw
+       sp += 12
+       (P5:0) = [sp++];
+#else
        cli R3;
+#endif
        P1 = R1;        /* P1 = address */
        P2 = R2;        /* P2 = count */
        SSYNC;
@@ -166,7 +269,14 @@ ENTRY(_insb)
                B[P1++] = R0;
                NOP;
 .Lbyte_loop_e:  NOP;
+#ifdef CONFIG_IPIPE
+       sp += -12
+       call ___ipipe_unstall_root_raw
+       sp += 12
+       rets = [sp++]
+#else
        sti R3;
+#endif
        RTS;
 #else
        P0 = R0;        /* P0 = port */
@@ -175,13 +285,28 @@ ENTRY(_insb)
        SSYNC;
        LSETUP( .Lbyte_loop_s, .Lbyte_loop_e) LC0 = P2;
 .Lbyte_loop_s:
+#ifdef CONFIG_IPIPE
+       [--sp] = rets
+       [--sp] = (P5:0);
+       sp += -12
+       call ___ipipe_stall_root_raw
+       sp += 12
+       (P5:0) = [sp++];
+#else
        CLI R3;
+#endif
        NOP; NOP; NOP;
        R0 = B[P0];
        B[P1++] = R0;
 .Lbyte_loop_e:
+#ifdef CONFIG_IPIPE
+       sp += -12
+       call ___ipipe_unstall_root_raw
+       sp += 12
+       rets = [sp++]
+#else
        STI R3;
-
+#endif
        RTS;
 #endif
 ENDPROC(_insb)
@@ -189,7 +314,16 @@ ENDPROC(_insb)
 ENTRY(_insl_16)
 #ifdef CONFIG_BFIN_INS_LOWOVERHEAD
        P0 = R0;        /* P0 = port */
+#ifdef CONFIG_IPIPE
+       [--sp] = rets
+       [--sp] = (P5:0);
+       sp += -12
+       call ___ipipe_stall_root_raw
+       sp += 12
+       (P5:0) = [sp++];
+#else
        cli R3;
+#endif
        P1 = R1;        /* P1 = address */
        P2 = R2;        /* P2 = count */
        SSYNC;
@@ -200,7 +334,14 @@ ENTRY(_insl_16)
                  W[P1++] = R0;
                  NOP;
 .Llong16_loop_e:  NOP;
+#ifdef CONFIG_IPIPE
+       sp += -12
+       call ___ipipe_unstall_root_raw
+       sp += 12
+       rets = [sp++]
+#else
        sti R3;
+#endif
        RTS;
 #else
        P0 = R0;        /* P0 = port */
@@ -209,14 +350,30 @@ ENTRY(_insl_16)
        SSYNC;
        LSETUP( .Llong16_loop_s, .Llong16_loop_e) LC0 = P2;
 .Llong16_loop_s:
+#ifdef CONFIG_IPIPE
+       [--sp] = rets
+       [--sp] = (P5:0);
+       sp += -12
+       call ___ipipe_stall_root_raw
+       sp += 12
+       (P5:0) = [sp++];
+#else
        CLI R3;
+#endif
        NOP; NOP; NOP;
        R0 = [P0];
        W[P1++] = R0;
        R0 = R0 >> 16;
        W[P1++] = R0;
 .Llong16_loop_e:
+#ifdef CONFIG_IPIPE
+       sp += -12
+       call ___ipipe_unstall_root_raw
+       sp += 12
+       rets = [sp++]
+#else
        STI R3;
+#endif
        RTS;
 #endif
 ENDPROC(_insl_16)
index 00f2d37..f397ede 100644 (file)
@@ -154,29 +154,29 @@ config IRQ_MAC_TX
 config IRQ_PORTH_INTB
        int "IRQ_PORTH_INTB"
        default 11
-config IRQ_TMR0
-       int "IRQ_TMR0"
-       default 12
-config IRQ_TMR1
-       int "IRQ_TMR1"
+config IRQ_TIMER0
+       int "IRQ_TIMER0"
+       default 8
+config IRQ_TIMER1
+       int "IRQ_TIMER1"
        default 12
-config IRQ_TMR2
-       int "IRQ_TMR2"
+config IRQ_TIMER2
+       int "IRQ_TIMER2"
        default 12
-config IRQ_TMR3
-       int "IRQ_TMR3"
+config IRQ_TIMER3
+       int "IRQ_TIMER3"
        default 12
-config IRQ_TMR4
-       int "IRQ_TMR4"
+config IRQ_TIMER4
+       int "IRQ_TIMER4"
        default 12
-config IRQ_TMR5
-       int "IRQ_TMR5"
+config IRQ_TIMER5
+       int "IRQ_TIMER5"
        default 12
-config IRQ_TMR6
-       int "IRQ_TMR6"
+config IRQ_TIMER6
+       int "IRQ_TIMER6"
        default 12
-config IRQ_TMR7
-       int "IRQ_TMR7"
+config IRQ_TIMER7
+       int "IRQ_TIMER7"
        default 12
 config IRQ_PORTG_INTA
        int "IRQ_PORTG_INTA"
index 9fbcd22..ee3d473 100644 (file)
@@ -1163,7 +1163,7 @@ static __inline__ void bfin_write_PLL_CTL(unsigned int val)
        if (val == bfin_read_PLL_CTL())
                return;
 
-       local_irq_save(flags);
+       local_irq_save_hw(flags);
        /* Enable the PLL Wakeup bit in SIC IWR */
        iwr0 = bfin_read32(SIC_IWR0);
        iwr1 = bfin_read32(SIC_IWR1);
@@ -1177,7 +1177,7 @@ static __inline__ void bfin_write_PLL_CTL(unsigned int val)
 
        bfin_write32(SIC_IWR0, iwr0);
        bfin_write32(SIC_IWR1, iwr1);
-       local_irq_restore(flags);
+       local_irq_restore_hw(flags);
 }
 
 /* Writing to VR_CTL initiates a PLL relock sequence. */
@@ -1188,7 +1188,7 @@ static __inline__ void bfin_write_VR_CTL(unsigned int val)
        if (val == bfin_read_VR_CTL())
                return;
 
-       local_irq_save(flags);
+       local_irq_save_hw(flags);
        /* Enable the PLL Wakeup bit in SIC IWR */
        iwr0 = bfin_read32(SIC_IWR0);
        iwr1 = bfin_read32(SIC_IWR1);
@@ -1202,7 +1202,7 @@ static __inline__ void bfin_write_VR_CTL(unsigned int val)
 
        bfin_write32(SIC_IWR0, iwr0);
        bfin_write32(SIC_IWR1, iwr1);
-       local_irq_restore(flags);
+       local_irq_restore_hw(flags);
 }
 
 #endif /* _CDEF_BF52X_H */
index e5062f1..3ff0f09 100644 (file)
 #define IRQ_PORTH_INTA         BFIN_IRQ(29)    /* Port H Interrupt A */
 #define IRQ_MAC_TX             BFIN_IRQ(30)    /* DMA2 Channel (MAC TX) */
 #define IRQ_PORTH_INTB         BFIN_IRQ(31)    /* Port H Interrupt B */
-#define IRQ_TMR0               BFIN_IRQ(32)    /* Timer 0 */
-#define IRQ_TMR1               BFIN_IRQ(33)    /* Timer 1 */
-#define IRQ_TMR2               BFIN_IRQ(34)    /* Timer 2 */
-#define IRQ_TMR3               BFIN_IRQ(35)    /* Timer 3 */
-#define IRQ_TMR4               BFIN_IRQ(36)    /* Timer 4 */
-#define IRQ_TMR5               BFIN_IRQ(37)    /* Timer 5 */
-#define IRQ_TMR6               BFIN_IRQ(38)    /* Timer 6 */
-#define IRQ_TMR7               BFIN_IRQ(39)    /* Timer 7 */
+#define IRQ_TIMER0             BFIN_IRQ(32)    /* Timer 0 */
+#define IRQ_TIMER1             BFIN_IRQ(33)    /* Timer 1 */
+#define IRQ_TIMER2             BFIN_IRQ(34)    /* Timer 2 */
+#define IRQ_TIMER3             BFIN_IRQ(35)    /* Timer 3 */
+#define IRQ_TIMER4             BFIN_IRQ(36)    /* Timer 4 */
+#define IRQ_TIMER5             BFIN_IRQ(37)    /* Timer 5 */
+#define IRQ_TIMER6             BFIN_IRQ(38)    /* Timer 6 */
+#define IRQ_TIMER7             BFIN_IRQ(39)    /* Timer 7 */
 #define IRQ_PORTG_INTA         BFIN_IRQ(40)    /* Port G Interrupt A */
 #define IRQ_PORTG_INTB         BFIN_IRQ(41)    /* Port G Interrupt B */
 #define IRQ_MEM_DMA0           BFIN_IRQ(42)    /* MDMA Stream 0 */
 #define IRQ_PORTH_INTB_POS     28
 
 /* IAR4 BIT FIELDS */
-#define IRQ_TMR0_POS           0
-#define IRQ_TMR1_POS           4
-#define IRQ_TMR2_POS           8
-#define IRQ_TMR3_POS           12
-#define IRQ_TMR4_POS           16
-#define IRQ_TMR5_POS           20
-#define IRQ_TMR6_POS           24
-#define IRQ_TMR7_POS           28
+#define IRQ_TIMER0_POS         0
+#define IRQ_TIMER1_POS         4
+#define IRQ_TIMER2_POS         8
+#define IRQ_TIMER3_POS         12
+#define IRQ_TIMER4_POS         16
+#define IRQ_TIMER5_POS         20
+#define IRQ_TIMER6_POS         24
+#define IRQ_TIMER7_POS         28
 
 /* IAR5 BIT FIELDS */
 #define IRQ_PORTG_INTA_POS     0
index c490c79..3151fd5 100644 (file)
@@ -70,14 +70,14 @@ void __init program_IAR(void)
                        ((CONFIG_IRQ_MAC_TX - 7) << IRQ_MAC_TX_POS) |
                        ((CONFIG_IRQ_PORTH_INTB - 7) << IRQ_PORTH_INTB_POS));
 
-       bfin_write_SIC_IAR4(((CONFIG_IRQ_TMR0 - 7) << IRQ_TMR0_POS) |
-                       ((CONFIG_IRQ_TMR1 - 7) << IRQ_TMR1_POS) |
-                       ((CONFIG_IRQ_TMR2 - 7) << IRQ_TMR2_POS) |
-                       ((CONFIG_IRQ_TMR3 - 7) << IRQ_TMR3_POS) |
-                       ((CONFIG_IRQ_TMR4 - 7) << IRQ_TMR4_POS) |
-                       ((CONFIG_IRQ_TMR5 - 7) << IRQ_TMR5_POS) |
-                       ((CONFIG_IRQ_TMR6 - 7) << IRQ_TMR6_POS) |
-                       ((CONFIG_IRQ_TMR7 - 7) << IRQ_TMR7_POS));
+       bfin_write_SIC_IAR4(((CONFIG_IRQ_TIMER0 - 7) << IRQ_TIMER0_POS) |
+                       ((CONFIG_IRQ_TIMER1 - 7) << IRQ_TIMER1_POS) |
+                       ((CONFIG_IRQ_TIMER2 - 7) << IRQ_TIMER2_POS) |
+                       ((CONFIG_IRQ_TIMER3 - 7) << IRQ_TIMER3_POS) |
+                       ((CONFIG_IRQ_TIMER4 - 7) << IRQ_TIMER4_POS) |
+                       ((CONFIG_IRQ_TIMER5 - 7) << IRQ_TIMER5_POS) |
+                       ((CONFIG_IRQ_TIMER6 - 7) << IRQ_TIMER6_POS) |
+                       ((CONFIG_IRQ_TIMER7 - 7) << IRQ_TIMER7_POS));
 
        bfin_write_SIC_IAR5(((CONFIG_IRQ_PORTG_INTA - 7) << IRQ_PORTG_INTA_POS) |
                        ((CONFIG_IRQ_PORTG_INTB - 7) << IRQ_PORTG_INTB_POS) |
index 3cde4be..8438ec6 100644 (file)
@@ -168,29 +168,29 @@ config IRQ_MAC_TX
 config IRQ_PORTH_INTB
        int "IRQ_PORTH_INTB"
        default 11
-config IRQ_TMR0
-       int "IRQ_TMR0"
-       default 12
-config IRQ_TMR1
-       int "IRQ_TMR1"
+config IRQ_TIMER0
+       int "IRQ_TIMER0"
+       default 8
+config IRQ_TIMER1
+       int "IRQ_TIMER1"
        default 12
-config IRQ_TMR2
-       int "IRQ_TMR2"
+config IRQ_TIMER2
+       int "IRQ_TIMER2"
        default 12
-config IRQ_TMR3
-       int "IRQ_TMR3"
+config IRQ_TIMER3
+       int "IRQ_TIMER3"
        default 12
-config IRQ_TMR4
-       int "IRQ_TMR4"
+config IRQ_TIMER4
+       int "IRQ_TIMER4"
        default 12
-config IRQ_TMR5
-       int "IRQ_TMR5"
+config IRQ_TIMER5
+       int "IRQ_TIMER5"
        default 12
-config IRQ_TMR6
-       int "IRQ_TMR6"
+config IRQ_TIMER6
+       int "IRQ_TIMER6"
        default 12
-config IRQ_TMR7
-       int "IRQ_TMR7"
+config IRQ_TIMER7
+       int "IRQ_TIMER7"
        default 12
 config IRQ_PORTG_INTA
        int "IRQ_PORTG_INTA"
index 8a374c3..1fe76d8 100644 (file)
@@ -1163,7 +1163,7 @@ static __inline__ void bfin_write_PLL_CTL(unsigned int val)
        if (val == bfin_read_PLL_CTL())
                return;
 
-       local_irq_save(flags);
+       local_irq_save_hw(flags);
        /* Enable the PLL Wakeup bit in SIC IWR */
        iwr0 = bfin_read32(SIC_IWR0);
        iwr1 = bfin_read32(SIC_IWR1);
@@ -1177,7 +1177,7 @@ static __inline__ void bfin_write_PLL_CTL(unsigned int val)
 
        bfin_write32(SIC_IWR0, iwr0);
        bfin_write32(SIC_IWR1, iwr1);
-       local_irq_restore(flags);
+       local_irq_restore_hw(flags);
 }
 
 /* Writing to VR_CTL initiates a PLL relock sequence. */
@@ -1188,7 +1188,7 @@ static __inline__ void bfin_write_VR_CTL(unsigned int val)
        if (val == bfin_read_VR_CTL())
                return;
 
-       local_irq_save(flags);
+       local_irq_save_hw(flags);
        /* Enable the PLL Wakeup bit in SIC IWR */
        iwr0 = bfin_read32(SIC_IWR0);
        iwr1 = bfin_read32(SIC_IWR1);
@@ -1202,7 +1202,7 @@ static __inline__ void bfin_write_VR_CTL(unsigned int val)
 
        bfin_write32(SIC_IWR0, iwr0);
        bfin_write32(SIC_IWR1, iwr1);
-       local_irq_restore(flags);
+       local_irq_restore_hw(flags);
 }
 
 #endif /* _CDEF_BF52X_H */
index 4e2b3f2..8ea660d 100644 (file)
 #define IRQ_MAC_TX             BFIN_IRQ(30)    /* DMA2 Channel (MAC TX/NAND) */
 #define IRQ_NFC                        BFIN_IRQ(30)    /* DMA2 Channel (MAC TX/NAND) */
 #define IRQ_PORTH_INTB         BFIN_IRQ(31)    /* Port H Interrupt B */
-#define IRQ_TMR0               BFIN_IRQ(32)    /* Timer 0 */
-#define IRQ_TMR1               BFIN_IRQ(33)    /* Timer 1 */
-#define IRQ_TMR2               BFIN_IRQ(34)    /* Timer 2 */
-#define IRQ_TMR3               BFIN_IRQ(35)    /* Timer 3 */
-#define IRQ_TMR4               BFIN_IRQ(36)    /* Timer 4 */
-#define IRQ_TMR5               BFIN_IRQ(37)    /* Timer 5 */
-#define IRQ_TMR6               BFIN_IRQ(38)    /* Timer 6 */
-#define IRQ_TMR7               BFIN_IRQ(39)    /* Timer 7 */
+#define IRQ_TIMER0             BFIN_IRQ(32)    /* Timer 0 */
+#define IRQ_TIMER1             BFIN_IRQ(33)    /* Timer 1 */
+#define IRQ_TIMER2             BFIN_IRQ(34)    /* Timer 2 */
+#define IRQ_TIMER3             BFIN_IRQ(35)    /* Timer 3 */
+#define IRQ_TIMER4             BFIN_IRQ(36)    /* Timer 4 */
+#define IRQ_TIMER5             BFIN_IRQ(37)    /* Timer 5 */
+#define IRQ_TIMER6             BFIN_IRQ(38)    /* Timer 6 */
+#define IRQ_TIMER7             BFIN_IRQ(39)    /* Timer 7 */
 #define IRQ_PORTG_INTA         BFIN_IRQ(40)    /* Port G Interrupt A */
 #define IRQ_PORTG_INTB         BFIN_IRQ(41)    /* Port G Interrupt B */
 #define IRQ_MEM_DMA0           BFIN_IRQ(42)    /* MDMA Stream 0 */
 #define IRQ_PORTH_INTB_POS     28
 
 /* IAR4 BIT FIELDS */
-#define IRQ_TMR0_POS           0
-#define IRQ_TMR1_POS           4
-#define IRQ_TMR2_POS           8
-#define IRQ_TMR3_POS           12
-#define IRQ_TMR4_POS           16
-#define IRQ_TMR5_POS           20
-#define IRQ_TMR6_POS           24
-#define IRQ_TMR7_POS           28
+#define IRQ_TIMER0_POS         0
+#define IRQ_TIMER1_POS         4
+#define IRQ_TIMER2_POS         8
+#define IRQ_TIMER3_POS         12
+#define IRQ_TIMER4_POS         16
+#define IRQ_TIMER5_POS         20
+#define IRQ_TIMER6_POS         24
+#define IRQ_TIMER7_POS         28
 
 /* IAR5 BIT FIELDS */
 #define IRQ_PORTG_INTA_POS     0
index 8a23674..f8c8acd 100644 (file)
@@ -69,14 +69,14 @@ void __init program_IAR(void)
                        ((CONFIG_IRQ_MAC_TX - 7) << IRQ_MAC_TX_POS) |
                        ((CONFIG_IRQ_PORTH_INTB - 7) << IRQ_PORTH_INTB_POS));
 
-       bfin_write_SIC_IAR4(((CONFIG_IRQ_TMR0 - 7) << IRQ_TMR0_POS) |
-                       ((CONFIG_IRQ_TMR1 - 7) << IRQ_TMR1_POS) |
-                       ((CONFIG_IRQ_TMR2 - 7) << IRQ_TMR2_POS) |
-                       ((CONFIG_IRQ_TMR3 - 7) << IRQ_TMR3_POS) |
-                       ((CONFIG_IRQ_TMR4 - 7) << IRQ_TMR4_POS) |
-                       ((CONFIG_IRQ_TMR5 - 7) << IRQ_TMR5_POS) |
-                       ((CONFIG_IRQ_TMR6 - 7) << IRQ_TMR6_POS) |
-                       ((CONFIG_IRQ_TMR7 - 7) << IRQ_TMR7_POS));
+       bfin_write_SIC_IAR4(((CONFIG_IRQ_TIMER0 - 7) << IRQ_TIMER0_POS) |
+                       ((CONFIG_IRQ_TIMER1 - 7) << IRQ_TIMER1_POS) |
+                       ((CONFIG_IRQ_TIMER2 - 7) << IRQ_TIMER2_POS) |
+                       ((CONFIG_IRQ_TIMER3 - 7) << IRQ_TIMER3_POS) |
+                       ((CONFIG_IRQ_TIMER4 - 7) << IRQ_TIMER4_POS) |
+                       ((CONFIG_IRQ_TIMER5 - 7) << IRQ_TIMER5_POS) |
+                       ((CONFIG_IRQ_TIMER6 - 7) << IRQ_TIMER6_POS) |
+                       ((CONFIG_IRQ_TIMER7 - 7) << IRQ_TIMER7_POS));
 
        bfin_write_SIC_IAR5(((CONFIG_IRQ_PORTG_INTA - 7) << IRQ_PORTG_INTA_POS) |
                        ((CONFIG_IRQ_PORTG_INTB - 7) << IRQ_PORTG_INTB_POS) |
index 76beb75..14427de 100644 (file)
@@ -59,7 +59,7 @@ config DMA7_UARTTX
        default 10
 config TIMER0
        int "TIMER0"
-       default 11
+       default 8
 config TIMER1
        int "TIMER1"
        default 11
index d7b08f6..bbc3c83 100644 (file)
 static inline void bfin_write_FIO_FLAG_##name(unsigned short val) \
 { \
        unsigned long flags; \
-       local_irq_save(flags); \
+       local_irq_save_hw(flags); \
        bfin_write16(FIO_FLAG_##name, val); \
        bfin_read_CHIPID(); \
-       local_irq_restore(flags); \
+       local_irq_restore_hw(flags); \
 }
 BFIN_WRITE_FIO_FLAG(D)
 BFIN_WRITE_FIO_FLAG(C)
@@ -699,10 +699,10 @@ static inline u16 bfin_read_FIO_FLAG_##name(void) \
 { \
        unsigned long flags; \
        u16 ret; \
-       local_irq_save(flags); \
+       local_irq_save_hw(flags); \
        ret = bfin_read16(FIO_FLAG_##name); \
        bfin_read_CHIPID(); \
-       local_irq_restore(flags); \
+       local_irq_restore_hw(flags); \
        return ret; \
 }
 BFIN_READ_FIO_FLAG(D)
@@ -729,7 +729,7 @@ static __inline__ void bfin_write_PLL_CTL(unsigned int val)
        if (val == bfin_read_PLL_CTL())
                return;
 
-       local_irq_save(flags);
+       local_irq_save_hw(flags);
        /* Enable the PLL Wakeup bit in SIC IWR */
        iwr = bfin_read32(SIC_IWR);
        /* Only allow PPL Wakeup) */
@@ -740,7 +740,7 @@ static __inline__ void bfin_write_PLL_CTL(unsigned int val)
        asm("IDLE;");
 
        bfin_write32(SIC_IWR, iwr);
-       local_irq_restore(flags);
+       local_irq_restore_hw(flags);
 }
 
 /* Writing to VR_CTL initiates a PLL relock sequence. */
@@ -751,7 +751,7 @@ static __inline__ void bfin_write_VR_CTL(unsigned int val)
        if (val == bfin_read_VR_CTL())
                return;
 
-       local_irq_save(flags);
+       local_irq_save_hw(flags);
        /* Enable the PLL Wakeup bit in SIC IWR */
        iwr = bfin_read32(SIC_IWR);
        /* Only allow PPL Wakeup) */
@@ -762,7 +762,7 @@ static __inline__ void bfin_write_VR_CTL(unsigned int val)
        asm("IDLE;");
 
        bfin_write32(SIC_IWR, iwr);
-       local_irq_restore(flags);
+       local_irq_restore_hw(flags);
 }
 
 #endif                         /* _CDEF_BF532_H */
index e7dd315..db1e346 100644 (file)
@@ -100,9 +100,9 @@ Core        Emulation               **
 #define        IRQ_SPI                 20      /*DMA5 Interrupt (SPI) */
 #define        IRQ_UART0_RX            21      /*DMA6 Interrupt (UART RX) */
 #define        IRQ_UART0_TX            22      /*DMA7 Interrupt (UART TX) */
-#define        IRQ_TMR0                23      /*Timer 0 */
-#define        IRQ_TMR1                24      /*Timer 1 */
-#define        IRQ_TMR2                25      /*Timer 2 */
+#define        IRQ_TIMER0              23      /*Timer 0 */
+#define        IRQ_TIMER1              24      /*Timer 1 */
+#define        IRQ_TIMER2              25      /*Timer 2 */
 #define        IRQ_PROG_INTA           26      /*Programmable Flags A (8) */
 #define        IRQ_PROG_INTB           27      /*Programmable Flags B (8) */
 #define        IRQ_MEM_DMA0            28      /*DMA8/9 Interrupt (Memory DMA Stream 0) */
index 8255374..bbc08fd 100644 (file)
@@ -64,29 +64,29 @@ config IRQ_MAC_RX
 config IRQ_MAC_TX
        int "IRQ_MAC_TX"
        default 11
-config IRQ_TMR0
-       int "IRQ_TMR0"
-       default 12
-config IRQ_TMR1
-       int "IRQ_TMR1"
+config IRQ_TIMER0
+       int "IRQ_TIMER0"
+       default 8
+config IRQ_TIMER1
+       int "IRQ_TIMER1"
        default 12
-config IRQ_TMR2
-       int "IRQ_TMR2"
+config IRQ_TIMER2
+       int "IRQ_TIMER2"
        default 12
-config IRQ_TMR3
-       int "IRQ_TMR3"
+config IRQ_TIMER3
+       int "IRQ_TIMER3"
        default 12
-config IRQ_TMR4
-       int "IRQ_TMR4"
+config IRQ_TIMER4
+       int "IRQ_TIMER4"
        default 12
-config IRQ_TMR5
-       int "IRQ_TMR5"
+config IRQ_TIMER5
+       int "IRQ_TIMER5"
        default 12
-config IRQ_TMR6
-       int "IRQ_TMR6"
+config IRQ_TIMER6
+       int "IRQ_TIMER6"
        default 12
-config IRQ_TMR7
-       int "IRQ_TMR7"
+config IRQ_TIMER7
+       int "IRQ_TIMER7"
        default 12
 config IRQ_PROG_INTA
        int "IRQ_PROG_INTA"
index f341692..5f8b5f8 100644 (file)
@@ -1783,7 +1783,7 @@ static __inline__ void bfin_write_PLL_CTL(unsigned int val)
        if (val == bfin_read_PLL_CTL())
                return;
 
-       local_irq_save(flags);
+       local_irq_save_hw(flags);
        /* Enable the PLL Wakeup bit in SIC IWR */
        iwr = bfin_read32(SIC_IWR);
        /* Only allow PPL Wakeup) */
@@ -1794,7 +1794,7 @@ static __inline__ void bfin_write_PLL_CTL(unsigned int val)
        asm("IDLE;");
 
        bfin_write32(SIC_IWR, iwr);
-       local_irq_restore(flags);
+       local_irq_restore_hw(flags);
 }
 
 /* Writing to VR_CTL initiates a PLL relock sequence. */
@@ -1805,7 +1805,7 @@ static __inline__ void bfin_write_VR_CTL(unsigned int val)
        if (val == bfin_read_VR_CTL())
                return;
 
-       local_irq_save(flags);
+       local_irq_save_hw(flags);
        /* Enable the PLL Wakeup bit in SIC IWR */
        iwr = bfin_read32(SIC_IWR);
        /* Only allow PPL Wakeup) */
@@ -1816,7 +1816,7 @@ static __inline__ void bfin_write_VR_CTL(unsigned int val)
        asm("IDLE;");
 
        bfin_write32(SIC_IWR, iwr);
-       local_irq_restore(flags);
+       local_irq_restore_hw(flags);
 }
 
 #endif                         /* _CDEF_BF534_H */
index 2e68a8a..b2a71d5 100644 (file)
 #define IRQ_CAN_TX          23 /*CAN Transmit Interrupt */
 #define IRQ_MAC_RX          24 /*DMA1 (Ethernet RX) Interrupt */
 #define IRQ_MAC_TX          25 /*DMA2 (Ethernet TX) Interrupt */
-#define IRQ_TMR0            26 /*Timer 0 */
-#define IRQ_TMR1            27 /*Timer 1 */
-#define IRQ_TMR2            28 /*Timer 2 */
-#define IRQ_TMR3            29 /*Timer 3 */
-#define IRQ_TMR4            30 /*Timer 4 */
-#define IRQ_TMR5            31 /*Timer 5 */
-#define IRQ_TMR6            32 /*Timer 6 */
-#define IRQ_TMR7            33 /*Timer 7 */
+#define IRQ_TIMER0            26       /*Timer 0 */
+#define IRQ_TIMER1            27       /*Timer 1 */
+#define IRQ_TIMER2            28       /*Timer 2 */
+#define IRQ_TIMER3            29       /*Timer 3 */
+#define IRQ_TIMER4            30       /*Timer 4 */
+#define IRQ_TIMER5            31       /*Timer 5 */
+#define IRQ_TIMER6            32       /*Timer 6 */
+#define IRQ_TIMER7            33       /*Timer 7 */
 #define IRQ_PROG_INTA       34 /* PF Ports F&G (PF15:0) Interrupt A */
 #define IRQ_PORTG_INTB      35 /* PF Port G (PF15:0) Interrupt B */
 #define IRQ_MEM_DMA0        36 /*(Memory DMA Stream 0) */
 #define IRQ_CAN_TX_POS      0
 #define IRQ_MAC_RX_POS      4
 #define IRQ_MAC_TX_POS      8
-#define IRQ_TMR0_POS        12
-#define IRQ_TMR1_POS        16
-#define IRQ_TMR2_POS        20
-#define IRQ_TMR3_POS        24
-#define IRQ_TMR4_POS        28
+#define IRQ_TIMER0_POS        12
+#define IRQ_TIMER1_POS        16
+#define IRQ_TIMER2_POS        20
+#define IRQ_TIMER3_POS        24
+#define IRQ_TIMER4_POS        28
 
 /* IAR3 BIT FIELDS*/
-#define IRQ_TMR5_POS        0
-#define IRQ_TMR6_POS        4
-#define IRQ_TMR7_POS        8
+#define IRQ_TIMER5_POS        0
+#define IRQ_TIMER6_POS        4
+#define IRQ_TIMER7_POS        8
 #define IRQ_PROG_INTA_POS   12
 #define IRQ_PORTG_INTB_POS   16
 #define IRQ_MEM_DMA0_POS    20
index b1300b3..51c4808 100644 (file)
@@ -55,15 +55,15 @@ void __init program_IAR(void)
        bfin_write_SIC_IAR2(((CONFIG_IRQ_CAN_TX - 7) << IRQ_CAN_TX_POS) |
                            ((CONFIG_IRQ_MAC_RX - 7) << IRQ_MAC_RX_POS) |
                            ((CONFIG_IRQ_MAC_TX - 7) << IRQ_MAC_TX_POS) |
-                           ((CONFIG_IRQ_TMR0 - 7) << IRQ_TMR0_POS) |
-                           ((CONFIG_IRQ_TMR1 - 7) << IRQ_TMR1_POS) |
-                           ((CONFIG_IRQ_TMR2 - 7) << IRQ_TMR2_POS) |
-                           ((CONFIG_IRQ_TMR3 - 7) << IRQ_TMR3_POS) |
-                           ((CONFIG_IRQ_TMR4 - 7) << IRQ_TMR4_POS));
+                           ((CONFIG_IRQ_TIMER0 - 7) << IRQ_TIMER0_POS) |
+                           ((CONFIG_IRQ_TIMER1 - 7) << IRQ_TIMER1_POS) |
+                           ((CONFIG_IRQ_TIMER2 - 7) << IRQ_TIMER2_POS) |
+                           ((CONFIG_IRQ_TIMER3 - 7) << IRQ_TIMER3_POS) |
+                           ((CONFIG_IRQ_TIMER4 - 7) << IRQ_TIMER4_POS));
 
-       bfin_write_SIC_IAR3(((CONFIG_IRQ_TMR5 - 7) << IRQ_TMR5_POS) |
-                           ((CONFIG_IRQ_TMR6 - 7) << IRQ_TMR6_POS) |
-                           ((CONFIG_IRQ_TMR7 - 7) << IRQ_TMR7_POS) |
+       bfin_write_SIC_IAR3(((CONFIG_IRQ_TIMER5 - 7) << IRQ_TIMER5_POS) |
+                           ((CONFIG_IRQ_TIMER6 - 7) << IRQ_TIMER6_POS) |
+                           ((CONFIG_IRQ_TIMER7 - 7) << IRQ_TIMER7_POS) |
                            ((CONFIG_IRQ_PROG_INTA - 7) << IRQ_PROG_INTA_POS) |
                            ((CONFIG_IRQ_PORTG_INTB - 7) << IRQ_PORTG_INTB_POS) |
                            ((CONFIG_IRQ_MEM_DMA0 - 7) << IRQ_MEM_DMA0_POS) |
index a6f3307..f068c35 100644 (file)
@@ -55,14 +55,14 @@ config IRQ_UART0_RX
 config IRQ_UART0_TX
        int "IRQ_UART0_TX"
        default 10
-config IRQ_TMR0
-       int "IRQ_TMR0"
-       default 11
-config IRQ_TMR1
-       int "IRQ_TMR1"
+config IRQ_TIMER0
+       int "IRQ_TIMER0"
+       default 8
+config IRQ_TIMER1
+       int "IRQ_TIMER1"
        default 11
-config IRQ_TMR2
-       int "IRQ_TMR2"
+config IRQ_TIMER2
+       int "IRQ_TIMER2"
        default 11
 config IRQ_PORTF_INTA
        int "IRQ_PORTF_INTA"
index 7e469b8..241725b 100644 (file)
@@ -2063,7 +2063,7 @@ static __inline__ void bfin_write_PLL_CTL(unsigned int val)
        if (val == bfin_read_PLL_CTL())
                return;
 
-       local_irq_save(flags);
+       local_irq_save_hw(flags);
        /* Enable the PLL Wakeup bit in SIC IWR */
        iwr0 = bfin_read32(SIC_IWR0);
        iwr1 = bfin_read32(SIC_IWR1);
@@ -2077,7 +2077,7 @@ static __inline__ void bfin_write_PLL_CTL(unsigned int val)
 
        bfin_write32(SIC_IWR0, iwr0);
        bfin_write32(SIC_IWR1, iwr1);
-       local_irq_restore(flags);
+       local_irq_restore_hw(flags);
 }
 
 /* Writing to VR_CTL initiates a PLL relock sequence. */
@@ -2088,7 +2088,7 @@ static __inline__ void bfin_write_VR_CTL(unsigned int val)
        if (val == bfin_read_VR_CTL())
                return;
 
-       local_irq_save(flags);
+       local_irq_save_hw(flags);
        /* Enable the PLL Wakeup bit in SIC IWR */
        iwr0 = bfin_read32(SIC_IWR0);
        iwr1 = bfin_read32(SIC_IWR1);
@@ -2102,7 +2102,7 @@ static __inline__ void bfin_write_VR_CTL(unsigned int val)
 
        bfin_write32(SIC_IWR0, iwr0);
        bfin_write32(SIC_IWR1, iwr1);
-       local_irq_restore(flags);
+       local_irq_restore_hw(flags);
 }
 
 #endif
index 60bdac4..fdc87fe 100644 (file)
@@ -81,9 +81,9 @@
 #define IRQ_SPI0               BFIN_IRQ(13)    /* DMA 5 Channel (SPI0) */
 #define IRQ_UART0_RX           BFIN_IRQ(14)    /* DMA 6 Channel (UART0 RX) */
 #define IRQ_UART0_TX           BFIN_IRQ(15)    /* DMA 7 Channel (UART0 TX) */
-#define IRQ_TMR0               BFIN_IRQ(16)    /* Timer 0 */
-#define IRQ_TMR1               BFIN_IRQ(17)    /* Timer 1 */
-#define IRQ_TMR2               BFIN_IRQ(18)    /* Timer 2 */
+#define IRQ_TIMER0             BFIN_IRQ(16)    /* Timer 0 */
+#define IRQ_TIMER1             BFIN_IRQ(17)    /* Timer 1 */
+#define IRQ_TIMER2             BFIN_IRQ(18)    /* Timer 2 */
 #define IRQ_PORTF_INTA         BFIN_IRQ(19)    /* Port F Interrupt A */
 #define IRQ_PORTF_INTB         BFIN_IRQ(20)    /* Port F Interrupt B */
 #define IRQ_MEM0_DMA0          BFIN_IRQ(21)    /* MDMA0 Stream 0 */
 #define IRQ_UART0_TX_POS       28
 
 /* IAR2 BIT FIELDS */
-#define IRQ_TMR0_POS           0
-#define IRQ_TMR1_POS           4
-#define IRQ_TMR2_POS           8
+#define IRQ_TIMER0_POS         0
+#define IRQ_TIMER1_POS         4
+#define IRQ_TIMER2_POS         8
 #define IRQ_PORTF_INTA_POS     12
 #define IRQ_PORTF_INTB_POS     16
 #define IRQ_MEM0_DMA0_POS      20
index f81f2ac..70d17e5 100644 (file)
@@ -53,9 +53,9 @@ void __init program_IAR(void)
                        ((CONFIG_IRQ_UART0_RX - 7) << IRQ_UART0_RX_POS) |
                        ((CONFIG_IRQ_UART0_TX - 7) << IRQ_UART0_TX_POS));
 
-       bfin_write_SIC_IAR2(((CONFIG_IRQ_TMR0 - 7) << IRQ_TMR0_POS) |
-                       ((CONFIG_IRQ_TMR1 - 7) << IRQ_TMR1_POS) |
-                       ((CONFIG_IRQ_TMR2 - 7) << IRQ_TMR2_POS) |
+       bfin_write_SIC_IAR2(((CONFIG_IRQ_TIMER0 - 7) << IRQ_TIMER0_POS) |
+                       ((CONFIG_IRQ_TIMER1 - 7) << IRQ_TIMER1_POS) |
+                       ((CONFIG_IRQ_TIMER2 - 7) << IRQ_TIMER2_POS) |
                        ((CONFIG_IRQ_PORTF_INTA - 7) << IRQ_PORTF_INTA_POS) |
                        ((CONFIG_IRQ_PORTF_INTB - 7) << IRQ_PORTF_INTB_POS) |
                        ((CONFIG_IRQ_MEM0_DMA0 - 7) << IRQ_MEM0_DMA0_POS) |
index 1bfcd8f..dcf6571 100644 (file)
@@ -250,7 +250,7 @@ config IRQ_OTPSEC
        default 11
 config IRQ_TIMER0
        int "IRQ_TIMER0"
-       default 11
+       default 8
 config IRQ_TIMER1
        int "IRQ_TIMER1"
        default 11
index 0a3b210..6e636c4 100644 (file)
@@ -2702,7 +2702,7 @@ static __inline__ void bfin_write_PLL_CTL(unsigned int val)
        if (val == bfin_read_PLL_CTL())
                return;
 
-       local_irq_save(flags);
+       local_irq_save_hw(flags);
        /* Enable the PLL Wakeup bit in SIC IWR */
        iwr0 = bfin_read32(SIC_IWR0);
        iwr1 = bfin_read32(SIC_IWR1);
@@ -2719,7 +2719,7 @@ static __inline__ void bfin_write_PLL_CTL(unsigned int val)
        bfin_write32(SIC_IWR0, iwr0);
        bfin_write32(SIC_IWR1, iwr1);
        bfin_write32(SIC_IWR2, iwr2);
-       local_irq_restore(flags);
+       local_irq_restore_hw(flags);
 }
 
 /* Writing to VR_CTL initiates a PLL relock sequence. */
@@ -2730,7 +2730,7 @@ static __inline__ void bfin_write_VR_CTL(unsigned int val)
        if (val == bfin_read_VR_CTL())
                return;
 
-       local_irq_save(flags);
+       local_irq_save_hw(flags);
        /* Enable the PLL Wakeup bit in SIC IWR */
        iwr0 = bfin_read32(SIC_IWR0);
        iwr1 = bfin_read32(SIC_IWR1);
@@ -2747,7 +2747,7 @@ static __inline__ void bfin_write_VR_CTL(unsigned int val)
        bfin_write32(SIC_IWR0, iwr0);
        bfin_write32(SIC_IWR1, iwr1);
        bfin_write32(SIC_IWR2, iwr2);
-       local_irq_restore(flags);
+       local_irq_restore_hw(flags);
 }
 
 #endif /* _CDEF_BF54X_H */
index ad380d1..60299a7 100644 (file)
@@ -158,7 +158,7 @@ Events         (highest priority)  EMU         0
 #define IRQ_PINT2              BFIN_IRQ(94)    /* PINT2 Interrupt */
 #define IRQ_PINT3              BFIN_IRQ(95)    /* PINT3 Interrupt */
 
-#define SYS_IRQS               IRQ_PINT3
+#define SYS_IRQS               IRQ_PINT3
 
 #define BFIN_PA_IRQ(x)         ((x) + SYS_IRQS + 1)
 #define IRQ_PA0                        BFIN_PA_IRQ(0)
index 5d56438..638ec38 100644 (file)
@@ -138,7 +138,7 @@ config IRQ_DMA2_11
        default 9
 config IRQ_TIMER0
        int "TIMER 0  Interrupt"
-       default 10
+       default 8
 config IRQ_TIMER1
        int "TIMER 1  Interrupt"
        default 10
index b16875d..95d609f 100644 (file)
@@ -1537,7 +1537,7 @@ static __inline__ void bfin_write_PLL_CTL(unsigned int val)
        if (val == bfin_read_PLL_CTL())
                return;
 
-       local_irq_save(flags);
+       local_irq_save_hw(flags);
        /* Enable the PLL Wakeup bit in SIC IWR */
        iwr0 = bfin_read32(SICA_IWR0);
        iwr1 = bfin_read32(SICA_IWR1);
@@ -1551,7 +1551,7 @@ static __inline__ void bfin_write_PLL_CTL(unsigned int val)
 
        bfin_write32(SICA_IWR0, iwr0);
        bfin_write32(SICA_IWR1, iwr1);
-       local_irq_restore(flags);
+       local_irq_restore_hw(flags);
 }
 
 /* Writing to VR_CTL initiates a PLL relock sequence. */
@@ -1562,7 +1562,7 @@ static __inline__ void bfin_write_VR_CTL(unsigned int val)
        if (val == bfin_read_VR_CTL())
                return;
 
-       local_irq_save(flags);
+       local_irq_save_hw(flags);
        /* Enable the PLL Wakeup bit in SIC IWR */
        iwr0 = bfin_read32(SICA_IWR0);
        iwr1 = bfin_read32(SICA_IWR1);
@@ -1576,7 +1576,7 @@ static __inline__ void bfin_write_VR_CTL(unsigned int val)
 
        bfin_write32(SICA_IWR0, iwr0);
        bfin_write32(SICA_IWR1, iwr1);
-       local_irq_restore(flags);
+       local_irq_restore_hw(flags);
 }
 
 #endif                         /* _CDEF_BF561_H */
index 56f68d8..72e1660 100644 (file)
@@ -104,7 +104,7 @@ static int bfin_target(struct cpufreq_policy *policy,
                 cclk_hz, target_freq, freqs.old);
 
        cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
-       local_irq_save(flags);
+       local_irq_save_hw(flags);
                plldiv = (bfin_read_PLL_DIV() & SSEL) | dpm_state_table[index].csel;
                tscale = dpm_state_table[index].tscale;
                bfin_write_PLL_DIV(plldiv);
@@ -115,7 +115,7 @@ static int bfin_target(struct cpufreq_policy *policy,
        cycles += 10; /* ~10 cycles we lose after get_cycles() */
        __bfin_cycles_off += (cycles << __bfin_cycles_mod) - (cycles << index);
        __bfin_cycles_mod = index;
-       local_irq_restore(flags);
+       local_irq_restore_hw(flags);
        /* TODO: just test case for cycles clock source, remove later */
        pr_debug("cpufreq: done\n");
        cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
index 2604b53..c1bdd1e 100644 (file)
@@ -129,8 +129,15 @@ __common_int_entry:
 #endif
        r1 =  sp;
        SP += -12;
+#ifdef CONFIG_IPIPE
+       call ___ipipe_grab_irq
+       SP += 12;
+       cc = r0 == 0;
+       if cc jump .Lcommon_restore_context;
+#else /* CONFIG_IPIPE */
        call _do_irq;
        SP += 12;
+#endif /* CONFIG_IPIPE */
        call _return_from_int;
 .Lcommon_restore_context:
        RESTORE_CONTEXT
@@ -247,3 +254,56 @@ ENTRY(_evt_system_call)
        call _system_call;
        jump .Lcommon_restore_context;
 ENDPROC(_evt_system_call)
+
+#ifdef CONFIG_IPIPE
+ENTRY(___ipipe_call_irqtail)
+       r0.l = 1f;
+       r0.h = 1f;
+       reti = r0;
+       rti;
+1:
+       [--sp] = rets;
+       [--sp] = ( r7:4, p5:3 );
+       p0.l = ___ipipe_irq_tail_hook;
+       p0.h = ___ipipe_irq_tail_hook;
+       p0 = [p0];
+       sp += -12;
+       call (p0);
+       sp += 12;
+       ( r7:4, p5:3 ) = [sp++];
+       rets = [sp++];
+
+       [--sp] = reti;
+       reti = [sp++];          /* IRQs are off. */
+       r0.h = 3f;
+       r0.l = 3f;
+       p0.l = lo(EVT14);
+       p0.h = hi(EVT14);
+       [p0] = r0;
+       csync;
+       r0 = 0x401f;
+       sti r0;
+       raise 14;
+       [--sp] = reti;          /* IRQs on. */
+2:
+       jump 2b;                /* Likely paranoid. */
+3:
+       sp += 4;                /* Discard saved RETI */
+       r0.h = _evt14_softirq;
+       r0.l = _evt14_softirq;
+       p0.l = lo(EVT14);
+       p0.h = hi(EVT14);
+       [p0] = r0;
+       csync;
+       p0.l = _bfin_irq_flags;
+       p0.h = _bfin_irq_flags;
+       r0 = [p0];
+       sti r0;
+#if 0 /* FIXME: this actually raises scheduling latencies */
+       /* Reenable interrupts */
+       [--sp] = reti;
+       r0 = [sp++];
+#endif
+       rts;
+ENDPROC(___ipipe_call_irqtail)
+#endif /* CONFIG_IPIPE */
index 7c1db77..1bba603 100644 (file)
@@ -34,6 +34,9 @@
 #include <linux/kernel_stat.h>
 #include <linux/seq_file.h>
 #include <linux/irq.h>
+#ifdef CONFIG_IPIPE
+#include <linux/ipipe.h>
+#endif
 #ifdef CONFIG_KGDB
 #include <linux/kgdb.h>
 #endif
@@ -135,8 +138,8 @@ static void bfin_ack_noop(unsigned int irq)
 static void bfin_core_mask_irq(unsigned int irq)
 {
        bfin_irq_flags &= ~(1 << irq);
-       if (!irqs_disabled())
-               local_irq_enable();
+       if (!irqs_disabled_hw())
+               local_irq_enable_hw();
 }
 
 static void bfin_core_unmask_irq(unsigned int irq)
@@ -151,8 +154,8 @@ static void bfin_core_unmask_irq(unsigned int irq)
         * local_irq_enable just does "STI bfin_irq_flags", so it's exactly
         * what we need.
         */
-       if (!irqs_disabled())
-               local_irq_enable();
+       if (!irqs_disabled_hw())
+               local_irq_enable_hw();
        return;
 }
 
@@ -235,7 +238,7 @@ int bfin_internal_set_wake(unsigned int irq, unsigned int state)
        break;
        }
 
-       local_irq_save(flags);
+       local_irq_save_hw(flags);
 
        if (state) {
                bfin_sic_iwr[bank] |= (1 << bit);
@@ -246,7 +249,7 @@ int bfin_internal_set_wake(unsigned int irq, unsigned int state)
                vr_wakeup  &= ~wakeup;
        }
 
-       local_irq_restore(flags);
+       local_irq_restore_hw(flags);
 
        return 0;
 }
@@ -272,6 +275,19 @@ static struct irq_chip bfin_internal_irqchip = {
 #endif
 };
 
+static void bfin_handle_irq(unsigned irq)
+{
+#ifdef CONFIG_IPIPE
+       struct pt_regs regs;    /* Contents not used. */
+       ipipe_trace_irq_entry(irq);
+       __ipipe_handle_irq(irq, &regs);
+       ipipe_trace_irq_exit(irq);
+#else /* !CONFIG_IPIPE */
+       struct irq_desc *desc = irq_desc + irq;
+       desc->handle_irq(irq, desc);
+#endif  /* !CONFIG_IPIPE */
+}
+
 #ifdef BF537_GENERIC_ERROR_INT_DEMUX
 static int error_int_mask;
 
@@ -325,10 +341,9 @@ static void bfin_demux_error_irq(unsigned int int_err_irq,
                irq = IRQ_UART1_ERROR;
 
        if (irq) {
-               if (error_int_mask & (1L << (irq - IRQ_PPI_ERROR))) {
-                       struct irq_desc *desc = irq_desc + irq;
-                       desc->handle_irq(irq, desc);
-               } else {
+               if (error_int_mask & (1L << (irq - IRQ_PPI_ERROR)))
+                       bfin_handle_irq(irq);
+               else {
 
                        switch (irq) {
                        case IRQ_PPI_ERROR:
@@ -374,10 +389,14 @@ static void bfin_demux_error_irq(unsigned int int_err_irq,
 
 static inline void bfin_set_irq_handler(unsigned irq, irq_flow_handler_t handle)
 {
+#ifdef CONFIG_IPIPE
+       _set_irq_handler(irq, handle_edge_irq);
+#else
        struct irq_desc *desc = irq_desc + irq;
        /* May not call generic set_irq_handler() due to spinlock
           recursion. */
        desc->handle_irq = handle;
+#endif
 }
 
 static DECLARE_BITMAP(gpio_enabled, MAX_BLACKFIN_GPIOS);
@@ -563,10 +582,8 @@ static void bfin_demux_gpio_irq(unsigned int inta_irq,
                        mask = get_gpiop_data(i) & get_gpiop_maska(i);
 
                        while (mask) {
-                               if (mask & 1) {
-                                       desc = irq_desc + irq;
-                                       desc->handle_irq(irq, desc);
-                               }
+                               if (mask & 1)
+                                       bfin_handle_irq(irq);
                                irq++;
                                mask >>= 1;
                        }
@@ -576,10 +593,8 @@ static void bfin_demux_gpio_irq(unsigned int inta_irq,
                        mask = get_gpiop_data(gpio) & get_gpiop_maska(gpio);
 
                        do {
-                               if (mask & 1) {
-                                       desc = irq_desc + irq;
-                                       desc->handle_irq(irq, desc);
-                               }
+                               if (mask & 1)
+                                       bfin_handle_irq(irq);
                                irq++;
                                mask >>= 1;
                        } while (mask);
@@ -900,8 +915,7 @@ static void bfin_demux_gpio_irq(unsigned int inta_irq,
        while (request) {
                if (request & 1) {
                        irq = pint2irq_lut[pint_val] + SYS_IRQS;
-                       desc = irq_desc + irq;
-                       desc->handle_irq(irq, desc);
+                       bfin_handle_irq(irq);
                }
                pint_val++;
                request >>= 1;
@@ -1025,11 +1039,10 @@ int __init init_arch_irq(void)
                        break;
 #ifdef BF537_GENERIC_ERROR_INT_DEMUX
                case IRQ_GENERIC_ERROR:
-                       set_irq_handler(irq, bfin_demux_error_irq);
-
+                       set_irq_chained_handler(irq, bfin_demux_error_irq);
                        break;
 #endif
-#ifdef CONFIG_TICK_SOURCE_SYSTMR0
+#if defined(CONFIG_TICK_SOURCE_SYSTMR0) || defined(CONFIG_IPIPE)
                case IRQ_TIMER0:
                        set_irq_handler(irq, handle_percpu_irq);
                        break;
@@ -1041,7 +1054,17 @@ int __init init_arch_irq(void)
                        break;
 #endif
                default:
+#ifdef CONFIG_IPIPE
+       /*
+        * We want internal interrupt sources to be masked, because
+        * ISRs may trigger interrupts recursively (e.g. DMA), but
+        * interrupts are _not_ masked at CPU level. So let's handle
+        * them as level interrupts.
+        */
+                       set_irq_handler(irq, handle_level_irq);
+#else /* !CONFIG_IPIPE */
                        set_irq_handler(irq, handle_simple_irq);
+#endif /* !CONFIG_IPIPE */
                        break;
                }
        }
@@ -1101,6 +1124,14 @@ int __init init_arch_irq(void)
        bfin_write_SIC_IWR(IWR_DISABLE_ALL);
 #endif
 
+#ifdef CONFIG_IPIPE
+       for (irq = 0; irq < NR_IRQS; irq++) {
+               struct irq_desc *desc = irq_desc + irq;
+               desc->ic_prio = __ipipe_get_irq_priority(irq);
+               desc->thr_prio = __ipipe_get_irqthread_priority(irq);
+       }
+#endif /* CONFIG_IPIPE */
+
        return 0;
 }
 
@@ -1156,3 +1187,161 @@ void do_irq(int vec, struct pt_regs *fp)
        }
        asm_do_IRQ(vec, fp);
 }
+
+#ifdef CONFIG_IPIPE
+
+int __ipipe_get_irq_priority(unsigned irq)
+{
+       int ient, prio;
+
+       if (irq <= IRQ_CORETMR)
+               return irq;
+
+       for (ient = 0; ient < NR_PERI_INTS; ient++) {
+               struct ivgx *ivg = ivg_table + ient;
+               if (ivg->irqno == irq) {
+                       for (prio = 0; prio <= IVG13-IVG7; prio++) {
+                               if (ivg7_13[prio].ifirst <= ivg &&
+                                   ivg7_13[prio].istop > ivg)
+                                       return IVG7 + prio;
+                       }
+               }
+       }
+
+       return IVG15;
+}
+
+int __ipipe_get_irqthread_priority(unsigned irq)
+{
+       int ient, prio;
+       int demux_irq;
+
+       /* The returned priority value is rescaled to [0..IVG13+1]
+        * with 0 being the lowest effective priority level. */
+
+       if (irq <= IRQ_CORETMR)
+               return IVG13 - irq + 1;
+
+       /* GPIO IRQs are given the priority of the demux
+        * interrupt. */
+       if (IS_GPIOIRQ(irq)) {
+#if defined(CONFIG_BF54x)
+               u32 bank = PINT_2_BANK(irq2pint_lut[irq - SYS_IRQS]);
+               demux_irq = (bank == 0 ? IRQ_PINT0 :
+                               bank == 1 ? IRQ_PINT1 :
+                               bank == 2 ? IRQ_PINT2 :
+                               IRQ_PINT3);
+#elif defined(CONFIG_BF561)
+               demux_irq = (irq >= IRQ_PF32 ? IRQ_PROG2_INTA :
+                               irq >= IRQ_PF16 ? IRQ_PROG1_INTA :
+                               IRQ_PROG0_INTA);
+#elif defined(CONFIG_BF52x)
+               demux_irq = (irq >= IRQ_PH0 ? IRQ_PORTH_INTA :
+                               irq >= IRQ_PG0 ? IRQ_PORTG_INTA :
+                               IRQ_PORTF_INTA);
+#else
+               demux_irq = irq;
+#endif
+               return IVG13 - PRIO_GPIODEMUX(demux_irq) + 1;
+       }
+
+       /* The GPIO demux interrupt is given a lower priority
+        * than the GPIO IRQs, so that its threaded handler
+        * unmasks the interrupt line after the decoded IRQs
+        * have been processed. */
+       prio = PRIO_GPIODEMUX(irq);
+       /* demux irq? */
+       if (prio != -1)
+               return IVG13 - prio;
+
+       for (ient = 0; ient < NR_PERI_INTS; ient++) {
+               struct ivgx *ivg = ivg_table + ient;
+               if (ivg->irqno == irq) {
+                       for (prio = 0; prio <= IVG13-IVG7; prio++) {
+                               if (ivg7_13[prio].ifirst <= ivg &&
+                                   ivg7_13[prio].istop > ivg)
+                                       return IVG7 - prio;
+                       }
+               }
+       }
+
+       return 0;
+}
+
+/* Hw interrupts are disabled on entry (check SAVE_CONTEXT). */
+#ifdef CONFIG_DO_IRQ_L1
+__attribute__((l1_text))
+#endif
+asmlinkage int __ipipe_grab_irq(int vec, struct pt_regs *regs)
+{
+       struct ivgx *ivg_stop = ivg7_13[vec-IVG7].istop;
+       struct ivgx *ivg = ivg7_13[vec-IVG7].ifirst;
+       int irq;
+
+       if (likely(vec == EVT_IVTMR_P)) {
+               irq = IRQ_CORETMR;
+               goto handle_irq;
+       }
+
+       SSYNC();
+
+#if defined(CONFIG_BF54x) || defined(CONFIG_BF52x) || defined(CONFIG_BF561)
+       {
+               unsigned long sic_status[3];
+
+               sic_status[0] = bfin_read_SIC_ISR0() & bfin_read_SIC_IMASK0();
+               sic_status[1] = bfin_read_SIC_ISR1() & bfin_read_SIC_IMASK1();
+#ifdef CONFIG_BF54x
+               sic_status[2] = bfin_read_SIC_ISR2() & bfin_read_SIC_IMASK2();
+#endif
+               for (;; ivg++) {
+                       if (ivg >= ivg_stop) {
+                               atomic_inc(&num_spurious);
+                               return 0;
+                       }
+                       if (sic_status[(ivg->irqno - IVG7) / 32] & ivg->isrflag)
+                               break;
+               }
+       }
+#else
+       {
+               unsigned long sic_status;
+
+               sic_status = bfin_read_SIC_IMASK() & bfin_read_SIC_ISR();
+
+               for (;; ivg++) {
+                       if (ivg >= ivg_stop) {
+                               atomic_inc(&num_spurious);
+                               return 0;
+                       } else if (sic_status & ivg->isrflag)
+                               break;
+               }
+       }
+#endif
+
+       irq = ivg->irqno;
+
+       if (irq == IRQ_SYSTMR) {
+               bfin_write_TIMER_STATUS(1); /* Latch TIMIL0 */
+               /* This is basically what we need from the register frame. */
+               __raw_get_cpu_var(__ipipe_tick_regs).ipend = regs->ipend;
+               __raw_get_cpu_var(__ipipe_tick_regs).pc = regs->pc;
+               if (!ipipe_root_domain_p)
+                       __raw_get_cpu_var(__ipipe_tick_regs).ipend |= 0x10;
+               else
+                       __raw_get_cpu_var(__ipipe_tick_regs).ipend &= ~0x10;
+       }
+
+handle_irq:
+
+       ipipe_trace_irq_entry(irq);
+       __ipipe_handle_irq(irq, regs);
+       ipipe_trace_irq_exit(irq);
+
+       if (ipipe_root_domain_p)
+               return !test_bit(IPIPE_STALL_FLAG, &ipipe_root_cpudom_var(status));
+
+       return 0;
+}
+
+#endif /* CONFIG_IPIPE */
index 96600b8..d3d70fd 100644 (file)
@@ -71,7 +71,7 @@ void bfin_pm_suspend_standby_enter(void)
        gpio_pm_wakeup_request(CONFIG_PM_WAKEUP_GPIO_NUMBER, WAKEUP_TYPE);
 #endif
 
-       local_irq_save(flags);
+       local_irq_save_hw(flags);
        bfin_pm_standby_setup();
 
 #ifdef CONFIG_PM_BFIN_SLEEP_DEEPER
@@ -105,7 +105,7 @@ void bfin_pm_suspend_standby_enter(void)
        bfin_write_SIC_IWR(IWR_DISABLE_ALL);
 #endif
 
-       local_irq_restore(flags);
+       local_irq_restore_hw(flags);
 }
 
 int bf53x_suspend_l1_mem(unsigned char *memptr)
@@ -249,12 +249,12 @@ int bfin_pm_suspend_mem_enter(void)
        wakeup |= GPWE;
 #endif
 
-       local_irq_save(flags);
+       local_irq_save_hw(flags);
 
        ret = blackfin_dma_suspend();
 
        if (ret) {
-               local_irq_restore(flags);
+               local_irq_restore_hw(flags);
                kfree(memptr);
                return ret;
        }
@@ -275,7 +275,7 @@ int bfin_pm_suspend_mem_enter(void)
        bfin_gpio_pm_hibernate_restore();
        blackfin_dma_resume();
 
-       local_irq_restore(flags);
+       local_irq_restore_hw(flags);
        kfree(memptr);
 
        return 0;
index 66c47a7..77c9928 100644 (file)
@@ -348,7 +348,7 @@ int __cpuinit __cpu_up(unsigned int cpu)
 
 static void __cpuinit setup_secondary(unsigned int cpu)
 {
-#ifndef CONFIG_TICK_SOURCE_SYSTMR0
+#if !(defined(CONFIG_TICK_SOURCE_SYSTMR0) || defined(CONFIG_IPIPE))
        struct irq_desc *timer_desc;
 #endif
        unsigned long ilat;
@@ -369,7 +369,7 @@ static void __cpuinit setup_secondary(unsigned int cpu)
            IMASK_IVG14 | IMASK_IVG13 | IMASK_IVG12 | IMASK_IVG11 |
            IMASK_IVG10 | IMASK_IVG9 | IMASK_IVG8 | IMASK_IVG7 | IMASK_IVGHW;
 
-#ifdef CONFIG_TICK_SOURCE_SYSTMR0
+#if defined(CONFIG_TICK_SOURCE_SYSTMR0) || defined(CONFIG_IPIPE)
        /* Power down the core timer, just to play safe. */
        bfin_write_TCNTL(0);