1#include <linux/module.h>
2#include <linux/stddef.h>
3#include <linux/init.h>
4#include <linux/sched.h>
5#include <linux/signal.h>
6#include <linux/interrupt.h>
7#include <asm/irq.h>
8#include <asm/io.h>
9#include <asm/8xx_immap.h>
10#include <asm/mpc8xx.h>
11#include "ppc8xx_pic.h"
12
13extern int cpm_get_irq(void);
14
15
16
17
18
19
20
21
22
23
24static void m8xx_mask_irq(unsigned int irq_nr)
25{
26 int bit, word;
27
28 bit = irq_nr & 0x1f;
29 word = irq_nr >> 5;
30
31 ppc_cached_irq_mask[word] &= ~(1 << (31-bit));
32 out_be32(&((immap_t *)IMAP_ADDR)->im_siu_conf.sc_simask, ppc_cached_irq_mask[word]);
33}
34
35static void m8xx_unmask_irq(unsigned int irq_nr)
36{
37 int bit, word;
38
39 bit = irq_nr & 0x1f;
40 word = irq_nr >> 5;
41
42 ppc_cached_irq_mask[word] |= (1 << (31-bit));
43 out_be32(&((immap_t *)IMAP_ADDR)->im_siu_conf.sc_simask, ppc_cached_irq_mask[word]);
44}
45
46static void m8xx_end_irq(unsigned int irq_nr)
47{
48 if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS))
49 && irq_desc[irq_nr].action) {
50 int bit, word;
51
52 bit = irq_nr & 0x1f;
53 word = irq_nr >> 5;
54
55 ppc_cached_irq_mask[word] |= (1 << (31-bit));
56 out_be32(&((immap_t *)IMAP_ADDR)->im_siu_conf.sc_simask, ppc_cached_irq_mask[word]);
57 }
58}
59
60
61static void m8xx_mask_and_ack(unsigned int irq_nr)
62{
63 int bit, word;
64
65 bit = irq_nr & 0x1f;
66 word = irq_nr >> 5;
67
68 ppc_cached_irq_mask[word] &= ~(1 << (31-bit));
69 out_be32(&((immap_t *)IMAP_ADDR)->im_siu_conf.sc_simask, ppc_cached_irq_mask[word]);
70 out_be32(&((immap_t *)IMAP_ADDR)->im_siu_conf.sc_sipend, 1 << (31-bit));
71}
72
73struct hw_interrupt_type ppc8xx_pic = {
74 .typename = " 8xx SIU ",
75 .enable = m8xx_unmask_irq,
76 .disable = m8xx_mask_irq,
77 .ack = m8xx_mask_and_ack,
78 .end = m8xx_end_irq,
79};
80
81
82
83
84int
85m8xx_get_irq(struct pt_regs *regs)
86{
87 int irq;
88
89
90
91
92 irq = in_be32(&((immap_t *)IMAP_ADDR)->im_siu_conf.sc_sivec) >> 26;
93
94
95
96
97
98 if (irq == CPM_INTERRUPT)
99 irq = CPM_IRQ_OFFSET + cpm_get_irq();
100#if defined(CONFIG_PCI)
101 else if (irq == ISA_BRIDGE_INT) {
102 int isa_irq;
103
104 if ((isa_irq = i8259_poll(regs)) >= 0)
105 irq = I8259_IRQ_OFFSET + isa_irq;
106 }
107#endif
108 else if (irq == SIU_LEVEL7)
109 irq = -1;
110
111 return irq;
112}
113
114#if defined(CONFIG_MBX) && defined(CONFIG_PCI)
115
116
117
118
119void mbx_i8259_action(int irq, void *dev_id, struct pt_regs *regs)
120{
121
122
123
124
125}
126#endif
127