aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/kernel/cpu/irq
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2009-05-22 00:29:37 -0400
committerPaul Mundt <lethal@linux-sh.org>2009-05-22 00:29:37 -0400
commit5f8371cec93b94a24a55ba1de642ce6eade6d62c (patch)
tree61b6d2acb10226b3c0f2d31bda3a49288e540eba /arch/sh/kernel/cpu/irq
parent8e9bb19ef97d6594e735bee64b6d72103e350854 (diff)
parentd8586ba6e1415150e1bab89f0a05447bb6f2d6d5 (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.c64
-rw-r--r--arch/sh/kernel/cpu/irq/intc-sh5.c36
-rw-r--r--arch/sh/kernel/cpu/irq/ipr.c8
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 */
25static unsigned long imask_mask = 0x7fff;
26static int interrupt_priority = 0;
27
28static void enable_imask_irq(unsigned int irq);
29static void disable_imask_irq(unsigned int irq);
30static void shutdown_imask_irq(unsigned int irq);
31static void mask_and_ack_imask(unsigned int);
32static void end_imask_irq(unsigned int irq);
33
34#define IMASK_PRIORITY 15 26#define IMASK_PRIORITY 15
35 27
36static unsigned int startup_imask_irq(unsigned int irq) 28static DECLARE_BITMAP(imask_mask, IMASK_PRIORITY);
37{ 29static int interrupt_priority;
38 /* Nothing to do */
39 return 0; /* never anything pending */
40}
41 30
42static struct hw_interrupt_type imask_irq_type = { 31static 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
52void 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
75static void disable_imask_irq(unsigned int irq) 54static 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
84static void enable_imask_irq(unsigned int irq) 62static 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
92static void mask_and_ack_imask(unsigned int irq) 70static 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,
97static 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
103static void shutdown_imask_irq(unsigned int irq)
104{
105 /* Nothing to do */
106}
107 76
108void make_imask_irq(unsigned int irq) 77void 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);
84static void mask_and_ack_intc(unsigned int); 84static void mask_and_ack_intc(unsigned int);
85static void end_intc_irq(unsigned int irq); 85static void end_intc_irq(unsigned int irq);
86 86
87static struct hw_interrupt_type intc_irq_type = { 87static 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) */
156void 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)
164static 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
176int 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
185void __init plat_irq_setup(void) 155void __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");