aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/blackfin/kernel/irqchip.c43
1 files changed, 25 insertions, 18 deletions
diff --git a/arch/blackfin/kernel/irqchip.c b/arch/blackfin/kernel/irqchip.c
index 7378440792a4..4b5fd36187d9 100644
--- a/arch/blackfin/kernel/irqchip.c
+++ b/arch/blackfin/kernel/irqchip.c
@@ -104,6 +104,29 @@ static void check_stack_overflow(int irq)
104static inline void check_stack_overflow(int irq) { } 104static inline void check_stack_overflow(int irq) { }
105#endif 105#endif
106 106
107#ifndef CONFIG_IPIPE
108static void maybe_lower_to_irq14(void)
109{
110 unsigned short pending, other_ints;
111
112 /*
113 * If we're the only interrupt running (ignoring IRQ15 which
114 * is for syscalls), lower our priority to IRQ14 so that
115 * softirqs run at that level. If there's another,
116 * lower-level interrupt, irq_exit will defer softirqs to
117 * that. If the interrupt pipeline is enabled, we are already
118 * running at IRQ14 priority, so we don't need this code.
119 */
120 CSYNC();
121 pending = bfin_read_IPEND() & ~0x8000;
122 other_ints = pending & (pending - 1);
123 if (other_ints == 0)
124 lower_to_irq14();
125}
126#else
127static inline void maybe_lower_to_irq14(void) { }
128#endif
129
107/* 130/*
108 * do_IRQ handles all hardware IRQs. Decoded IRQs should not 131 * do_IRQ handles all hardware IRQs. Decoded IRQs should not
109 * come via this function. Instead, they should provide their 132 * come via this function. Instead, they should provide their
@@ -114,9 +137,6 @@ __attribute__((l1_text))
114#endif 137#endif
115asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs) 138asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs)
116{ 139{
117#ifndef CONFIG_IPIPE
118 unsigned short pending, other_ints;
119#endif
120 struct pt_regs *old_regs = set_irq_regs(regs); 140 struct pt_regs *old_regs = set_irq_regs(regs);
121 141
122 irq_enter(); 142 irq_enter();
@@ -132,21 +152,8 @@ asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs)
132 else 152 else
133 generic_handle_irq(irq); 153 generic_handle_irq(irq);
134 154
135#ifndef CONFIG_IPIPE 155 maybe_lower_to_irq14();
136 /* 156
137 * If we're the only interrupt running (ignoring IRQ15 which
138 * is for syscalls), lower our priority to IRQ14 so that
139 * softirqs run at that level. If there's another,
140 * lower-level interrupt, irq_exit will defer softirqs to
141 * that. If the interrupt pipeline is enabled, we are already
142 * running at IRQ14 priority, so we don't need this code.
143 */
144 CSYNC();
145 pending = bfin_read_IPEND() & ~0x8000;
146 other_ints = pending & (pending - 1);
147 if (other_ints == 0)
148 lower_to_irq14();
149#endif /* !CONFIG_IPIPE */
150 irq_exit(); 157 irq_exit();
151 158
152 set_irq_regs(old_regs); 159 set_irq_regs(old_regs);