diff options
| author | Paul Mundt <lethal@linux-sh.org> | 2009-05-21 12:16:17 -0400 |
|---|---|---|
| committer | Paul Mundt <lethal@linux-sh.org> | 2009-05-21 12:16:17 -0400 |
| commit | 55620c86ebc29013c0d26c5b3bc423faea299fee (patch) | |
| tree | 90d1206ec8f668e073f31fc36c991d034b6af8e0 | |
| parent | 62669e61a5f559826b1d2e863649a6005eee629b (diff) | |
sh: irq: Rework the SR.IMASK bitmap handling.
This tidies up how the SR.IMASK bitmap is managed, using the bitmap API
directly instead. At the same time, tidy up the irq_chip conversion a
bit.
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
| -rw-r--r-- | arch/sh/kernel/cpu/irq/imask.c | 64 |
1 files changed, 16 insertions, 48 deletions
diff --git a/arch/sh/kernel/cpu/irq/imask.c b/arch/sh/kernel/cpu/irq/imask.c index f43753b54e1d..3bef3c2629ad 100644 --- a/arch/sh/kernel/cpu/irq/imask.c +++ b/arch/sh/kernel/cpu/irq/imask.c | |||
| @@ -18,38 +18,17 @@ | |||
| 18 | #include <linux/spinlock.h> | 18 | #include <linux/spinlock.h> |
| 19 | #include <linux/cache.h> | 19 | #include <linux/cache.h> |
| 20 | #include <linux/irq.h> | 20 | #include <linux/irq.h> |
| 21 | #include <linux/bitmap.h> | ||
| 21 | #include <asm/system.h> | 22 | #include <asm/system.h> |
| 22 | #include <asm/irq.h> | 23 | #include <asm/irq.h> |
| 23 | 24 | ||
| 24 | /* Bitmap of IRQ masked */ | 25 | /* Bitmap of IRQ masked */ |
| 25 | static unsigned long imask_mask = 0x7fff; | ||
| 26 | static int interrupt_priority = 0; | ||
| 27 | |||
| 28 | static void enable_imask_irq(unsigned int irq); | ||
| 29 | static void disable_imask_irq(unsigned int irq); | ||
| 30 | static void shutdown_imask_irq(unsigned int irq); | ||
| 31 | static void mask_and_ack_imask(unsigned int); | ||
| 32 | static void end_imask_irq(unsigned int irq); | ||
| 33 | |||
| 34 | #define IMASK_PRIORITY 15 | 26 | #define IMASK_PRIORITY 15 |
| 35 | 27 | ||
| 36 | static unsigned int startup_imask_irq(unsigned int irq) | 28 | static DECLARE_BITMAP(imask_mask, IMASK_PRIORITY); |
| 37 | { | 29 | static int interrupt_priority; |
| 38 | /* Nothing to do */ | ||
| 39 | return 0; /* never anything pending */ | ||
| 40 | } | ||
| 41 | 30 | ||
| 42 | static struct irq_chip imask_irq_type = { | 31 | static inline void set_interrupt_registers(int ip) |
| 43 | .typename = "SR.IMASK", | ||
| 44 | .startup = startup_imask_irq, | ||
| 45 | .shutdown = shutdown_imask_irq, | ||
| 46 | .enable = enable_imask_irq, | ||
| 47 | .disable = disable_imask_irq, | ||
| 48 | .ack = mask_and_ack_imask, | ||
| 49 | .end = end_imask_irq | ||
| 50 | }; | ||
| 51 | |||
| 52 | void static inline set_interrupt_registers(int ip) | ||
| 53 | { | 32 | { |
| 54 | unsigned long __dummy; | 33 | unsigned long __dummy; |
| 55 | 34 | ||
| @@ -72,42 +51,31 @@ void static inline set_interrupt_registers(int ip) | |||
| 72 | : "t"); | 51 | : "t"); |
| 73 | } | 52 | } |
| 74 | 53 | ||
| 75 | static void disable_imask_irq(unsigned int irq) | 54 | static void mask_imask_irq(unsigned int irq) |
| 76 | { | 55 | { |
| 77 | clear_bit(irq, &imask_mask); | 56 | clear_bit(irq, &imask_mask); |
| 78 | if (interrupt_priority < IMASK_PRIORITY - irq) | 57 | if (interrupt_priority < IMASK_PRIORITY - irq) |
| 79 | interrupt_priority = IMASK_PRIORITY - irq; | 58 | interrupt_priority = IMASK_PRIORITY - irq; |
| 80 | |||
| 81 | set_interrupt_registers(interrupt_priority); | 59 | set_interrupt_registers(interrupt_priority); |
| 82 | } | 60 | } |
| 83 | 61 | ||
| 84 | static void enable_imask_irq(unsigned int irq) | 62 | static void unmask_imask_irq(unsigned int irq) |
| 85 | { | 63 | { |
| 86 | set_bit(irq, &imask_mask); | 64 | set_bit(irq, &imask_mask); |
| 87 | interrupt_priority = IMASK_PRIORITY - ffz(imask_mask); | 65 | interrupt_priority = IMASK_PRIORITY - |
| 88 | 66 | find_first_zero_bit(imask_mask, IMASK_PRIORITY); | |
| 89 | set_interrupt_registers(interrupt_priority); | 67 | set_interrupt_registers(interrupt_priority); |
| 90 | } | 68 | } |
| 91 | 69 | ||
| 92 | static void mask_and_ack_imask(unsigned int irq) | 70 | static struct irq_chip imask_irq_chip = { |
| 93 | { | 71 | .typename = "SR.IMASK", |
| 94 | disable_imask_irq(irq); | 72 | .mask = mask_imask_irq, |
| 95 | } | 73 | .unmask = unmask_imask_irq, |
| 96 | 74 | .mask_ack = mask_imask_irq, | |
| 97 | static void end_imask_irq(unsigned int irq) | 75 | }; |
| 98 | { | ||
| 99 | if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) | ||
| 100 | enable_imask_irq(irq); | ||
| 101 | } | ||
| 102 | |||
| 103 | static void shutdown_imask_irq(unsigned int irq) | ||
| 104 | { | ||
| 105 | /* Nothing to do */ | ||
| 106 | } | ||
| 107 | 76 | ||
| 108 | void make_imask_irq(unsigned int irq) | 77 | void make_imask_irq(unsigned int irq) |
| 109 | { | 78 | { |
| 110 | disable_irq_nosync(irq); | 79 | set_irq_chip_and_handler_name(irq, &imask_irq_chip, |
| 111 | irq_desc[irq].chip = &imask_irq_type; | 80 | handle_level_irq, "level"); |
| 112 | enable_irq(irq); | ||
| 113 | } | 81 | } |
