diff options
Diffstat (limited to 'arch/mips/alchemy/common/irq.c')
-rw-r--r-- | arch/mips/alchemy/common/irq.c | 604 |
1 files changed, 309 insertions, 295 deletions
diff --git a/arch/mips/alchemy/common/irq.c b/arch/mips/alchemy/common/irq.c index d670928afcfd..9f78ada83b3c 100644 --- a/arch/mips/alchemy/common/irq.c +++ b/arch/mips/alchemy/common/irq.c | |||
@@ -29,6 +29,8 @@ | |||
29 | #include <linux/init.h> | 29 | #include <linux/init.h> |
30 | #include <linux/interrupt.h> | 30 | #include <linux/interrupt.h> |
31 | #include <linux/irq.h> | 31 | #include <linux/irq.h> |
32 | #include <linux/slab.h> | ||
33 | #include <linux/sysdev.h> | ||
32 | 34 | ||
33 | #include <asm/irq_cpu.h> | 35 | #include <asm/irq_cpu.h> |
34 | #include <asm/mipsregs.h> | 36 | #include <asm/mipsregs.h> |
@@ -39,253 +41,181 @@ | |||
39 | 41 | ||
40 | static int au1x_ic_settype(unsigned int irq, unsigned int flow_type); | 42 | static int au1x_ic_settype(unsigned int irq, unsigned int flow_type); |
41 | 43 | ||
44 | /* NOTE on interrupt priorities: The original writers of this code said: | ||
45 | * | ||
46 | * Because of the tight timing of SETUP token to reply transactions, | ||
47 | * the USB devices-side packet complete interrupt (USB_DEV_REQ_INT) | ||
48 | * needs the highest priority. | ||
49 | */ | ||
50 | |||
42 | /* per-processor fixed function irqs */ | 51 | /* per-processor fixed function irqs */ |
43 | struct au1xxx_irqmap au1xxx_ic0_map[] __initdata = { | 52 | struct au1xxx_irqmap { |
44 | 53 | int im_irq; | |
45 | #if defined(CONFIG_SOC_AU1000) | 54 | int im_type; |
46 | { AU1000_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | 55 | int im_request; /* set 1 to get higher priority */ |
47 | { AU1000_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | 56 | }; |
48 | { AU1000_UART2_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | 57 | |
49 | { AU1000_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | 58 | struct au1xxx_irqmap au1000_irqmap[] __initdata = { |
50 | { AU1000_SSI0_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | 59 | { AU1000_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
51 | { AU1000_SSI1_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | 60 | { AU1000_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
52 | { AU1000_DMA_INT_BASE, IRQ_TYPE_LEVEL_HIGH, 0 }, | 61 | { AU1000_UART2_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
53 | { AU1000_DMA_INT_BASE+1, IRQ_TYPE_LEVEL_HIGH, 0 }, | 62 | { AU1000_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
54 | { AU1000_DMA_INT_BASE+2, IRQ_TYPE_LEVEL_HIGH, 0 }, | 63 | { AU1000_SSI0_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
55 | { AU1000_DMA_INT_BASE+3, IRQ_TYPE_LEVEL_HIGH, 0 }, | 64 | { AU1000_SSI1_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
56 | { AU1000_DMA_INT_BASE+4, IRQ_TYPE_LEVEL_HIGH, 0 }, | 65 | { AU1000_DMA_INT_BASE, IRQ_TYPE_LEVEL_HIGH, 0 }, |
57 | { AU1000_DMA_INT_BASE+5, IRQ_TYPE_LEVEL_HIGH, 0 }, | 66 | { AU1000_DMA_INT_BASE+1, IRQ_TYPE_LEVEL_HIGH, 0 }, |
58 | { AU1000_DMA_INT_BASE+6, IRQ_TYPE_LEVEL_HIGH, 0 }, | 67 | { AU1000_DMA_INT_BASE+2, IRQ_TYPE_LEVEL_HIGH, 0 }, |
59 | { AU1000_DMA_INT_BASE+7, IRQ_TYPE_LEVEL_HIGH, 0 }, | 68 | { AU1000_DMA_INT_BASE+3, IRQ_TYPE_LEVEL_HIGH, 0 }, |
60 | { AU1000_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 69 | { AU1000_DMA_INT_BASE+4, IRQ_TYPE_LEVEL_HIGH, 0 }, |
61 | { AU1000_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 70 | { AU1000_DMA_INT_BASE+5, IRQ_TYPE_LEVEL_HIGH, 0 }, |
62 | { AU1000_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 71 | { AU1000_DMA_INT_BASE+6, IRQ_TYPE_LEVEL_HIGH, 0 }, |
63 | { AU1000_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 }, | 72 | { AU1000_DMA_INT_BASE+7, IRQ_TYPE_LEVEL_HIGH, 0 }, |
64 | { AU1000_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 73 | { AU1000_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
65 | { AU1000_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 74 | { AU1000_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
66 | { AU1000_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 75 | { AU1000_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
67 | { AU1000_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 76 | { AU1000_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
68 | { AU1000_IRDA_TX_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | 77 | { AU1000_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
69 | { AU1000_IRDA_RX_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | 78 | { AU1000_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
70 | { AU1000_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | 79 | { AU1000_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
71 | { AU1000_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 80 | { AU1000_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 }, |
72 | { AU1000_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 0 }, | 81 | { AU1000_IRDA_TX_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
73 | { AU1000_ACSYNC_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 82 | { AU1000_IRDA_RX_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
74 | { AU1000_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | 83 | { AU1000_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 1 }, |
75 | { AU1000_MAC1_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
76 | { AU1000_AC97C_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
77 | |||
78 | #elif defined(CONFIG_SOC_AU1500) | ||
79 | |||
80 | { AU1500_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
81 | { AU1000_PCI_INTA, IRQ_TYPE_LEVEL_LOW, 0 }, | ||
82 | { AU1000_PCI_INTB, IRQ_TYPE_LEVEL_LOW, 0 }, | ||
83 | { AU1500_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
84 | { AU1000_PCI_INTC, IRQ_TYPE_LEVEL_LOW, 0 }, | ||
85 | { AU1000_PCI_INTD, IRQ_TYPE_LEVEL_LOW, 0 }, | ||
86 | { AU1000_DMA_INT_BASE, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
87 | { AU1000_DMA_INT_BASE+1, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
88 | { AU1000_DMA_INT_BASE+2, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
89 | { AU1000_DMA_INT_BASE+3, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
90 | { AU1000_DMA_INT_BASE+4, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
91 | { AU1000_DMA_INT_BASE+5, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
92 | { AU1000_DMA_INT_BASE+6, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
93 | { AU1000_DMA_INT_BASE+7, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
94 | { AU1000_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
95 | { AU1000_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
96 | { AU1000_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
97 | { AU1000_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 }, | ||
98 | { AU1000_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
99 | { AU1000_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
100 | { AU1000_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
101 | { AU1000_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
102 | { AU1000_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
103 | { AU1000_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
104 | { AU1000_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 0 }, | ||
105 | { AU1000_ACSYNC_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
106 | { AU1500_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
107 | { AU1500_MAC1_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
108 | { AU1000_AC97C_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
109 | |||
110 | #elif defined(CONFIG_SOC_AU1100) | ||
111 | |||
112 | { AU1100_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
113 | { AU1100_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
114 | { AU1100_SD_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
115 | { AU1100_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
116 | { AU1000_SSI0_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
117 | { AU1000_SSI1_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
118 | { AU1000_DMA_INT_BASE, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
119 | { AU1000_DMA_INT_BASE+1, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
120 | { AU1000_DMA_INT_BASE+2, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
121 | { AU1000_DMA_INT_BASE+3, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
122 | { AU1000_DMA_INT_BASE+4, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
123 | { AU1000_DMA_INT_BASE+5, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
124 | { AU1000_DMA_INT_BASE+6, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
125 | { AU1000_DMA_INT_BASE+7, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
126 | { AU1000_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
127 | { AU1000_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
128 | { AU1000_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
129 | { AU1000_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 }, | ||
130 | { AU1000_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
131 | { AU1000_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
132 | { AU1000_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
133 | { AU1000_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
134 | { AU1000_IRDA_TX_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
135 | { AU1000_IRDA_RX_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
136 | { AU1000_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
137 | { AU1000_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 84 | { AU1000_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
138 | { AU1000_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 0 }, | 85 | { AU1000_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 0 }, |
139 | { AU1000_ACSYNC_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 86 | { AU1000_ACSYNC_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
140 | { AU1100_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | 87 | { AU1000_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
141 | { AU1100_LCD_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | 88 | { AU1000_MAC1_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
142 | { AU1000_AC97C_INT, IRQ_TYPE_EDGE_RISING, 0 }, | 89 | { AU1000_AC97C_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
143 | 90 | { -1, }, | |
144 | #elif defined(CONFIG_SOC_AU1550) | ||
145 | |||
146 | { AU1550_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
147 | { AU1550_PCI_INTA, IRQ_TYPE_LEVEL_LOW, 0 }, | ||
148 | { AU1550_PCI_INTB, IRQ_TYPE_LEVEL_LOW, 0 }, | ||
149 | { AU1550_DDMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
150 | { AU1550_CRYPTO_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
151 | { AU1550_PCI_INTC, IRQ_TYPE_LEVEL_LOW, 0 }, | ||
152 | { AU1550_PCI_INTD, IRQ_TYPE_LEVEL_LOW, 0 }, | ||
153 | { AU1550_PCI_RST_INT, IRQ_TYPE_LEVEL_LOW, 0 }, | ||
154 | { AU1550_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
155 | { AU1550_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
156 | { AU1550_PSC0_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
157 | { AU1550_PSC1_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
158 | { AU1550_PSC2_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
159 | { AU1550_PSC3_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
160 | { AU1000_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
161 | { AU1000_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
162 | { AU1000_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
163 | { AU1000_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 }, | ||
164 | { AU1000_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
165 | { AU1000_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
166 | { AU1000_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
167 | { AU1000_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
168 | { AU1550_NAND_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
169 | { AU1550_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
170 | { AU1550_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
171 | { AU1550_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 0 }, | ||
172 | { AU1550_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
173 | { AU1550_MAC1_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
174 | |||
175 | #elif defined(CONFIG_SOC_AU1200) | ||
176 | |||
177 | { AU1200_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
178 | { AU1200_SWT_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
179 | { AU1200_SD_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
180 | { AU1200_DDMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
181 | { AU1200_MAE_BE_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
182 | { AU1200_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
183 | { AU1200_MAE_FE_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
184 | { AU1200_PSC0_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
185 | { AU1200_PSC1_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
186 | { AU1200_AES_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
187 | { AU1200_CAMERA_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
188 | { AU1000_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
189 | { AU1000_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
190 | { AU1000_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
191 | { AU1000_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 }, | ||
192 | { AU1000_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
193 | { AU1000_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
194 | { AU1000_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
195 | { AU1000_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
196 | { AU1200_NAND_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
197 | { AU1200_USB_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
198 | { AU1200_LCD_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
199 | { AU1200_MAE_BOTH_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
200 | |||
201 | #else | ||
202 | #error "Error: Unknown Alchemy SOC" | ||
203 | #endif | ||
204 | }; | 91 | }; |
205 | 92 | ||
93 | struct au1xxx_irqmap au1500_irqmap[] __initdata = { | ||
94 | { AU1500_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
95 | { AU1500_PCI_INTA, IRQ_TYPE_LEVEL_LOW, 0 }, | ||
96 | { AU1500_PCI_INTB, IRQ_TYPE_LEVEL_LOW, 0 }, | ||
97 | { AU1500_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
98 | { AU1500_PCI_INTC, IRQ_TYPE_LEVEL_LOW, 0 }, | ||
99 | { AU1500_PCI_INTD, IRQ_TYPE_LEVEL_LOW, 0 }, | ||
100 | { AU1500_DMA_INT_BASE, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
101 | { AU1500_DMA_INT_BASE+1, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
102 | { AU1500_DMA_INT_BASE+2, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
103 | { AU1500_DMA_INT_BASE+3, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
104 | { AU1500_DMA_INT_BASE+4, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
105 | { AU1500_DMA_INT_BASE+5, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
106 | { AU1500_DMA_INT_BASE+6, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
107 | { AU1500_DMA_INT_BASE+7, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
108 | { AU1500_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
109 | { AU1500_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
110 | { AU1500_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
111 | { AU1500_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
112 | { AU1500_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
113 | { AU1500_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
114 | { AU1500_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
115 | { AU1500_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 }, | ||
116 | { AU1500_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 1 }, | ||
117 | { AU1500_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
118 | { AU1500_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 0 }, | ||
119 | { AU1500_ACSYNC_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
120 | { AU1500_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
121 | { AU1500_MAC1_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
122 | { AU1500_AC97C_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
123 | { -1, }, | ||
124 | }; | ||
206 | 125 | ||
207 | #ifdef CONFIG_PM | 126 | struct au1xxx_irqmap au1100_irqmap[] __initdata = { |
127 | { AU1100_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
128 | { AU1100_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
129 | { AU1100_SD_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
130 | { AU1100_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
131 | { AU1100_SSI0_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
132 | { AU1100_SSI1_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
133 | { AU1100_DMA_INT_BASE, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
134 | { AU1100_DMA_INT_BASE+1, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
135 | { AU1100_DMA_INT_BASE+2, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
136 | { AU1100_DMA_INT_BASE+3, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
137 | { AU1100_DMA_INT_BASE+4, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
138 | { AU1100_DMA_INT_BASE+5, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
139 | { AU1100_DMA_INT_BASE+6, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
140 | { AU1100_DMA_INT_BASE+7, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
141 | { AU1100_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
142 | { AU1100_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
143 | { AU1100_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
144 | { AU1100_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
145 | { AU1100_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
146 | { AU1100_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
147 | { AU1100_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
148 | { AU1100_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 }, | ||
149 | { AU1100_IRDA_TX_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
150 | { AU1100_IRDA_RX_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
151 | { AU1100_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 1 }, | ||
152 | { AU1100_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
153 | { AU1100_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 0 }, | ||
154 | { AU1100_ACSYNC_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
155 | { AU1100_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
156 | { AU1100_LCD_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
157 | { AU1100_AC97C_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
158 | { -1, }, | ||
159 | }; | ||
208 | 160 | ||
209 | /* | 161 | struct au1xxx_irqmap au1550_irqmap[] __initdata = { |
210 | * Save/restore the interrupt controller state. | 162 | { AU1550_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
211 | * Called from the save/restore core registers as part of the | 163 | { AU1550_PCI_INTA, IRQ_TYPE_LEVEL_LOW, 0 }, |
212 | * au_sleep function in power.c.....maybe I should just pm_register() | 164 | { AU1550_PCI_INTB, IRQ_TYPE_LEVEL_LOW, 0 }, |
213 | * them instead? | 165 | { AU1550_DDMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
214 | */ | 166 | { AU1550_CRYPTO_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
215 | static unsigned int sleep_intctl_config0[2]; | 167 | { AU1550_PCI_INTC, IRQ_TYPE_LEVEL_LOW, 0 }, |
216 | static unsigned int sleep_intctl_config1[2]; | 168 | { AU1550_PCI_INTD, IRQ_TYPE_LEVEL_LOW, 0 }, |
217 | static unsigned int sleep_intctl_config2[2]; | 169 | { AU1550_PCI_RST_INT, IRQ_TYPE_LEVEL_LOW, 0 }, |
218 | static unsigned int sleep_intctl_src[2]; | 170 | { AU1550_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
219 | static unsigned int sleep_intctl_assign[2]; | 171 | { AU1550_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
220 | static unsigned int sleep_intctl_wake[2]; | 172 | { AU1550_PSC0_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
221 | static unsigned int sleep_intctl_mask[2]; | 173 | { AU1550_PSC1_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
222 | 174 | { AU1550_PSC2_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | |
223 | void save_au1xxx_intctl(void) | 175 | { AU1550_PSC3_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
224 | { | 176 | { AU1550_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
225 | sleep_intctl_config0[0] = au_readl(IC0_CFG0RD); | 177 | { AU1550_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
226 | sleep_intctl_config1[0] = au_readl(IC0_CFG1RD); | 178 | { AU1550_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
227 | sleep_intctl_config2[0] = au_readl(IC0_CFG2RD); | 179 | { AU1550_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
228 | sleep_intctl_src[0] = au_readl(IC0_SRCRD); | 180 | { AU1550_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
229 | sleep_intctl_assign[0] = au_readl(IC0_ASSIGNRD); | 181 | { AU1550_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
230 | sleep_intctl_wake[0] = au_readl(IC0_WAKERD); | 182 | { AU1550_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
231 | sleep_intctl_mask[0] = au_readl(IC0_MASKRD); | 183 | { AU1550_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 }, |
232 | 184 | { AU1550_NAND_INT, IRQ_TYPE_EDGE_RISING, 0 }, | |
233 | sleep_intctl_config0[1] = au_readl(IC1_CFG0RD); | 185 | { AU1550_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 1 }, |
234 | sleep_intctl_config1[1] = au_readl(IC1_CFG1RD); | 186 | { AU1550_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
235 | sleep_intctl_config2[1] = au_readl(IC1_CFG2RD); | 187 | { AU1550_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 0 }, |
236 | sleep_intctl_src[1] = au_readl(IC1_SRCRD); | 188 | { AU1550_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
237 | sleep_intctl_assign[1] = au_readl(IC1_ASSIGNRD); | 189 | { AU1550_MAC1_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
238 | sleep_intctl_wake[1] = au_readl(IC1_WAKERD); | 190 | { -1, }, |
239 | sleep_intctl_mask[1] = au_readl(IC1_MASKRD); | 191 | }; |
240 | } | ||
241 | 192 | ||
242 | /* | 193 | struct au1xxx_irqmap au1200_irqmap[] __initdata = { |
243 | * For most restore operations, we clear the entire register and | 194 | { AU1200_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
244 | * then set the bits we found during the save. | 195 | { AU1200_SWT_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
245 | */ | 196 | { AU1200_SD_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
246 | void restore_au1xxx_intctl(void) | 197 | { AU1200_DDMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
247 | { | 198 | { AU1200_MAE_BE_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
248 | au_writel(0xffffffff, IC0_MASKCLR); au_sync(); | 199 | { AU1200_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
249 | 200 | { AU1200_MAE_FE_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | |
250 | au_writel(0xffffffff, IC0_CFG0CLR); au_sync(); | 201 | { AU1200_PSC0_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
251 | au_writel(sleep_intctl_config0[0], IC0_CFG0SET); au_sync(); | 202 | { AU1200_PSC1_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
252 | au_writel(0xffffffff, IC0_CFG1CLR); au_sync(); | 203 | { AU1200_AES_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
253 | au_writel(sleep_intctl_config1[0], IC0_CFG1SET); au_sync(); | 204 | { AU1200_CAMERA_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
254 | au_writel(0xffffffff, IC0_CFG2CLR); au_sync(); | 205 | { AU1200_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
255 | au_writel(sleep_intctl_config2[0], IC0_CFG2SET); au_sync(); | 206 | { AU1200_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
256 | au_writel(0xffffffff, IC0_SRCCLR); au_sync(); | 207 | { AU1200_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
257 | au_writel(sleep_intctl_src[0], IC0_SRCSET); au_sync(); | 208 | { AU1200_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
258 | au_writel(0xffffffff, IC0_ASSIGNCLR); au_sync(); | 209 | { AU1200_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
259 | au_writel(sleep_intctl_assign[0], IC0_ASSIGNSET); au_sync(); | 210 | { AU1200_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
260 | au_writel(0xffffffff, IC0_WAKECLR); au_sync(); | 211 | { AU1200_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
261 | au_writel(sleep_intctl_wake[0], IC0_WAKESET); au_sync(); | 212 | { AU1200_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 }, |
262 | au_writel(0xffffffff, IC0_RISINGCLR); au_sync(); | 213 | { AU1200_NAND_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
263 | au_writel(0xffffffff, IC0_FALLINGCLR); au_sync(); | 214 | { AU1200_USB_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
264 | au_writel(0x00000000, IC0_TESTBIT); au_sync(); | 215 | { AU1200_LCD_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
265 | 216 | { AU1200_MAE_BOTH_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | |
266 | au_writel(0xffffffff, IC1_MASKCLR); au_sync(); | 217 | { -1, }, |
267 | 218 | }; | |
268 | au_writel(0xffffffff, IC1_CFG0CLR); au_sync(); | ||
269 | au_writel(sleep_intctl_config0[1], IC1_CFG0SET); au_sync(); | ||
270 | au_writel(0xffffffff, IC1_CFG1CLR); au_sync(); | ||
271 | au_writel(sleep_intctl_config1[1], IC1_CFG1SET); au_sync(); | ||
272 | au_writel(0xffffffff, IC1_CFG2CLR); au_sync(); | ||
273 | au_writel(sleep_intctl_config2[1], IC1_CFG2SET); au_sync(); | ||
274 | au_writel(0xffffffff, IC1_SRCCLR); au_sync(); | ||
275 | au_writel(sleep_intctl_src[1], IC1_SRCSET); au_sync(); | ||
276 | au_writel(0xffffffff, IC1_ASSIGNCLR); au_sync(); | ||
277 | au_writel(sleep_intctl_assign[1], IC1_ASSIGNSET); au_sync(); | ||
278 | au_writel(0xffffffff, IC1_WAKECLR); au_sync(); | ||
279 | au_writel(sleep_intctl_wake[1], IC1_WAKESET); au_sync(); | ||
280 | au_writel(0xffffffff, IC1_RISINGCLR); au_sync(); | ||
281 | au_writel(0xffffffff, IC1_FALLINGCLR); au_sync(); | ||
282 | au_writel(0x00000000, IC1_TESTBIT); au_sync(); | ||
283 | |||
284 | au_writel(sleep_intctl_mask[1], IC1_MASKSET); au_sync(); | ||
285 | |||
286 | au_writel(sleep_intctl_mask[0], IC0_MASKSET); au_sync(); | ||
287 | } | ||
288 | #endif /* CONFIG_PM */ | ||
289 | 219 | ||
290 | 220 | ||
291 | static void au1x_ic0_unmask(unsigned int irq_nr) | 221 | static void au1x_ic0_unmask(unsigned int irq_nr) |
@@ -306,7 +236,7 @@ static void au1x_ic1_unmask(unsigned int irq_nr) | |||
306 | * nowhere in the current kernel sources is it disabled. --mlau | 236 | * nowhere in the current kernel sources is it disabled. --mlau |
307 | */ | 237 | */ |
308 | #if defined(CONFIG_MIPS_PB1000) | 238 | #if defined(CONFIG_MIPS_PB1000) |
309 | if (irq_nr == AU1000_GPIO_15) | 239 | if (irq_nr == AU1000_GPIO15_INT) |
310 | au_writel(0x4000, PB1000_MDR); /* enable int */ | 240 | au_writel(0x4000, PB1000_MDR); /* enable int */ |
311 | #endif | 241 | #endif |
312 | au_sync(); | 242 | au_sync(); |
@@ -378,11 +308,13 @@ static void au1x_ic1_maskack(unsigned int irq_nr) | |||
378 | 308 | ||
379 | static int au1x_ic1_setwake(unsigned int irq, unsigned int on) | 309 | static int au1x_ic1_setwake(unsigned int irq, unsigned int on) |
380 | { | 310 | { |
381 | unsigned int bit = irq - AU1000_INTC1_INT_BASE; | 311 | int bit = irq - AU1000_INTC1_INT_BASE; |
382 | unsigned long wakemsk, flags; | 312 | unsigned long wakemsk, flags; |
383 | 313 | ||
384 | /* only GPIO 0-7 can act as wakeup source: */ | 314 | /* only GPIO 0-7 can act as wakeup source. Fortunately these |
385 | if ((irq < AU1000_GPIO_0) || (irq > AU1000_GPIO_7)) | 315 | * are wired up identically on all supported variants. |
316 | */ | ||
317 | if ((bit < 0) || (bit > 7)) | ||
386 | return -EINVAL; | 318 | return -EINVAL; |
387 | 319 | ||
388 | local_irq_save(flags); | 320 | local_irq_save(flags); |
@@ -504,11 +436,11 @@ static int au1x_ic_settype(unsigned int irq, unsigned int flow_type) | |||
504 | asmlinkage void plat_irq_dispatch(void) | 436 | asmlinkage void plat_irq_dispatch(void) |
505 | { | 437 | { |
506 | unsigned int pending = read_c0_status() & read_c0_cause(); | 438 | unsigned int pending = read_c0_status() & read_c0_cause(); |
507 | unsigned long s, off, bit; | 439 | unsigned long s, off; |
508 | 440 | ||
509 | if (pending & CAUSEF_IP7) { | 441 | if (pending & CAUSEF_IP7) { |
510 | do_IRQ(MIPS_CPU_IRQ_BASE + 7); | 442 | off = MIPS_CPU_IRQ_BASE + 7; |
511 | return; | 443 | goto handle; |
512 | } else if (pending & CAUSEF_IP2) { | 444 | } else if (pending & CAUSEF_IP2) { |
513 | s = IC0_REQ0INT; | 445 | s = IC0_REQ0INT; |
514 | off = AU1000_INTC0_INT_BASE; | 446 | off = AU1000_INTC0_INT_BASE; |
@@ -524,58 +456,20 @@ asmlinkage void plat_irq_dispatch(void) | |||
524 | } else | 456 | } else |
525 | goto spurious; | 457 | goto spurious; |
526 | 458 | ||
527 | bit = 0; | ||
528 | s = au_readl(s); | 459 | s = au_readl(s); |
529 | if (unlikely(!s)) { | 460 | if (unlikely(!s)) { |
530 | spurious: | 461 | spurious: |
531 | spurious_interrupt(); | 462 | spurious_interrupt(); |
532 | return; | 463 | return; |
533 | } | 464 | } |
534 | #ifdef AU1000_USB_DEV_REQ_INT | 465 | off += __ffs(s); |
535 | /* | 466 | handle: |
536 | * Because of the tight timing of SETUP token to reply | 467 | do_IRQ(off); |
537 | * transactions, the USB devices-side packet complete | ||
538 | * interrupt needs the highest priority. | ||
539 | */ | ||
540 | bit = 1 << (AU1000_USB_DEV_REQ_INT - AU1000_INTC0_INT_BASE); | ||
541 | if ((pending & CAUSEF_IP2) && (s & bit)) { | ||
542 | do_IRQ(AU1000_USB_DEV_REQ_INT); | ||
543 | return; | ||
544 | } | ||
545 | #endif | ||
546 | do_IRQ(__ffs(s) + off); | ||
547 | } | 468 | } |
548 | 469 | ||
549 | /* setup edge/level and assign request 0/1 */ | 470 | static void __init au1000_init_irq(struct au1xxx_irqmap *map) |
550 | void __init au1xxx_setup_irqmap(struct au1xxx_irqmap *map, int count) | ||
551 | { | 471 | { |
552 | unsigned int bit, irq_nr; | 472 | unsigned int bit, irq_nr; |
553 | |||
554 | while (count--) { | ||
555 | irq_nr = map[count].im_irq; | ||
556 | |||
557 | if (((irq_nr < AU1000_INTC0_INT_BASE) || | ||
558 | (irq_nr >= AU1000_INTC0_INT_BASE + 32)) && | ||
559 | ((irq_nr < AU1000_INTC1_INT_BASE) || | ||
560 | (irq_nr >= AU1000_INTC1_INT_BASE + 32))) | ||
561 | continue; | ||
562 | |||
563 | if (irq_nr >= AU1000_INTC1_INT_BASE) { | ||
564 | bit = irq_nr - AU1000_INTC1_INT_BASE; | ||
565 | if (map[count].im_request) | ||
566 | au_writel(1 << bit, IC1_ASSIGNCLR); | ||
567 | } else { | ||
568 | bit = irq_nr - AU1000_INTC0_INT_BASE; | ||
569 | if (map[count].im_request) | ||
570 | au_writel(1 << bit, IC0_ASSIGNCLR); | ||
571 | } | ||
572 | |||
573 | au1x_ic_settype(irq_nr, map[count].im_type); | ||
574 | } | ||
575 | } | ||
576 | |||
577 | void __init arch_init_irq(void) | ||
578 | { | ||
579 | int i; | 473 | int i; |
580 | 474 | ||
581 | /* | 475 | /* |
@@ -585,7 +479,7 @@ void __init arch_init_irq(void) | |||
585 | au_writel(0xffffffff, IC0_CFG1CLR); | 479 | au_writel(0xffffffff, IC0_CFG1CLR); |
586 | au_writel(0xffffffff, IC0_CFG2CLR); | 480 | au_writel(0xffffffff, IC0_CFG2CLR); |
587 | au_writel(0xffffffff, IC0_MASKCLR); | 481 | au_writel(0xffffffff, IC0_MASKCLR); |
588 | au_writel(0xffffffff, IC0_ASSIGNSET); | 482 | au_writel(0xffffffff, IC0_ASSIGNCLR); |
589 | au_writel(0xffffffff, IC0_WAKECLR); | 483 | au_writel(0xffffffff, IC0_WAKECLR); |
590 | au_writel(0xffffffff, IC0_SRCSET); | 484 | au_writel(0xffffffff, IC0_SRCSET); |
591 | au_writel(0xffffffff, IC0_FALLINGCLR); | 485 | au_writel(0xffffffff, IC0_FALLINGCLR); |
@@ -596,7 +490,7 @@ void __init arch_init_irq(void) | |||
596 | au_writel(0xffffffff, IC1_CFG1CLR); | 490 | au_writel(0xffffffff, IC1_CFG1CLR); |
597 | au_writel(0xffffffff, IC1_CFG2CLR); | 491 | au_writel(0xffffffff, IC1_CFG2CLR); |
598 | au_writel(0xffffffff, IC1_MASKCLR); | 492 | au_writel(0xffffffff, IC1_MASKCLR); |
599 | au_writel(0xffffffff, IC1_ASSIGNSET); | 493 | au_writel(0xffffffff, IC1_ASSIGNCLR); |
600 | au_writel(0xffffffff, IC1_WAKECLR); | 494 | au_writel(0xffffffff, IC1_WAKECLR); |
601 | au_writel(0xffffffff, IC1_SRCSET); | 495 | au_writel(0xffffffff, IC1_SRCSET); |
602 | au_writel(0xffffffff, IC1_FALLINGCLR); | 496 | au_writel(0xffffffff, IC1_FALLINGCLR); |
@@ -619,11 +513,131 @@ void __init arch_init_irq(void) | |||
619 | /* | 513 | /* |
620 | * Initialize IC0, which is fixed per processor. | 514 | * Initialize IC0, which is fixed per processor. |
621 | */ | 515 | */ |
622 | au1xxx_setup_irqmap(au1xxx_ic0_map, ARRAY_SIZE(au1xxx_ic0_map)); | 516 | while (map->im_irq != -1) { |
517 | irq_nr = map->im_irq; | ||
623 | 518 | ||
624 | /* Boards can register additional (GPIO-based) IRQs. | 519 | if (irq_nr >= AU1000_INTC1_INT_BASE) { |
625 | */ | 520 | bit = irq_nr - AU1000_INTC1_INT_BASE; |
626 | board_init_irq(); | 521 | if (map->im_request) |
522 | au_writel(1 << bit, IC1_ASSIGNSET); | ||
523 | } else { | ||
524 | bit = irq_nr - AU1000_INTC0_INT_BASE; | ||
525 | if (map->im_request) | ||
526 | au_writel(1 << bit, IC0_ASSIGNSET); | ||
527 | } | ||
528 | |||
529 | au1x_ic_settype(irq_nr, map->im_type); | ||
530 | ++map; | ||
531 | } | ||
627 | 532 | ||
628 | set_c0_status(IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3); | 533 | set_c0_status(IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3); |
629 | } | 534 | } |
535 | |||
536 | void __init arch_init_irq(void) | ||
537 | { | ||
538 | switch (alchemy_get_cputype()) { | ||
539 | case ALCHEMY_CPU_AU1000: | ||
540 | au1000_init_irq(au1000_irqmap); | ||
541 | break; | ||
542 | case ALCHEMY_CPU_AU1500: | ||
543 | au1000_init_irq(au1500_irqmap); | ||
544 | break; | ||
545 | case ALCHEMY_CPU_AU1100: | ||
546 | au1000_init_irq(au1100_irqmap); | ||
547 | break; | ||
548 | case ALCHEMY_CPU_AU1550: | ||
549 | au1000_init_irq(au1550_irqmap); | ||
550 | break; | ||
551 | case ALCHEMY_CPU_AU1200: | ||
552 | au1000_init_irq(au1200_irqmap); | ||
553 | break; | ||
554 | } | ||
555 | } | ||
556 | |||
557 | struct alchemy_ic_sysdev { | ||
558 | struct sys_device sysdev; | ||
559 | void __iomem *base; | ||
560 | unsigned long pmdata[7]; | ||
561 | }; | ||
562 | |||
563 | static int alchemy_ic_suspend(struct sys_device *dev, pm_message_t state) | ||
564 | { | ||
565 | struct alchemy_ic_sysdev *icdev = | ||
566 | container_of(dev, struct alchemy_ic_sysdev, sysdev); | ||
567 | |||
568 | icdev->pmdata[0] = __raw_readl(icdev->base + IC_CFG0RD); | ||
569 | icdev->pmdata[1] = __raw_readl(icdev->base + IC_CFG1RD); | ||
570 | icdev->pmdata[2] = __raw_readl(icdev->base + IC_CFG2RD); | ||
571 | icdev->pmdata[3] = __raw_readl(icdev->base + IC_SRCRD); | ||
572 | icdev->pmdata[4] = __raw_readl(icdev->base + IC_ASSIGNRD); | ||
573 | icdev->pmdata[5] = __raw_readl(icdev->base + IC_WAKERD); | ||
574 | icdev->pmdata[6] = __raw_readl(icdev->base + IC_MASKRD); | ||
575 | |||
576 | return 0; | ||
577 | } | ||
578 | |||
579 | static int alchemy_ic_resume(struct sys_device *dev) | ||
580 | { | ||
581 | struct alchemy_ic_sysdev *icdev = | ||
582 | container_of(dev, struct alchemy_ic_sysdev, sysdev); | ||
583 | |||
584 | __raw_writel(0xffffffff, icdev->base + IC_MASKCLR); | ||
585 | __raw_writel(0xffffffff, icdev->base + IC_CFG0CLR); | ||
586 | __raw_writel(0xffffffff, icdev->base + IC_CFG1CLR); | ||
587 | __raw_writel(0xffffffff, icdev->base + IC_CFG2CLR); | ||
588 | __raw_writel(0xffffffff, icdev->base + IC_SRCCLR); | ||
589 | __raw_writel(0xffffffff, icdev->base + IC_ASSIGNCLR); | ||
590 | __raw_writel(0xffffffff, icdev->base + IC_WAKECLR); | ||
591 | __raw_writel(0xffffffff, icdev->base + IC_RISINGCLR); | ||
592 | __raw_writel(0xffffffff, icdev->base + IC_FALLINGCLR); | ||
593 | __raw_writel(0x00000000, icdev->base + IC_TESTBIT); | ||
594 | wmb(); | ||
595 | __raw_writel(icdev->pmdata[0], icdev->base + IC_CFG0SET); | ||
596 | __raw_writel(icdev->pmdata[1], icdev->base + IC_CFG1SET); | ||
597 | __raw_writel(icdev->pmdata[2], icdev->base + IC_CFG2SET); | ||
598 | __raw_writel(icdev->pmdata[3], icdev->base + IC_SRCSET); | ||
599 | __raw_writel(icdev->pmdata[4], icdev->base + IC_ASSIGNSET); | ||
600 | __raw_writel(icdev->pmdata[5], icdev->base + IC_WAKESET); | ||
601 | wmb(); | ||
602 | |||
603 | __raw_writel(icdev->pmdata[6], icdev->base + IC_MASKSET); | ||
604 | wmb(); | ||
605 | |||
606 | return 0; | ||
607 | } | ||
608 | |||
609 | static struct sysdev_class alchemy_ic_sysdev_class = { | ||
610 | .name = "ic", | ||
611 | .suspend = alchemy_ic_suspend, | ||
612 | .resume = alchemy_ic_resume, | ||
613 | }; | ||
614 | |||
615 | static int __init alchemy_ic_sysdev_init(void) | ||
616 | { | ||
617 | struct alchemy_ic_sysdev *icdev; | ||
618 | unsigned long icbase[2] = { IC0_PHYS_ADDR, IC1_PHYS_ADDR }; | ||
619 | int err, i; | ||
620 | |||
621 | err = sysdev_class_register(&alchemy_ic_sysdev_class); | ||
622 | if (err) | ||
623 | return err; | ||
624 | |||
625 | for (i = 0; i < 2; i++) { | ||
626 | icdev = kzalloc(sizeof(struct alchemy_ic_sysdev), GFP_KERNEL); | ||
627 | if (!icdev) | ||
628 | return -ENOMEM; | ||
629 | |||
630 | icdev->base = ioremap(icbase[i], 0x1000); | ||
631 | |||
632 | icdev->sysdev.id = i; | ||
633 | icdev->sysdev.cls = &alchemy_ic_sysdev_class; | ||
634 | err = sysdev_register(&icdev->sysdev); | ||
635 | if (err) { | ||
636 | kfree(icdev); | ||
637 | return err; | ||
638 | } | ||
639 | } | ||
640 | |||
641 | return 0; | ||
642 | } | ||
643 | device_initcall(alchemy_ic_sysdev_init); | ||