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 /arch/sh/kernel | |
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>
Diffstat (limited to 'arch/sh/kernel')
-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 | } |