aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel/i8259.c
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
commitc71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch)
treeecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /arch/mips/kernel/i8259.c
parentea53c912f8a86a8567697115b6a0d8152beee5c8 (diff)
parent6a00f206debf8a5c8899055726ad127dbeeed098 (diff)
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts: litmus/sched_cedf.c
Diffstat (limited to 'arch/mips/kernel/i8259.c')
-rw-r--r--arch/mips/kernel/i8259.c66
1 files changed, 27 insertions, 39 deletions
diff --git a/arch/mips/kernel/i8259.c b/arch/mips/kernel/i8259.c
index 27799113332c..5c74eb797f08 100644
--- a/arch/mips/kernel/i8259.c
+++ b/arch/mips/kernel/i8259.c
@@ -14,7 +14,8 @@
14#include <linux/interrupt.h> 14#include <linux/interrupt.h>
15#include <linux/kernel.h> 15#include <linux/kernel.h>
16#include <linux/spinlock.h> 16#include <linux/spinlock.h>
17#include <linux/sysdev.h> 17#include <linux/syscore_ops.h>
18#include <linux/irq.h>
18 19
19#include <asm/i8259.h> 20#include <asm/i8259.h>
20#include <asm/io.h> 21#include <asm/io.h>
@@ -30,19 +31,19 @@
30 31
31static int i8259A_auto_eoi = -1; 32static int i8259A_auto_eoi = -1;
32DEFINE_RAW_SPINLOCK(i8259A_lock); 33DEFINE_RAW_SPINLOCK(i8259A_lock);
33static void disable_8259A_irq(unsigned int irq); 34static void disable_8259A_irq(struct irq_data *d);
34static void enable_8259A_irq(unsigned int irq); 35static void enable_8259A_irq(struct irq_data *d);
35static void mask_and_ack_8259A(unsigned int irq); 36static void mask_and_ack_8259A(struct irq_data *d);
36static void init_8259A(int auto_eoi); 37static void init_8259A(int auto_eoi);
37 38
38static struct irq_chip i8259A_chip = { 39static struct irq_chip i8259A_chip = {
39 .name = "XT-PIC", 40 .name = "XT-PIC",
40 .mask = disable_8259A_irq, 41 .irq_mask = disable_8259A_irq,
41 .disable = disable_8259A_irq, 42 .irq_disable = disable_8259A_irq,
42 .unmask = enable_8259A_irq, 43 .irq_unmask = enable_8259A_irq,
43 .mask_ack = mask_and_ack_8259A, 44 .irq_mask_ack = mask_and_ack_8259A,
44#ifdef CONFIG_MIPS_MT_SMTC_IRQAFF 45#ifdef CONFIG_MIPS_MT_SMTC_IRQAFF
45 .set_affinity = plat_set_irq_affinity, 46 .irq_set_affinity = plat_set_irq_affinity,
46#endif /* CONFIG_MIPS_MT_SMTC_IRQAFF */ 47#endif /* CONFIG_MIPS_MT_SMTC_IRQAFF */
47}; 48};
48 49
@@ -58,12 +59,11 @@ static unsigned int cached_irq_mask = 0xffff;
58#define cached_master_mask (cached_irq_mask) 59#define cached_master_mask (cached_irq_mask)
59#define cached_slave_mask (cached_irq_mask >> 8) 60#define cached_slave_mask (cached_irq_mask >> 8)
60 61
61static void disable_8259A_irq(unsigned int irq) 62static void disable_8259A_irq(struct irq_data *d)
62{ 63{
63 unsigned int mask; 64 unsigned int mask, irq = d->irq - I8259A_IRQ_BASE;
64 unsigned long flags; 65 unsigned long flags;
65 66
66 irq -= I8259A_IRQ_BASE;
67 mask = 1 << irq; 67 mask = 1 << irq;
68 raw_spin_lock_irqsave(&i8259A_lock, flags); 68 raw_spin_lock_irqsave(&i8259A_lock, flags);
69 cached_irq_mask |= mask; 69 cached_irq_mask |= mask;
@@ -74,12 +74,11 @@ static void disable_8259A_irq(unsigned int irq)
74 raw_spin_unlock_irqrestore(&i8259A_lock, flags); 74 raw_spin_unlock_irqrestore(&i8259A_lock, flags);
75} 75}
76 76
77static void enable_8259A_irq(unsigned int irq) 77static void enable_8259A_irq(struct irq_data *d)
78{ 78{
79 unsigned int mask; 79 unsigned int mask, irq = d->irq - I8259A_IRQ_BASE;
80 unsigned long flags; 80 unsigned long flags;
81 81
82 irq -= I8259A_IRQ_BASE;
83 mask = ~(1 << irq); 82 mask = ~(1 << irq);
84 raw_spin_lock_irqsave(&i8259A_lock, flags); 83 raw_spin_lock_irqsave(&i8259A_lock, flags);
85 cached_irq_mask &= mask; 84 cached_irq_mask &= mask;
@@ -111,7 +110,7 @@ int i8259A_irq_pending(unsigned int irq)
111void make_8259A_irq(unsigned int irq) 110void make_8259A_irq(unsigned int irq)
112{ 111{
113 disable_irq_nosync(irq); 112 disable_irq_nosync(irq);
114 set_irq_chip_and_handler(irq, &i8259A_chip, handle_level_irq); 113 irq_set_chip_and_handler(irq, &i8259A_chip, handle_level_irq);
115 enable_irq(irq); 114 enable_irq(irq);
116} 115}
117 116
@@ -144,12 +143,11 @@ static inline int i8259A_irq_real(unsigned int irq)
144 * first, _then_ send the EOI, and the order of EOI 143 * first, _then_ send the EOI, and the order of EOI
145 * to the two 8259s is important! 144 * to the two 8259s is important!
146 */ 145 */
147static void mask_and_ack_8259A(unsigned int irq) 146static void mask_and_ack_8259A(struct irq_data *d)
148{ 147{
149 unsigned int irqmask; 148 unsigned int irqmask, irq = d->irq - I8259A_IRQ_BASE;
150 unsigned long flags; 149 unsigned long flags;
151 150
152 irq -= I8259A_IRQ_BASE;
153 irqmask = 1 << irq; 151 irqmask = 1 << irq;
154 raw_spin_lock_irqsave(&i8259A_lock, flags); 152 raw_spin_lock_irqsave(&i8259A_lock, flags);
155 /* 153 /*
@@ -217,14 +215,13 @@ spurious_8259A_irq:
217 } 215 }
218} 216}
219 217
220static int i8259A_resume(struct sys_device *dev) 218static void i8259A_resume(void)
221{ 219{
222 if (i8259A_auto_eoi >= 0) 220 if (i8259A_auto_eoi >= 0)
223 init_8259A(i8259A_auto_eoi); 221 init_8259A(i8259A_auto_eoi);
224 return 0;
225} 222}
226 223
227static int i8259A_shutdown(struct sys_device *dev) 224static void i8259A_shutdown(void)
228{ 225{
229 /* Put the i8259A into a quiescent state that 226 /* Put the i8259A into a quiescent state that
230 * the kernel initialization code can get it 227 * the kernel initialization code can get it
@@ -234,26 +231,17 @@ static int i8259A_shutdown(struct sys_device *dev)
234 outb(0xff, PIC_MASTER_IMR); /* mask all of 8259A-1 */ 231 outb(0xff, PIC_MASTER_IMR); /* mask all of 8259A-1 */
235 outb(0xff, PIC_SLAVE_IMR); /* mask all of 8259A-1 */ 232 outb(0xff, PIC_SLAVE_IMR); /* mask all of 8259A-1 */
236 } 233 }
237 return 0;
238} 234}
239 235
240static struct sysdev_class i8259_sysdev_class = { 236static struct syscore_ops i8259_syscore_ops = {
241 .name = "i8259",
242 .resume = i8259A_resume, 237 .resume = i8259A_resume,
243 .shutdown = i8259A_shutdown, 238 .shutdown = i8259A_shutdown,
244}; 239};
245 240
246static struct sys_device device_i8259A = {
247 .id = 0,
248 .cls = &i8259_sysdev_class,
249};
250
251static int __init i8259A_init_sysfs(void) 241static int __init i8259A_init_sysfs(void)
252{ 242{
253 int error = sysdev_class_register(&i8259_sysdev_class); 243 register_syscore_ops(&i8259_syscore_ops);
254 if (!error) 244 return 0;
255 error = sysdev_register(&device_i8259A);
256 return error;
257} 245}
258 246
259device_initcall(i8259A_init_sysfs); 247device_initcall(i8259A_init_sysfs);
@@ -289,9 +277,9 @@ static void init_8259A(int auto_eoi)
289 * In AEOI mode we just have to mask the interrupt 277 * In AEOI mode we just have to mask the interrupt
290 * when acking. 278 * when acking.
291 */ 279 */
292 i8259A_chip.mask_ack = disable_8259A_irq; 280 i8259A_chip.irq_mask_ack = disable_8259A_irq;
293 else 281 else
294 i8259A_chip.mask_ack = mask_and_ack_8259A; 282 i8259A_chip.irq_mask_ack = mask_and_ack_8259A;
295 283
296 udelay(100); /* wait for 8259A to initialize */ 284 udelay(100); /* wait for 8259A to initialize */
297 285
@@ -338,8 +326,8 @@ void __init init_i8259_irqs(void)
338 init_8259A(0); 326 init_8259A(0);
339 327
340 for (i = I8259A_IRQ_BASE; i < I8259A_IRQ_BASE + 16; i++) { 328 for (i = I8259A_IRQ_BASE; i < I8259A_IRQ_BASE + 16; i++) {
341 set_irq_chip_and_handler(i, &i8259A_chip, handle_level_irq); 329 irq_set_chip_and_handler(i, &i8259A_chip, handle_level_irq);
342 set_irq_probe(i); 330 irq_set_probe(i);
343 } 331 }
344 332
345 setup_irq(I8259A_IRQ_BASE + PIC_CASCADE_IR, &irq2); 333 setup_irq(I8259A_IRQ_BASE + PIC_CASCADE_IR, &irq2);