diff options
author | Paul Mundt <lethal@linux-sh.org> | 2009-05-22 00:29:37 -0400 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2009-05-22 00:29:37 -0400 |
commit | 5f8371cec93b94a24a55ba1de642ce6eade6d62c (patch) | |
tree | 61b6d2acb10226b3c0f2d31bda3a49288e540eba /arch/sh/kernel/cpu/irq | |
parent | 8e9bb19ef97d6594e735bee64b6d72103e350854 (diff) | |
parent | d8586ba6e1415150e1bab89f0a05447bb6f2d6d5 (diff) |
Merge branches 'sh/stable-updates' and 'sh/sparseirq'
Diffstat (limited to 'arch/sh/kernel/cpu/irq')
-rw-r--r-- | arch/sh/kernel/cpu/irq/imask.c | 64 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/irq/intc-sh5.c | 36 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/irq/ipr.c | 8 |
3 files changed, 27 insertions, 81 deletions
diff --git a/arch/sh/kernel/cpu/irq/imask.c b/arch/sh/kernel/cpu/irq/imask.c index 301b505c4278..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 hw_interrupt_type 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 | } |
diff --git a/arch/sh/kernel/cpu/irq/intc-sh5.c b/arch/sh/kernel/cpu/irq/intc-sh5.c index 726f0335da76..6c092f1f5557 100644 --- a/arch/sh/kernel/cpu/irq/intc-sh5.c +++ b/arch/sh/kernel/cpu/irq/intc-sh5.c | |||
@@ -84,7 +84,7 @@ static void disable_intc_irq(unsigned int irq); | |||
84 | static void mask_and_ack_intc(unsigned int); | 84 | static void mask_and_ack_intc(unsigned int); |
85 | static void end_intc_irq(unsigned int irq); | 85 | static void end_intc_irq(unsigned int irq); |
86 | 86 | ||
87 | static struct hw_interrupt_type intc_irq_type = { | 87 | static struct irq_chip intc_irq_type = { |
88 | .typename = "INTC", | 88 | .typename = "INTC", |
89 | .startup = startup_intc_irq, | 89 | .startup = startup_intc_irq, |
90 | .shutdown = shutdown_intc_irq, | 90 | .shutdown = shutdown_intc_irq, |
@@ -152,43 +152,13 @@ static void end_intc_irq(unsigned int irq) | |||
152 | enable_intc_irq(irq); | 152 | enable_intc_irq(irq); |
153 | } | 153 | } |
154 | 154 | ||
155 | /* For future use, if we ever support IRLM=0) */ | ||
156 | void make_intc_irq(unsigned int irq) | ||
157 | { | ||
158 | disable_irq_nosync(irq); | ||
159 | irq_desc[irq].chip = &intc_irq_type; | ||
160 | disable_intc_irq(irq); | ||
161 | } | ||
162 | |||
163 | #if defined(CONFIG_PROC_FS) && defined(CONFIG_SYSCTL) | ||
164 | static int IRQ_to_vectorN[NR_INTC_IRQS] = { | ||
165 | 0x12, 0x15, 0x18, 0x1B, 0x40, 0x41, 0x42, 0x43, /* 0- 7 */ | ||
166 | -1, -1, -1, -1, 0x50, 0x51, 0x52, 0x53, /* 8-15 */ | ||
167 | 0x54, 0x55, 0x32, 0x33, 0x34, 0x35, 0x36, -1, /* 16-23 */ | ||
168 | -1, -1, -1, -1, -1, -1, -1, -1, /* 24-31 */ | ||
169 | 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x38, /* 32-39 */ | ||
170 | 0x39, 0x3A, 0x3B, -1, -1, -1, -1, -1, /* 40-47 */ | ||
171 | -1, -1, -1, -1, -1, -1, -1, -1, /* 48-55 */ | ||
172 | -1, -1, -1, -1, -1, -1, -1, 0x2B, /* 56-63 */ | ||
173 | |||
174 | }; | ||
175 | |||
176 | int intc_irq_describe(char* p, int irq) | ||
177 | { | ||
178 | if (irq < NR_INTC_IRQS) | ||
179 | return sprintf(p, "(0x%3x)", IRQ_to_vectorN[irq]*0x20); | ||
180 | else | ||
181 | return 0; | ||
182 | } | ||
183 | #endif | ||
184 | |||
185 | void __init plat_irq_setup(void) | 155 | void __init plat_irq_setup(void) |
186 | { | 156 | { |
187 | unsigned long long __dummy0, __dummy1=~0x00000000100000f0; | 157 | unsigned long long __dummy0, __dummy1=~0x00000000100000f0; |
188 | unsigned long reg; | 158 | unsigned long reg; |
189 | int i; | 159 | int i; |
190 | 160 | ||
191 | intc_virt = onchip_remap(INTC_BASE, 1024, "INTC"); | 161 | intc_virt = (unsigned long)ioremap_nocache(INTC_BASE, 1024); |
192 | if (!intc_virt) { | 162 | if (!intc_virt) { |
193 | panic("Unable to remap INTC\n"); | 163 | panic("Unable to remap INTC\n"); |
194 | } | 164 | } |
@@ -196,7 +166,7 @@ void __init plat_irq_setup(void) | |||
196 | 166 | ||
197 | /* Set default: per-line enable/disable, priority driven ack/eoi */ | 167 | /* Set default: per-line enable/disable, priority driven ack/eoi */ |
198 | for (i = 0; i < NR_INTC_IRQS; i++) | 168 | for (i = 0; i < NR_INTC_IRQS; i++) |
199 | irq_desc[i].chip = &intc_irq_type; | 169 | set_irq_chip_and_handler(i, &intc_irq_type, handle_level_irq); |
200 | 170 | ||
201 | 171 | ||
202 | /* Disable all interrupts and set all priorities to 0 to avoid trouble */ | 172 | /* Disable all interrupts and set all priorities to 0 to avoid trouble */ |
diff --git a/arch/sh/kernel/cpu/irq/ipr.c b/arch/sh/kernel/cpu/irq/ipr.c index 3eb17ee5540e..fa0c8467a280 100644 --- a/arch/sh/kernel/cpu/irq/ipr.c +++ b/arch/sh/kernel/cpu/irq/ipr.c | |||
@@ -59,10 +59,18 @@ void register_ipr_controller(struct ipr_desc *desc) | |||
59 | 59 | ||
60 | for (i = 0; i < desc->nr_irqs; i++) { | 60 | for (i = 0; i < desc->nr_irqs; i++) { |
61 | struct ipr_data *p = desc->ipr_data + i; | 61 | struct ipr_data *p = desc->ipr_data + i; |
62 | struct irq_desc *irq_desc; | ||
62 | 63 | ||
63 | BUG_ON(p->ipr_idx >= desc->nr_offsets); | 64 | BUG_ON(p->ipr_idx >= desc->nr_offsets); |
64 | BUG_ON(!desc->ipr_offsets[p->ipr_idx]); | 65 | BUG_ON(!desc->ipr_offsets[p->ipr_idx]); |
65 | 66 | ||
67 | irq_desc = irq_to_desc_alloc_cpu(p->irq, smp_processor_id()); | ||
68 | if (unlikely(!irq_desc)) { | ||
69 | printk(KERN_INFO "can not get irq_desc for %d\n", | ||
70 | p->irq); | ||
71 | continue; | ||
72 | } | ||
73 | |||
66 | disable_irq_nosync(p->irq); | 74 | disable_irq_nosync(p->irq); |
67 | set_irq_chip_and_handler_name(p->irq, &desc->chip, | 75 | set_irq_chip_and_handler_name(p->irq, &desc->chip, |
68 | handle_level_irq, "level"); | 76 | handle_level_irq, "level"); |