summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Thibault <samuel.thibault@ens-lyon.org>2019-11-12 22:03:30 +0100
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2019-11-12 22:03:30 +0100
commit955d33b3189d31dcdc86ea33a0def24f3e781340 (patch)
tree2b16096c2d05589117b72f0bdfb246e555147fb5
parent65c62a0ab0c2099c7bb4ba6a8e74173fa38a578e (diff)
parent259f75fa47ae7bc03c91cc102dc9480f14cd7266 (diff)
Merge branch 'master-user_level_drivers' into master-user_level_drivers-debian
-rw-r--r--linux/dev/arch/i386/kernel/irq.c93
1 files changed, 51 insertions, 42 deletions
diff --git a/linux/dev/arch/i386/kernel/irq.c b/linux/dev/arch/i386/kernel/irq.c
index 39f88b6b..a3b34956 100644
--- a/linux/dev/arch/i386/kernel/irq.c
+++ b/linux/dev/arch/i386/kernel/irq.c
@@ -90,6 +90,49 @@ static struct linux_action *irq_action[16] =
};
/*
+ * Mask an IRQ.
+ */
+static inline void
+mask_irq (unsigned int irq_nr)
+{
+ int new_pic_mask = curr_pic_mask | 1 << irq_nr;
+
+ if (curr_pic_mask != new_pic_mask)
+ {
+ curr_pic_mask = new_pic_mask;
+ if (irq_nr < 8)
+ outb (curr_pic_mask & 0xff, PIC_MASTER_OCW);
+ else
+ outb (curr_pic_mask >> 8, PIC_SLAVE_OCW);
+ }
+}
+
+/*
+ * Unmask an IRQ.
+ */
+static inline void
+unmask_irq (unsigned int irq_nr)
+{
+ int mask;
+ int new_pic_mask;
+
+ mask = 1 << irq_nr;
+ if (irq_nr >= 8)
+ mask |= 1 << 2;
+
+ new_pic_mask = curr_pic_mask & ~mask;
+
+ if (curr_pic_mask != new_pic_mask)
+ {
+ curr_pic_mask = new_pic_mask;
+ if (irq_nr < 8)
+ outb (curr_pic_mask & 0xff, PIC_MASTER_OCW);
+ else
+ outb (curr_pic_mask >> 8, PIC_SLAVE_OCW);
+ }
+}
+
+/*
* Generic interrupt handler for Linux devices.
* Set up a fake `struct pt_regs' then call the real handler.
*/
@@ -119,6 +162,7 @@ linux_intr (int irq)
*prev = action->next;
linux_kfree(action);
action = *prev;
+ continue;
}
}
else if (action->handler)
@@ -127,52 +171,17 @@ linux_intr (int irq)
action = action->next;
}
- restore_flags (flags);
-
- intr_count--;
-}
-
-/*
- * Mask an IRQ.
- */
-static inline void
-mask_irq (unsigned int irq_nr)
-{
- int new_pic_mask = curr_pic_mask | 1 << irq_nr;
-
- if (curr_pic_mask != new_pic_mask)
+ if (!irq_action[irq])
{
- curr_pic_mask = new_pic_mask;
- if (irq_nr < 8)
- outb (curr_pic_mask & 0xff, PIC_MASTER_OCW);
- else
- outb (curr_pic_mask >> 8, PIC_SLAVE_OCW);
+ /* No handler any more, disable interrupt */
+ mask_irq (irq);
+ ivect[irq] = intnull;
+ iunit[irq] = irq;
}
-}
-
-/*
- * Unmask an IRQ.
- */
-static inline void
-unmask_irq (unsigned int irq_nr)
-{
- int mask;
- int new_pic_mask;
-
- mask = 1 << irq_nr;
- if (irq_nr >= 8)
- mask |= 1 << 2;
- new_pic_mask = curr_pic_mask & ~mask;
+ restore_flags (flags);
- if (curr_pic_mask != new_pic_mask)
- {
- curr_pic_mask = new_pic_mask;
- if (irq_nr < 8)
- outb (curr_pic_mask & 0xff, PIC_MASTER_OCW);
- else
- outb (curr_pic_mask >> 8, PIC_SLAVE_OCW);
- }
+ intr_count--;
}
/* Count how many subsystems requested to disable each IRQ */