patch-2.4.20 linux-2.4.20/arch/ppc64/kernel/irq.c
Next file: linux-2.4.20/arch/ppc64/kernel/lmb.c
Previous file: linux-2.4.20/arch/ppc64/kernel/ioctl32.c
Back to the patch index
Back to the overall index
- Lines: 159
- Date:
Thu Nov 28 15:53:11 2002
- Orig file:
linux-2.4.19/arch/ppc64/kernel/irq.c
- Orig date:
Fri Aug 2 17:39:43 2002
diff -urN linux-2.4.19/arch/ppc64/kernel/irq.c linux-2.4.20/arch/ppc64/kernel/irq.c
@@ -1,6 +1,4 @@
/*
- *
- *
* arch/ppc/kernel/irq.c
*
* Derived from arch/i386/kernel/irq.c
@@ -25,7 +23,6 @@
* should be easier.
*/
-
#include <linux/ptrace.h>
#include <linux/errno.h>
#include <linux/threads.h>
@@ -42,6 +39,7 @@
#include <linux/delay.h>
#include <linux/irq.h>
#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
#include <linux/random.h>
#include <asm/uaccess.h>
@@ -56,6 +54,7 @@
#include <asm/iSeries/LparData.h>
#include <asm/machdep.h>
#include <asm/paca.h>
+#include <asm/perfmon.h>
#include "local_irq.h"
@@ -99,7 +98,7 @@
* this needs to be removed.
* -- Cort
*/
-#define IRQ_KMALLOC_ENTRIES 8
+#define IRQ_KMALLOC_ENTRIES 16
static int cache_bitmask = 0;
static struct irqaction malloc_cache[IRQ_KMALLOC_ENTRIES];
extern int mem_init_done;
@@ -554,58 +553,61 @@
spin_unlock(&desc->lock);
}
-int do_IRQ(struct pt_regs *regs, int isfake)
+int do_IRQ(struct pt_regs *regs)
{
int cpu = smp_processor_id();
- int irq;
+ int irq, first = 1;
+#ifdef CONFIG_PPC_ISERIES
struct paca_struct *lpaca;
- struct ItLpQueue * lpq;
-
- /* if(cpu) udbg_printf("Entering do_IRQ\n"); */
-
- irq_enter(cpu);
+ struct ItLpQueue *lpq;
+#endif
- if (naca->platform != PLATFORM_ISERIES_LPAR) {
-
- /* every arch is required to have a get_irq -- Cort */
- irq = ppc_md.get_irq( regs );
+ irq_enter(cpu);
- if ( irq >= 0 ) {
- ppc_irq_dispatch_handler( regs, irq );
- if (ppc_md.post_irq)
- ppc_md.post_irq( regs, irq );
- } else {
- /* -2 means ignore, already handled */
- if (irq != -2) {
- printk(KERN_DEBUG "Bogus interrupt %d from PC = %lx\n",
- irq, regs->nip);
- ppc_spurious_interrupts++;
- }
- }
- }
- /* if on iSeries partition */
- else {
- lpaca = get_paca();
+#ifdef CONFIG_PPC_ISERIES
+ lpaca = get_paca();
#ifdef CONFIG_SMP
- if ( lpaca->xLpPaca.xIntDword.xFields.xIpiCnt ) {
- lpaca->xLpPaca.xIntDword.xFields.xIpiCnt = 0;
- iSeries_smp_message_recv( regs );
- }
-#endif /* CONFIG_SMP */
- lpq = lpaca->lpQueuePtr;
- if ( lpq && ItLpQueue_isLpIntPending( lpq ) )
- lpEvent_count += ItLpQueue_process( lpq, regs );
+ if (lpaca->xLpPaca.xIntDword.xFields.xIpiCnt) {
+ lpaca->xLpPaca.xIntDword.xFields.xIpiCnt = 0;
+ iSeries_smp_message_recv(regs);
}
-
+#endif /* CONFIG_SMP */
+ lpq = lpaca->lpQueuePtr;
+ if (lpq && ItLpQueue_isLpIntPending(lpq))
+ lpEvent_count += ItLpQueue_process(lpq, regs);
+#else
+ /*
+ * Every arch is required to implement ppc_md.get_irq.
+ * This function will either return an irq number or -1 to
+ * indicate there are no more pending. But the first time
+ * through the loop this means there wasn't an IRQ pending.
+ * The value -2 is for buggy hardware and means that this IRQ
+ * has already been handled. -- Tom
+ */
+ while ((irq = ppc_md.get_irq(regs)) >= 0) {
+ ppc_irq_dispatch_handler(regs, irq);
+ first = 0;
+ }
+ if (irq != -2 && first)
+ /* That's not SMP safe ... but who cares ? */
+ ppc_spurious_interrupts++;
+#endif
+
irq_exit(cpu);
- if (naca->platform == PLATFORM_ISERIES_LPAR) {
- if ( lpaca->xLpPaca.xIntDword.xFields.xDecrInt ) {
- lpaca->xLpPaca.xIntDword.xFields.xDecrInt = 0;
- /* Signal a fake decrementer interrupt */
- timer_interrupt( regs );
- }
+#ifdef CONFIG_PPC_ISERIES
+ if (lpaca->xLpPaca.xIntDword.xFields.xDecrInt) {
+ lpaca->xLpPaca.xIntDword.xFields.xDecrInt = 0;
+ /* Signal a fake decrementer interrupt */
+ timer_interrupt(regs);
+ }
+
+ if (lpaca->xLpPaca.xIntDword.xFields.xPdcInt) {
+ lpaca->xLpPaca.xIntDword.xFields.xPdcInt = 0;
+ /* Signal a fake PMC interrupt */
+ PerformanceMonitorException();
}
+#endif
if (softirq_pending(cpu))
do_softirq();
@@ -902,9 +904,11 @@
unsigned i;
for (i=0; i<MAX_PACAS; ++i) {
if ( paca[i].prof_buffer && (new_value & 1) )
- paca[i].prof_enabled = 1;
- else
- paca[i].prof_enabled = 0;
+ paca[i].prof_mode = PMC_STATE_DECR_PROFILE;
+ else {
+ if(paca[i].prof_mode != PMC_STATE_INITIAL)
+ paca[i].prof_mode = PMC_STATE_READY;
+ }
new_value >>= 1;
}
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)