|
@@ -18,38 +18,17 @@
|
|
|
#include <linux/spinlock.h>
|
|
|
#include <linux/cache.h>
|
|
|
#include <linux/irq.h>
|
|
|
+#include <linux/bitmap.h>
|
|
|
#include <asm/system.h>
|
|
|
#include <asm/irq.h>
|
|
|
|
|
|
/* Bitmap of IRQ masked */
|
|
|
-static unsigned long imask_mask = 0x7fff;
|
|
|
-static int interrupt_priority = 0;
|
|
|
-
|
|
|
-static void enable_imask_irq(unsigned int irq);
|
|
|
-static void disable_imask_irq(unsigned int irq);
|
|
|
-static void shutdown_imask_irq(unsigned int irq);
|
|
|
-static void mask_and_ack_imask(unsigned int);
|
|
|
-static void end_imask_irq(unsigned int irq);
|
|
|
-
|
|
|
#define IMASK_PRIORITY 15
|
|
|
|
|
|
-static unsigned int startup_imask_irq(unsigned int irq)
|
|
|
-{
|
|
|
- /* Nothing to do */
|
|
|
- return 0; /* never anything pending */
|
|
|
-}
|
|
|
+static DECLARE_BITMAP(imask_mask, IMASK_PRIORITY);
|
|
|
+static int interrupt_priority;
|
|
|
|
|
|
-static struct irq_chip imask_irq_type = {
|
|
|
- .typename = "SR.IMASK",
|
|
|
- .startup = startup_imask_irq,
|
|
|
- .shutdown = shutdown_imask_irq,
|
|
|
- .enable = enable_imask_irq,
|
|
|
- .disable = disable_imask_irq,
|
|
|
- .ack = mask_and_ack_imask,
|
|
|
- .end = end_imask_irq
|
|
|
-};
|
|
|
-
|
|
|
-void static inline set_interrupt_registers(int ip)
|
|
|
+static inline void set_interrupt_registers(int ip)
|
|
|
{
|
|
|
unsigned long __dummy;
|
|
|
|
|
@@ -72,42 +51,31 @@ void static inline set_interrupt_registers(int ip)
|
|
|
: "t");
|
|
|
}
|
|
|
|
|
|
-static void disable_imask_irq(unsigned int irq)
|
|
|
+static void mask_imask_irq(unsigned int irq)
|
|
|
{
|
|
|
clear_bit(irq, &imask_mask);
|
|
|
if (interrupt_priority < IMASK_PRIORITY - irq)
|
|
|
interrupt_priority = IMASK_PRIORITY - irq;
|
|
|
-
|
|
|
set_interrupt_registers(interrupt_priority);
|
|
|
}
|
|
|
|
|
|
-static void enable_imask_irq(unsigned int irq)
|
|
|
+static void unmask_imask_irq(unsigned int irq)
|
|
|
{
|
|
|
set_bit(irq, &imask_mask);
|
|
|
- interrupt_priority = IMASK_PRIORITY - ffz(imask_mask);
|
|
|
-
|
|
|
+ interrupt_priority = IMASK_PRIORITY -
|
|
|
+ find_first_zero_bit(imask_mask, IMASK_PRIORITY);
|
|
|
set_interrupt_registers(interrupt_priority);
|
|
|
}
|
|
|
|
|
|
-static void mask_and_ack_imask(unsigned int irq)
|
|
|
-{
|
|
|
- disable_imask_irq(irq);
|
|
|
-}
|
|
|
-
|
|
|
-static void end_imask_irq(unsigned int irq)
|
|
|
-{
|
|
|
- if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
|
|
|
- enable_imask_irq(irq);
|
|
|
-}
|
|
|
-
|
|
|
-static void shutdown_imask_irq(unsigned int irq)
|
|
|
-{
|
|
|
- /* Nothing to do */
|
|
|
-}
|
|
|
+static struct irq_chip imask_irq_chip = {
|
|
|
+ .typename = "SR.IMASK",
|
|
|
+ .mask = mask_imask_irq,
|
|
|
+ .unmask = unmask_imask_irq,
|
|
|
+ .mask_ack = mask_imask_irq,
|
|
|
+};
|
|
|
|
|
|
void make_imask_irq(unsigned int irq)
|
|
|
{
|
|
|
- disable_irq_nosync(irq);
|
|
|
- irq_desc[irq].chip = &imask_irq_type;
|
|
|
- enable_irq(irq);
|
|
|
+ set_irq_chip_and_handler_name(irq, &imask_irq_chip,
|
|
|
+ handle_level_irq, "level");
|
|
|
}
|