[PATCH][2.6] Nested Interrupt support
Jake Moilanen
moilanen at austin.ibm.com
Fri Jan 23 01:28:10 EST 2004
> Looks good. Could we use per cpu data here (do we init per cpu data
> before the xics setup)? Also Im wondering if we should have a quick
> check for overflow of the buffer.
>
Here's the patch using per cpu data for the irq stack.
Thanks,
Jake
-------------- next part --------------
# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
# ChangeSet 1.1393 -> 1.1394
# arch/ppc64/kernel/irq.c 1.54 -> 1.55
# arch/ppc64/kernel/xics.c 1.38 -> 1.39
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 04/01/22 moilanen at threadlp13.austin.ibm.com 1.1394
# Nested interrupt support.
# --------------------------------------------
#
diff -Nru a/arch/ppc64/kernel/irq.c b/arch/ppc64/kernel/irq.c
--- a/arch/ppc64/kernel/irq.c Thu Jan 22 08:20:25 2004
+++ b/arch/ppc64/kernel/irq.c Thu Jan 22 08:20:25 2004
@@ -822,16 +822,9 @@
}
out:
desc->status &= ~IRQ_INPROGRESS;
- /*
- * The ->end() handler has to deal with interrupts which got
- * disabled while the handler was running.
- */
- if (desc->handler) {
- if (desc->handler->end)
- desc->handler->end(irq);
- else if (desc->handler->enable)
- desc->handler->enable(irq);
- }
+
+ desc->handler->end(irq);
+
spin_unlock(&desc->lock);
}
diff -Nru a/arch/ppc64/kernel/xics.c b/arch/ppc64/kernel/xics.c
--- a/arch/ppc64/kernel/xics.c Thu Jan 22 08:20:25 2004
+++ b/arch/ppc64/kernel/xics.c Thu Jan 22 08:20:25 2004
@@ -92,6 +92,21 @@
static unsigned int default_server = 0xFF;
static unsigned int default_distrib_server = 0;
+/* Number of nested IRQs we can store */
+#define IRQ_DEPTH 2
+
+struct cpu_irq_stack
+{
+ int depth;
+ int priority[IRQ_DEPTH];
+ int irq[IRQ_DEPTH];
+};
+
+DEFINE_PER_CPU(struct cpu_irq_stack, _irq_stack);
+
+#define irq_stack __get_cpu_var(_irq_stack)
+#define irq_stack_depth (irq_stack).depth
+
/*
* XICS only has a single IPI, so encode the messages per CPU
*/
@@ -302,20 +317,36 @@
void xics_end_irq(unsigned int irq)
{
int cpu = smp_processor_id();
+ unsigned int priority;
+
+ if (irq >= 0 && irq != irq_offset_up(xics_irq_8259_cascade)) {
+ irq_stack_depth--;
+ priority = irq_stack.priority[irq_stack_depth];
+ } else {
+ priority = 0xff;
+ }
iosync();
- ops->xirr_info_set(cpu, ((0xff<<24) | (irq_offset_down(irq))));
+ ops->xirr_info_set(cpu, (priority<<24) | (irq_offset_down(irq)));
}
void xics_mask_and_ack_irq(u_int irq)
{
int cpu = smp_processor_id();
+ unsigned int priority;
if (irq < irq_offset_value()) {
+ if (irq >= 0) {
+ irq_stack_depth--;
+ priority = irq_stack.priority[irq_stack_depth];
+ } else {
+ priority = 0xff;
+ }
+
i8259_pic.ack(irq);
iosync();
- ops->xirr_info_set(cpu, ((0xff<<24) |
+ ops->xirr_info_set(cpu, ((priority<<24) |
xics_irq_8259_cascade_real));
iosync();
}
@@ -325,10 +356,12 @@
{
u_int cpu = smp_processor_id();
u_int vec;
+ u_int priority;
int irq;
vec = ops->xirr_info_get(cpu);
- /* (vec >> 24) == old priority */
+
+ priority = vec >> 24;
vec &= 0x00ffffff;
/* for sanity, this had better be < NR_IRQS - 16 */
@@ -345,6 +378,16 @@
} else {
irq = irq_offset_up(vec);
}
+
+ if (irq >= 0) {
+ if (irq_stack_depth >= IRQ_DEPTH)
+ panic("Illegal irq stack depth");
+
+ irq_stack.priority[irq_stack_depth] = priority;
+ irq_stack.irq[irq_stack_depth] = irq;
+ irq_stack_depth++;
+ }
+
return irq;
}
@@ -413,7 +456,7 @@
void xics_init_IRQ(void)
{
- int i;
+ int i, j;
unsigned long intr_size = 0;
struct device_node *np;
uint *ireg, ilen, indx = 0;
@@ -531,6 +574,14 @@
xics_8259_pic.disable = i8259_pic.disable;
for (i = 0; i < 16; ++i)
get_real_irq_desc(i)->handler = &xics_8259_pic;
+
+ for (i = 0; i < NR_CPUS; i++) {
+ per_cpu(_irq_stack, i).depth = 0;
+ for (j = 0; j < IRQ_DEPTH; j++) {
+ per_cpu(_irq_stack, i).priority[j] = 0xff;
+ per_cpu(_irq_stack, i).irq[j] = -1;
+ }
+ }
ops->cppr_info(boot_cpuid, 0xff);
iosync();
More information about the Linuxppc64-dev
mailing list