aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-03-29 23:30:12 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-03-29 23:30:12 -0400
commitce20269d1e97030afa476e12b99d2437e748d225 (patch)
tree644d9962049b4d73ff85e17562e383a57c8ce1fa
parent9754c5f6cbbd8893a29f139204e87a59eb342ca9 (diff)
parent8a1e97ee2e025f116765c92409a3cf8f6cb07ad6 (diff)
Merge branch 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-linus
* 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-linus: [MIPS] SMTC: Fix recursion in instant IPI replay code. [MIPS] BCM1480: Fix setting of irq affinity. [MIPS] do_page_fault() needs to use raw_smp_processor_id(). [MIPS] SMTC: Fix false trigger of debug code on single VPE. [MIPS] SMTC: irq_{enter,leave} and kstats keeping for relayed timer ints. [MIPS] lockdep: Deal with interrupt disable hazard in TRACE_IRQFLAGS [MIPS] lockdep: Handle interrupts in R3000 style c0_status register. [MIPS] MV64340: Add missing prototype for mv64340_irq_init(). [MIPS] MT: MIPS_MT_SMTC_INSTANT_REPLAY currently conflicts with PREEMPT. [MIPS] EV64120: Include <asm/irq.h> to fix warning. [MIPS] Ocelot: Fix warning. [MIPS] Ocelot: Give PMON_v1_setup a proper prototype.
-rw-r--r--arch/mips/Kconfig2
-rw-r--r--arch/mips/gt64120/momenco_ocelot/prom.c1
-rw-r--r--arch/mips/gt64120/momenco_ocelot/setup.c2
-rw-r--r--arch/mips/kernel/entry.S6
-rw-r--r--arch/mips/kernel/genex.S31
-rw-r--r--arch/mips/kernel/smtc.c65
-rw-r--r--arch/mips/mm/fault.c6
-rw-r--r--arch/mips/pci/pci-ev64120.c1
-rw-r--r--arch/mips/sibyte/bcm1480/irq.c4
-rw-r--r--include/asm-mips/irqflags.h55
-rw-r--r--include/asm-mips/marvell.h1
-rw-r--r--include/asm-mips/smtc_ipi.h16
12 files changed, 134 insertions, 56 deletions
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 656f0ca52782..c78b14380b3e 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -1606,7 +1606,7 @@ config MIPS_MT_FPAFF
1606 1606
1607config MIPS_MT_SMTC_INSTANT_REPLAY 1607config MIPS_MT_SMTC_INSTANT_REPLAY
1608 bool "Low-latency Dispatch of Deferred SMTC IPIs" 1608 bool "Low-latency Dispatch of Deferred SMTC IPIs"
1609 depends on MIPS_MT_SMTC 1609 depends on MIPS_MT_SMTC && !PREEMPT
1610 default y 1610 default y
1611 help 1611 help
1612 SMTC pseudo-interrupts between TCs are deferred and queued 1612 SMTC pseudo-interrupts between TCs are deferred and queued
diff --git a/arch/mips/gt64120/momenco_ocelot/prom.c b/arch/mips/gt64120/momenco_ocelot/prom.c
index 78f393b2afd9..c71c85276c74 100644
--- a/arch/mips/gt64120/momenco_ocelot/prom.c
+++ b/arch/mips/gt64120/momenco_ocelot/prom.c
@@ -32,7 +32,6 @@ void __init prom_init(void)
32 char **arg = (char **) fw_arg1; 32 char **arg = (char **) fw_arg1;
33 char **env = (char **) fw_arg2; 33 char **env = (char **) fw_arg2;
34 struct callvectors *cv = (struct callvectors *) fw_arg3; 34 struct callvectors *cv = (struct callvectors *) fw_arg3;
35 uint32_t tmp;
36 int i; 35 int i;
37 36
38 /* save the PROM vectors for debugging use */ 37 /* save the PROM vectors for debugging use */
diff --git a/arch/mips/gt64120/momenco_ocelot/setup.c b/arch/mips/gt64120/momenco_ocelot/setup.c
index 94f94ebbda6c..98b6fb38096d 100644
--- a/arch/mips/gt64120/momenco_ocelot/setup.c
+++ b/arch/mips/gt64120/momenco_ocelot/setup.c
@@ -79,7 +79,7 @@ static char reset_reason;
79static void __init setup_l3cache(unsigned long size); 79static void __init setup_l3cache(unsigned long size);
80 80
81/* setup code for a handoff from a version 1 PMON 2000 PROM */ 81/* setup code for a handoff from a version 1 PMON 2000 PROM */
82void PMON_v1_setup() 82static void PMON_v1_setup(void)
83{ 83{
84 /* A wired TLB entry for the GT64120A and the serial port. The 84 /* A wired TLB entry for the GT64120A and the serial port. The
85 GT64120A is going to be hit on every IRQ anyway - there's 85 GT64120A is going to be hit on every IRQ anyway - there's
diff --git a/arch/mips/kernel/entry.S b/arch/mips/kernel/entry.S
index 0b78fcbf044a..686249c5c328 100644
--- a/arch/mips/kernel/entry.S
+++ b/arch/mips/kernel/entry.S
@@ -121,7 +121,11 @@ FEXPORT(restore_partial) # restore partial frame
121 SAVE_AT 121 SAVE_AT
122 SAVE_TEMP 122 SAVE_TEMP
123 LONG_L v0, PT_STATUS(sp) 123 LONG_L v0, PT_STATUS(sp)
124 and v0, 1 124#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
125 and v0, ST0_IEP
126#else
127 and v0, ST0_IE
128#endif
125 beqz v0, 1f 129 beqz v0, 1f
126 jal trace_hardirqs_on 130 jal trace_hardirqs_on
127 b 2f 131 b 2f
diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S
index 83843a229be7..297bd56c2347 100644
--- a/arch/mips/kernel/genex.S
+++ b/arch/mips/kernel/genex.S
@@ -128,6 +128,37 @@ handle_vcei:
128 128
129 .align 5 129 .align 5
130NESTED(handle_int, PT_SIZE, sp) 130NESTED(handle_int, PT_SIZE, sp)
131#ifdef CONFIG_TRACE_IRQFLAGS
132 /*
133 * Check to see if the interrupted code has just disabled
134 * interrupts and ignore this interrupt for now if so.
135 *
136 * local_irq_disable() disables interrupts and then calls
137 * trace_hardirqs_off() to track the state. If an interrupt is taken
138 * after interrupts are disabled but before the state is updated
139 * it will appear to restore_all that it is incorrectly returning with
140 * interrupts disabled
141 */
142 .set push
143 .set noat
144 mfc0 k0, CP0_STATUS
145#if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX)
146 and k0, ST0_IEP
147 bnez k0, 1f
148
149 mfc0 k0, EP0_EPC
150 .set noreorder
151 j k0
152 rfe
153#else
154 and k0, ST0_IE
155 bnez k0, 1f
156
157 eret
158#endif
1591:
160 .set pop
161#endif
131 SAVE_ALL 162 SAVE_ALL
132 CLI 163 CLI
133 TRACE_IRQS_OFF 164 TRACE_IRQS_OFF
diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c
index f253eda27fa3..5dcfab6b288e 100644
--- a/arch/mips/kernel/smtc.c
+++ b/arch/mips/kernel/smtc.c
@@ -4,6 +4,7 @@
4#include <linux/sched.h> 4#include <linux/sched.h>
5#include <linux/cpumask.h> 5#include <linux/cpumask.h>
6#include <linux/interrupt.h> 6#include <linux/interrupt.h>
7#include <linux/kernel_stat.h>
7#include <linux/module.h> 8#include <linux/module.h>
8 9
9#include <asm/cpu.h> 10#include <asm/cpu.h>
@@ -14,6 +15,7 @@
14#include <asm/hazards.h> 15#include <asm/hazards.h>
15#include <asm/mmu_context.h> 16#include <asm/mmu_context.h>
16#include <asm/smp.h> 17#include <asm/smp.h>
18#include <asm/mips-boards/maltaint.h>
17#include <asm/mipsregs.h> 19#include <asm/mipsregs.h>
18#include <asm/cacheflush.h> 20#include <asm/cacheflush.h>
19#include <asm/time.h> 21#include <asm/time.h>
@@ -75,7 +77,7 @@ static struct smtc_ipi_q freeIPIq;
75 77
76void ipi_decode(struct smtc_ipi *); 78void ipi_decode(struct smtc_ipi *);
77static void post_direct_ipi(int cpu, struct smtc_ipi *pipi); 79static void post_direct_ipi(int cpu, struct smtc_ipi *pipi);
78static void setup_cross_vpe_interrupts(void); 80static void setup_cross_vpe_interrupts(unsigned int nvpe);
79void init_smtc_stats(void); 81void init_smtc_stats(void);
80 82
81/* Global SMTC Status */ 83/* Global SMTC Status */
@@ -168,7 +170,10 @@ __setup("tintq=", tintq);
168 170
169int imstuckcount[2][8]; 171int imstuckcount[2][8];
170/* vpemask represents IM/IE bits of per-VPE Status registers, low-to-high */ 172/* vpemask represents IM/IE bits of per-VPE Status registers, low-to-high */
171int vpemask[2][8] = {{0,1,1,0,0,0,0,1},{0,1,0,0,0,0,0,1}}; 173int vpemask[2][8] = {
174 {0, 0, 1, 0, 0, 0, 0, 1},
175 {0, 0, 0, 0, 0, 0, 0, 1}
176};
172int tcnoprog[NR_CPUS]; 177int tcnoprog[NR_CPUS];
173static atomic_t idle_hook_initialized = {0}; 178static atomic_t idle_hook_initialized = {0};
174static int clock_hang_reported[NR_CPUS]; 179static int clock_hang_reported[NR_CPUS];
@@ -501,8 +506,7 @@ void mipsmt_prepare_cpus(void)
501 506
502 /* If we have multiple VPEs running, set up the cross-VPE interrupt */ 507 /* If we have multiple VPEs running, set up the cross-VPE interrupt */
503 508
504 if (nvpe > 1) 509 setup_cross_vpe_interrupts(nvpe);
505 setup_cross_vpe_interrupts();
506 510
507 /* Set up queue of free IPI "messages". */ 511 /* Set up queue of free IPI "messages". */
508 nipi = NR_CPUS * IPIBUF_PER_CPU; 512 nipi = NR_CPUS * IPIBUF_PER_CPU;
@@ -607,7 +611,12 @@ void smtc_cpus_done(void)
607int setup_irq_smtc(unsigned int irq, struct irqaction * new, 611int setup_irq_smtc(unsigned int irq, struct irqaction * new,
608 unsigned long hwmask) 612 unsigned long hwmask)
609{ 613{
614 unsigned int vpe = current_cpu_data.vpe_id;
615
610 irq_hwmask[irq] = hwmask; 616 irq_hwmask[irq] = hwmask;
617#ifdef CONFIG_SMTC_IDLE_HOOK_DEBUG
618 vpemask[vpe][irq - MIPSCPU_INT_BASE] = 1;
619#endif
611 620
612 return setup_irq(irq, new); 621 return setup_irq(irq, new);
613} 622}
@@ -812,12 +821,15 @@ void ipi_decode(struct smtc_ipi *pipi)
812 smtc_ipi_nq(&freeIPIq, pipi); 821 smtc_ipi_nq(&freeIPIq, pipi);
813 switch (type_copy) { 822 switch (type_copy) {
814 case SMTC_CLOCK_TICK: 823 case SMTC_CLOCK_TICK:
824 irq_enter();
825 kstat_this_cpu.irqs[MIPSCPU_INT_BASE + MIPSCPU_INT_CPUCTR]++;
815 /* Invoke Clock "Interrupt" */ 826 /* Invoke Clock "Interrupt" */
816 ipi_timer_latch[dest_copy] = 0; 827 ipi_timer_latch[dest_copy] = 0;
817#ifdef CONFIG_SMTC_IDLE_HOOK_DEBUG 828#ifdef CONFIG_SMTC_IDLE_HOOK_DEBUG
818 clock_hang_reported[dest_copy] = 0; 829 clock_hang_reported[dest_copy] = 0;
819#endif /* CONFIG_SMTC_IDLE_HOOK_DEBUG */ 830#endif /* CONFIG_SMTC_IDLE_HOOK_DEBUG */
820 local_timer_interrupt(0, NULL); 831 local_timer_interrupt(0, NULL);
832 irq_exit();
821 break; 833 break;
822 case LINUX_SMP_IPI: 834 case LINUX_SMP_IPI:
823 switch ((int)arg_copy) { 835 switch ((int)arg_copy) {
@@ -965,8 +977,11 @@ static void ipi_irq_dispatch(void)
965 977
966static struct irqaction irq_ipi; 978static struct irqaction irq_ipi;
967 979
968static void setup_cross_vpe_interrupts(void) 980static void setup_cross_vpe_interrupts(unsigned int nvpe)
969{ 981{
982 if (nvpe < 1)
983 return;
984
970 if (!cpu_has_vint) 985 if (!cpu_has_vint)
971 panic("SMTC Kernel requires Vectored Interupt support"); 986 panic("SMTC Kernel requires Vectored Interupt support");
972 987
@@ -984,10 +999,17 @@ static void setup_cross_vpe_interrupts(void)
984 999
985/* 1000/*
986 * SMTC-specific hacks invoked from elsewhere in the kernel. 1001 * SMTC-specific hacks invoked from elsewhere in the kernel.
1002 *
1003 * smtc_ipi_replay is called from raw_local_irq_restore which is only ever
1004 * called with interrupts disabled. We do rely on interrupts being disabled
1005 * here because using spin_lock_irqsave()/spin_unlock_irqrestore() would
1006 * result in a recursive call to raw_local_irq_restore().
987 */ 1007 */
988 1008
989void smtc_ipi_replay(void) 1009static void __smtc_ipi_replay(void)
990{ 1010{
1011 unsigned int cpu = smp_processor_id();
1012
991 /* 1013 /*
992 * To the extent that we've ever turned interrupts off, 1014 * To the extent that we've ever turned interrupts off,
993 * we may have accumulated deferred IPIs. This is subtle. 1015 * we may have accumulated deferred IPIs. This is subtle.
@@ -1002,17 +1024,30 @@ void smtc_ipi_replay(void)
1002 * is clear, and we'll handle it as a real pseudo-interrupt 1024 * is clear, and we'll handle it as a real pseudo-interrupt
1003 * and not a pseudo-pseudo interrupt. 1025 * and not a pseudo-pseudo interrupt.
1004 */ 1026 */
1005 if (IPIQ[smp_processor_id()].depth > 0) { 1027 if (IPIQ[cpu].depth > 0) {
1006 struct smtc_ipi *pipi; 1028 while (1) {
1007 extern void self_ipi(struct smtc_ipi *); 1029 struct smtc_ipi_q *q = &IPIQ[cpu];
1030 struct smtc_ipi *pipi;
1031 extern void self_ipi(struct smtc_ipi *);
1032
1033 spin_lock(&q->lock);
1034 pipi = __smtc_ipi_dq(q);
1035 spin_unlock(&q->lock);
1036 if (!pipi)
1037 break;
1008 1038
1009 while ((pipi = smtc_ipi_dq(&IPIQ[smp_processor_id()]))) {
1010 self_ipi(pipi); 1039 self_ipi(pipi);
1011 smtc_cpu_stats[smp_processor_id()].selfipis++; 1040 smtc_cpu_stats[cpu].selfipis++;
1012 } 1041 }
1013 } 1042 }
1014} 1043}
1015 1044
1045void smtc_ipi_replay(void)
1046{
1047 raw_local_irq_disable();
1048 __smtc_ipi_replay();
1049}
1050
1016EXPORT_SYMBOL(smtc_ipi_replay); 1051EXPORT_SYMBOL(smtc_ipi_replay);
1017 1052
1018void smtc_idle_loop_hook(void) 1053void smtc_idle_loop_hook(void)
@@ -1117,7 +1152,13 @@ void smtc_idle_loop_hook(void)
1117 * is in use, there should never be any. 1152 * is in use, there should never be any.
1118 */ 1153 */
1119#ifndef CONFIG_MIPS_MT_SMTC_INSTANT_REPLAY 1154#ifndef CONFIG_MIPS_MT_SMTC_INSTANT_REPLAY
1120 smtc_ipi_replay(); 1155 {
1156 unsigned long flags;
1157
1158 local_irq_save(flags);
1159 __smtc_ipi_replay();
1160 local_irq_restore(flags);
1161 }
1121#endif /* CONFIG_MIPS_MT_SMTC_INSTANT_REPLAY */ 1162#endif /* CONFIG_MIPS_MT_SMTC_INSTANT_REPLAY */
1122} 1163}
1123 1164
diff --git a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c
index 6f90e7ef66ac..f9c595dceba9 100644
--- a/arch/mips/mm/fault.c
+++ b/arch/mips/mm/fault.c
@@ -42,7 +42,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long write,
42 siginfo_t info; 42 siginfo_t info;
43 43
44#if 0 44#if 0
45 printk("Cpu%d[%s:%d:%0*lx:%ld:%0*lx]\n", smp_processor_id(), 45 printk("Cpu%d[%s:%d:%0*lx:%ld:%0*lx]\n", raw_smp_processor_id(),
46 current->comm, current->pid, field, address, write, 46 current->comm, current->pid, field, address, write,
47 field, regs->cp0_epc); 47 field, regs->cp0_epc);
48#endif 48#endif
@@ -165,7 +165,7 @@ no_context:
165 165
166 printk(KERN_ALERT "CPU %d Unable to handle kernel paging request at " 166 printk(KERN_ALERT "CPU %d Unable to handle kernel paging request at "
167 "virtual address %0*lx, epc == %0*lx, ra == %0*lx\n", 167 "virtual address %0*lx, epc == %0*lx, ra == %0*lx\n",
168 smp_processor_id(), field, address, field, regs->cp0_epc, 168 raw_smp_processor_id(), field, address, field, regs->cp0_epc,
169 field, regs->regs[31]); 169 field, regs->regs[31]);
170 die("Oops", regs); 170 die("Oops", regs);
171 171
@@ -228,7 +228,7 @@ vmalloc_fault:
228 pmd_t *pmd, *pmd_k; 228 pmd_t *pmd, *pmd_k;
229 pte_t *pte_k; 229 pte_t *pte_k;
230 230
231 pgd = (pgd_t *) pgd_current[smp_processor_id()] + offset; 231 pgd = (pgd_t *) pgd_current[raw_smp_processor_id()] + offset;
232 pgd_k = init_mm.pgd + offset; 232 pgd_k = init_mm.pgd + offset;
233 233
234 if (!pgd_present(*pgd_k)) 234 if (!pgd_present(*pgd_k))
diff --git a/arch/mips/pci/pci-ev64120.c b/arch/mips/pci/pci-ev64120.c
index 9cd859ef1842..a84f594b5a18 100644
--- a/arch/mips/pci/pci-ev64120.c
+++ b/arch/mips/pci/pci-ev64120.c
@@ -1,4 +1,5 @@
1#include <linux/pci.h> 1#include <linux/pci.h>
2#include <asm/irq.h>
2 3
3int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) 4int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
4{ 5{
diff --git a/arch/mips/sibyte/bcm1480/irq.c b/arch/mips/sibyte/bcm1480/irq.c
index 20af0f1bb7bf..ba0c4b776c85 100644
--- a/arch/mips/sibyte/bcm1480/irq.c
+++ b/arch/mips/sibyte/bcm1480/irq.c
@@ -141,11 +141,11 @@ static void bcm1480_set_affinity(unsigned int irq, cpumask_t mask)
141 unsigned long flags; 141 unsigned long flags;
142 unsigned int irq_dirty; 142 unsigned int irq_dirty;
143 143
144 i = first_cpu(mask); 144 if (cpus_weight(mask) != 1) {
145 if (next_cpu(i, mask) <= NR_CPUS) {
146 printk("attempted to set irq affinity for irq %d to multiple CPUs\n", irq); 145 printk("attempted to set irq affinity for irq %d to multiple CPUs\n", irq);
147 return; 146 return;
148 } 147 }
148 i = first_cpu(mask);
149 149
150 /* Convert logical CPU to physical CPU */ 150 /* Convert logical CPU to physical CPU */
151 cpu = cpu_logical_map(i); 151 cpu = cpu_logical_map(i);
diff --git a/include/asm-mips/irqflags.h b/include/asm-mips/irqflags.h
index af3b07dfad4b..e459fa05db83 100644
--- a/include/asm-mips/irqflags.h
+++ b/include/asm-mips/irqflags.h
@@ -13,29 +13,9 @@
13 13
14#ifndef __ASSEMBLY__ 14#ifndef __ASSEMBLY__
15 15
16#include <linux/compiler.h>
16#include <asm/hazards.h> 17#include <asm/hazards.h>
17 18
18/*
19 * CONFIG_MIPS_MT_SMTC_INSTANT_REPLAY does prompt replay of deferred IPIs,
20 * at the cost of branch and call overhead on each local_irq_restore()
21 */
22
23#ifdef CONFIG_MIPS_MT_SMTC_INSTANT_REPLAY
24
25extern void smtc_ipi_replay(void);
26
27#define irq_restore_epilog(flags) \
28do { \
29 if (!(flags & 0x0400)) \
30 smtc_ipi_replay(); \
31} while (0)
32
33#else
34
35#define irq_restore_epilog(ignore) do { } while (0)
36
37#endif /* CONFIG_MIPS_MT_SMTC_INSTANT_REPLAY */
38
39__asm__ ( 19__asm__ (
40 " .macro raw_local_irq_enable \n" 20 " .macro raw_local_irq_enable \n"
41 " .set push \n" 21 " .set push \n"
@@ -205,17 +185,28 @@ __asm__ (
205 " .set pop \n" 185 " .set pop \n"
206 " .endm \n"); 186 " .endm \n");
207 187
208#define raw_local_irq_restore(flags) \ 188extern void smtc_ipi_replay(void);
209do { \ 189
210 unsigned long __tmp1; \ 190static inline void raw_local_irq_restore(unsigned long flags)
211 \ 191{
212 __asm__ __volatile__( \ 192 unsigned long __tmp1;
213 "raw_local_irq_restore\t%0" \ 193
214 : "=r" (__tmp1) \ 194#ifdef CONFIG_MIPS_MT_SMTC_INSTANT_REPLAY
215 : "0" (flags) \ 195 /*
216 : "memory"); \ 196 * CONFIG_MIPS_MT_SMTC_INSTANT_REPLAY does prompt replay of deferred
217 irq_restore_epilog(flags); \ 197 * IPIs, at the cost of branch and call overhead on each
218} while(0) 198 * local_irq_restore()
199 */
200 if (unlikely(!(flags & 0x0400)))
201 smtc_ipi_replay();
202#endif
203
204 __asm__ __volatile__(
205 "raw_local_irq_restore\t%0"
206 : "=r" (__tmp1)
207 : "0" (flags)
208 : "memory");
209}
219 210
220static inline int raw_irqs_disabled_flags(unsigned long flags) 211static inline int raw_irqs_disabled_flags(unsigned long flags)
221{ 212{
diff --git a/include/asm-mips/marvell.h b/include/asm-mips/marvell.h
index df94955b098a..b6144bafc565 100644
--- a/include/asm-mips/marvell.h
+++ b/include/asm-mips/marvell.h
@@ -54,5 +54,6 @@ struct mv_pci_controller {
54}; 54};
55 55
56extern void ll_mv64340_irq(void); 56extern void ll_mv64340_irq(void);
57extern void mv64340_irq_init(unsigned int base);
57 58
58#endif /* __ASM_MIPS_MARVELL_H */ 59#endif /* __ASM_MIPS_MARVELL_H */
diff --git a/include/asm-mips/smtc_ipi.h b/include/asm-mips/smtc_ipi.h
index 360ea6d250c7..a52a4a7a36e0 100644
--- a/include/asm-mips/smtc_ipi.h
+++ b/include/asm-mips/smtc_ipi.h
@@ -65,12 +65,10 @@ static inline void smtc_ipi_nq(struct smtc_ipi_q *q, struct smtc_ipi *p)
65 spin_unlock_irqrestore(&q->lock, flags); 65 spin_unlock_irqrestore(&q->lock, flags);
66} 66}
67 67
68static inline struct smtc_ipi *smtc_ipi_dq(struct smtc_ipi_q *q) 68static inline struct smtc_ipi *__smtc_ipi_dq(struct smtc_ipi_q *q)
69{ 69{
70 struct smtc_ipi *p; 70 struct smtc_ipi *p;
71 long flags;
72 71
73 spin_lock_irqsave(&q->lock, flags);
74 if (q->head == NULL) 72 if (q->head == NULL)
75 p = NULL; 73 p = NULL;
76 else { 74 else {
@@ -81,7 +79,19 @@ static inline struct smtc_ipi *smtc_ipi_dq(struct smtc_ipi_q *q)
81 if (q->head == NULL) 79 if (q->head == NULL)
82 q->tail = NULL; 80 q->tail = NULL;
83 } 81 }
82
83 return p;
84}
85
86static inline struct smtc_ipi *smtc_ipi_dq(struct smtc_ipi_q *q)
87{
88 unsigned long flags;
89 struct smtc_ipi *p;
90
91 spin_lock_irqsave(&q->lock, flags);
92 p = __smtc_ipi_dq(q);
84 spin_unlock_irqrestore(&q->lock, flags); 93 spin_unlock_irqrestore(&q->lock, flags);
94
85 return p; 95 return p;
86} 96}
87 97