1 #include <linux/config.h>
2 #include <linux/module.h>
3 #include <linux/stddef.h>
4 #include <linux/init.h>
5 #include <linux/sched.h>
6 #include <linux/signal.h>
8 #include <asm/8xx_immap.h>
9 #include <asm/mpc8xx.h>
10 #include "ppc8xx_pic.h"
12 /* The 8xx internal interrupt controller. It is usually
13 * the only interrupt controller. Some boards, like the MBX and
14 * Sandpoint have the 8259 as a secondary controller. Depending
15 * upon the processor type, the internal controller can have as
16 * few as 16 interrups or as many as 64. We could use the
17 * "clear_bit()" and "set_bit()" functions like other platforms,
18 * but they are overkill for us.
21 static void m8xx_mask_irq(unsigned int irq_nr)
28 ppc_cached_irq_mask[word] &= ~(1 << (31-bit));
29 ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_simask =
30 ppc_cached_irq_mask[word];
33 static void m8xx_unmask_irq(unsigned int irq_nr)
40 ppc_cached_irq_mask[word] |= (1 << (31-bit));
41 ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_simask =
42 ppc_cached_irq_mask[word];
45 static void m8xx_end_irq(unsigned int irq_nr)
47 if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS))
48 && irq_desc[irq_nr].action) {
54 ppc_cached_irq_mask[word] |= (1 << (31-bit));
55 ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_simask =
56 ppc_cached_irq_mask[word];
61 static void m8xx_mask_and_ack(unsigned int irq_nr)
68 ppc_cached_irq_mask[word] &= ~(1 << (31-bit));
69 ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_simask =
70 ppc_cached_irq_mask[word];
71 ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_sipend = 1 << (31-bit);
74 struct hw_interrupt_type ppc8xx_pic = {
87 m8xx_do_IRQ(struct pt_regs *regs,
91 unsigned long bits = 0;
93 /* For MPC8xx, read the SIVEC register and shift the bits down
94 * to get the irq number. */
95 bits = ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_sivec;
98 irq += ppc8xx_pic.irq_offset;
103 printk(KERN_DEBUG "Bogus interrupt %d from PC = %lx\n",
105 ppc_spurious_interrupts++;
108 ppc_irq_dispatch_handler( regs, irq );
116 * We either return a valid interrupt or -1 if there is nothing pending
119 m8xx_get_irq(struct pt_regs *regs)
123 /* For MPC8xx, read the SIVEC register and shift the bits down
124 * to get the irq number.
126 irq = ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_sivec >> 26;
129 * When we read the sivec without an interrupt to process, we will
130 * get back SIU_LEVEL7. In this case, return -1
132 if (irq == SIU_LEVEL7)
138 /* The MBX is the only 8xx board that uses the 8259.
140 #if defined(CONFIG_MBX) && defined(CONFIG_PCI)
141 void mbx_i8259_action(int cpl, void *dev_id, struct pt_regs *regs)
145 /* A bug in the QSpan chip causes it to give us 0xff always
146 * when doing a character read. So read 32 bits and shift.
147 * This doesn't seem to return useful values anyway, but
148 * read it to make sure things are acked.
151 irq = (inl(0x508) >> 24)&0xff;
152 if ( irq != 0xff ) printk("iack %d\n", irq);
163 irq += i8259_pic.irq_offset;
164 ppc_irq_dispatch_handler( regs, irq );
168 /* Only the MBX uses the external 8259. This allows us to catch standard
169 * drivers that may mess up the internal interrupt controllers, and also
170 * allow them to run without modification on the MBX.
172 int request_irq(unsigned int irq,
173 irqreturn_t (*handler)(int, void *, struct pt_regs *),
174 unsigned long irqflags, const char * devname, void *dev_id)
177 #if defined(CONFIG_MBX) && defined(CONFIG_PCI)
178 irq += i8259_pic.irq_offset;
179 return (request_8xxirq(irq, handler, irqflags, devname, dev_id));
182 * Handle other "well-known" interrupts, but panic on unknown ones.
185 #ifdef IDE0_INTERRUPT
186 case IDE0_INTERRUPT: /* IDE0 */
187 return (request_8xxirq(irq, handler, irqflags, devname,
190 #ifdef IDE1_INTERRUPT
191 case IDE1_INTERRUPT: /* IDE1 */
192 return (request_8xxirq(irq, handler, irqflags, devname,
195 default: /* unknown IRQ -> panic */
196 panic("request_irq");
201 EXPORT_SYMBOL(request_irq);