1 /* 2 * Copyright 2001, 2007-2008 MontaVista Software Inc. 3 * Author: MontaVista Software, Inc. <source@mvista.com> 4 * 5 * Copyright (C) 2007 Ralf Baechle (ralf@linux-mips.org) 6 * 7 * This program is free software; you can redistribute it and/or modify it 8 * under the terms of the GNU General Public License as published by the 9 * Free Software Foundation; either version 2 of the License, or (at your 10 * option) any later version. 11 * 12 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 13 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 14 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 15 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 16 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 17 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 18 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 19 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 20 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 21 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 22 * 23 * You should have received a copy of the GNU General Public License along 24 * with this program; if not, write to the Free Software Foundation, Inc., 25 * 675 Mass Ave, Cambridge, MA 02139, USA. 26 */ 27 28 #include <linux/bitops.h> 29 #include <linux/init.h> 30 #include <linux/interrupt.h> 31 #include <linux/irq.h> 32 33 #include <asm/irq_cpu.h> 34 #include <asm/mipsregs.h> 35 #include <asm/mach-au1x00/au1000.h> 36 #ifdef CONFIG_MIPS_PB1000 37 #include <asm/mach-pb1x00/pb1000.h> 38 #endif 39 40 static int au1x_ic_settype(unsigned int irq, unsigned int flow_type); 41 42 /* per-processor fixed function irqs */ 43 struct au1xxx_irqmap au1xxx_ic0_map[] __initdata = { 44 45 #if defined(CONFIG_SOC_AU1000) 46 { AU1000_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, 47 { AU1000_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, 48 { AU1000_UART2_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, 49 { AU1000_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, 50 { AU1000_SSI0_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, 51 { AU1000_SSI1_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, 52 { AU1000_DMA_INT_BASE, IRQ_TYPE_LEVEL_HIGH, 0 }, 53 { AU1000_DMA_INT_BASE+1, IRQ_TYPE_LEVEL_HIGH, 0 }, 54 { AU1000_DMA_INT_BASE+2, IRQ_TYPE_LEVEL_HIGH, 0 }, 55 { AU1000_DMA_INT_BASE+3, IRQ_TYPE_LEVEL_HIGH, 0 }, 56 { AU1000_DMA_INT_BASE+4, IRQ_TYPE_LEVEL_HIGH, 0 }, 57 { AU1000_DMA_INT_BASE+5, IRQ_TYPE_LEVEL_HIGH, 0 }, 58 { AU1000_DMA_INT_BASE+6, IRQ_TYPE_LEVEL_HIGH, 0 }, 59 { AU1000_DMA_INT_BASE+7, IRQ_TYPE_LEVEL_HIGH, 0 }, 60 { AU1000_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 }, 61 { AU1000_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, 62 { AU1000_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, 63 { AU1000_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 }, 64 { AU1000_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 }, 65 { AU1000_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, 66 { AU1000_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, 67 { AU1000_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 }, 68 { AU1000_IRDA_TX_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, 69 { AU1000_IRDA_RX_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, 70 { AU1000_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, 71 { AU1000_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 0 }, 72 { AU1000_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 0 }, 73 { AU1000_ACSYNC_INT, IRQ_TYPE_EDGE_RISING, 0 }, 74 { AU1000_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, 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 }, 138 { AU1000_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 0 }, 139 { AU1000_ACSYNC_INT, IRQ_TYPE_EDGE_RISING, 0 }, 140 { AU1100_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, 141 { AU1100_LCD_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, 142 { AU1000_AC97C_INT, IRQ_TYPE_EDGE_RISING, 0 }, 143 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 }; 205 206 207 #ifdef CONFIG_PM 208 209 /* 210 * Save/restore the interrupt controller state. 211 * Called from the save/restore core registers as part of the 212 * au_sleep function in power.c.....maybe I should just pm_register() 213 * them instead? 214 */ 215 static unsigned int sleep_intctl_config0[2]; 216 static unsigned int sleep_intctl_config1[2]; 217 static unsigned int sleep_intctl_config2[2]; 218 static unsigned int sleep_intctl_src[2]; 219 static unsigned int sleep_intctl_assign[2]; 220 static unsigned int sleep_intctl_wake[2]; 221 static unsigned int sleep_intctl_mask[2]; 222 223 void save_au1xxx_intctl(void) 224 { 225 sleep_intctl_config0[0] = au_readl(IC0_CFG0RD); 226 sleep_intctl_config1[0] = au_readl(IC0_CFG1RD); 227 sleep_intctl_config2[0] = au_readl(IC0_CFG2RD); 228 sleep_intctl_src[0] = au_readl(IC0_SRCRD); 229 sleep_intctl_assign[0] = au_readl(IC0_ASSIGNRD); 230 sleep_intctl_wake[0] = au_readl(IC0_WAKERD); 231 sleep_intctl_mask[0] = au_readl(IC0_MASKRD); 232 233 sleep_intctl_config0[1] = au_readl(IC1_CFG0RD); 234 sleep_intctl_config1[1] = au_readl(IC1_CFG1RD); 235 sleep_intctl_config2[1] = au_readl(IC1_CFG2RD); 236 sleep_intctl_src[1] = au_readl(IC1_SRCRD); 237 sleep_intctl_assign[1] = au_readl(IC1_ASSIGNRD); 238 sleep_intctl_wake[1] = au_readl(IC1_WAKERD); 239 sleep_intctl_mask[1] = au_readl(IC1_MASKRD); 240 } 241 242 /* 243 * For most restore operations, we clear the entire register and 244 * then set the bits we found during the save. 245 */ 246 void restore_au1xxx_intctl(void) 247 { 248 au_writel(0xffffffff, IC0_MASKCLR); au_sync(); 249 250 au_writel(0xffffffff, IC0_CFG0CLR); au_sync(); 251 au_writel(sleep_intctl_config0[0], IC0_CFG0SET); au_sync(); 252 au_writel(0xffffffff, IC0_CFG1CLR); au_sync(); 253 au_writel(sleep_intctl_config1[0], IC0_CFG1SET); au_sync(); 254 au_writel(0xffffffff, IC0_CFG2CLR); au_sync(); 255 au_writel(sleep_intctl_config2[0], IC0_CFG2SET); au_sync(); 256 au_writel(0xffffffff, IC0_SRCCLR); au_sync(); 257 au_writel(sleep_intctl_src[0], IC0_SRCSET); au_sync(); 258 au_writel(0xffffffff, IC0_ASSIGNCLR); au_sync(); 259 au_writel(sleep_intctl_assign[0], IC0_ASSIGNSET); au_sync(); 260 au_writel(0xffffffff, IC0_WAKECLR); au_sync(); 261 au_writel(sleep_intctl_wake[0], IC0_WAKESET); au_sync(); 262 au_writel(0xffffffff, IC0_RISINGCLR); au_sync(); 263 au_writel(0xffffffff, IC0_FALLINGCLR); au_sync(); 264 au_writel(0x00000000, IC0_TESTBIT); au_sync(); 265 266 au_writel(0xffffffff, IC1_MASKCLR); au_sync(); 267 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 290 291 static void au1x_ic0_unmask(unsigned int irq_nr) 292 { 293 unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE; 294 au_writel(1 << bit, IC0_MASKSET); 295 au_writel(1 << bit, IC0_WAKESET); 296 au_sync(); 297 } 298 299 static void au1x_ic1_unmask(unsigned int irq_nr) 300 { 301 unsigned int bit = irq_nr - AU1000_INTC1_INT_BASE; 302 au_writel(1 << bit, IC1_MASKSET); 303 au_writel(1 << bit, IC1_WAKESET); 304 305 /* very hacky. does the pb1000 cpld auto-disable this int? 306 * nowhere in the current kernel sources is it disabled. --mlau 307 */ 308 #if defined(CONFIG_MIPS_PB1000) 309 if (irq_nr == AU1000_GPIO_15) 310 au_writel(0x4000, PB1000_MDR); /* enable int */ 311 #endif 312 au_sync(); 313 } 314 315 static void au1x_ic0_mask(unsigned int irq_nr) 316 { 317 unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE; 318 au_writel(1 << bit, IC0_MASKCLR); 319 au_writel(1 << bit, IC0_WAKECLR); 320 au_sync(); 321 } 322 323 static void au1x_ic1_mask(unsigned int irq_nr) 324 { 325 unsigned int bit = irq_nr - AU1000_INTC1_INT_BASE; 326 au_writel(1 << bit, IC1_MASKCLR); 327 au_writel(1 << bit, IC1_WAKECLR); 328 au_sync(); 329 } 330 331 static void au1x_ic0_ack(unsigned int irq_nr) 332 { 333 unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE; 334 335 /* 336 * This may assume that we don't get interrupts from 337 * both edges at once, or if we do, that we don't care. 338 */ 339 au_writel(1 << bit, IC0_FALLINGCLR); 340 au_writel(1 << bit, IC0_RISINGCLR); 341 au_sync(); 342 } 343 344 static void au1x_ic1_ack(unsigned int irq_nr) 345 { 346 unsigned int bit = irq_nr - AU1000_INTC1_INT_BASE; 347 348 /* 349 * This may assume that we don't get interrupts from 350 * both edges at once, or if we do, that we don't care. 351 */ 352 au_writel(1 << bit, IC1_FALLINGCLR); 353 au_writel(1 << bit, IC1_RISINGCLR); 354 au_sync(); 355 } 356 357 static void au1x_ic0_maskack(unsigned int irq_nr) 358 { 359 unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE; 360 361 au_writel(1 << bit, IC0_WAKECLR); 362 au_writel(1 << bit, IC0_MASKCLR); 363 au_writel(1 << bit, IC0_RISINGCLR); 364 au_writel(1 << bit, IC0_FALLINGCLR); 365 au_sync(); 366 } 367 368 static void au1x_ic1_maskack(unsigned int irq_nr) 369 { 370 unsigned int bit = irq_nr - AU1000_INTC1_INT_BASE; 371 372 au_writel(1 << bit, IC1_WAKECLR); 373 au_writel(1 << bit, IC1_MASKCLR); 374 au_writel(1 << bit, IC1_RISINGCLR); 375 au_writel(1 << bit, IC1_FALLINGCLR); 376 au_sync(); 377 } 378 379 static int au1x_ic1_setwake(unsigned int irq, unsigned int on) 380 { 381 unsigned int bit = irq - AU1000_INTC1_INT_BASE; 382 unsigned long wakemsk, flags; 383 384 /* only GPIO 0-7 can act as wakeup source: */ 385 if ((irq < AU1000_GPIO_0) || (irq > AU1000_GPIO_7)) 386 return -EINVAL; 387 388 local_irq_save(flags); 389 wakemsk = au_readl(SYS_WAKEMSK); 390 if (on) 391 wakemsk |= 1 << bit; 392 else 393 wakemsk &= ~(1 << bit); 394 au_writel(wakemsk, SYS_WAKEMSK); 395 au_sync(); 396 local_irq_restore(flags); 397 398 return 0; 399 } 400 401 /* 402 * irq_chips for both ICs; this way the mask handlers can be 403 * as short as possible. 404 */ 405 static struct irq_chip au1x_ic0_chip = { 406 .name = "Alchemy-IC0", 407 .ack = au1x_ic0_ack, 408 .mask = au1x_ic0_mask, 409 .mask_ack = au1x_ic0_maskack, 410 .unmask = au1x_ic0_unmask, 411 .set_type = au1x_ic_settype, 412 }; 413 414 static struct irq_chip au1x_ic1_chip = { 415 .name = "Alchemy-IC1", 416 .ack = au1x_ic1_ack, 417 .mask = au1x_ic1_mask, 418 .mask_ack = au1x_ic1_maskack, 419 .unmask = au1x_ic1_unmask, 420 .set_type = au1x_ic_settype, 421 .set_wake = au1x_ic1_setwake, 422 }; 423 424 static int au1x_ic_settype(unsigned int irq, unsigned int flow_type) 425 { 426 struct irq_chip *chip; 427 unsigned long icr[6]; 428 unsigned int bit, ic; 429 int ret; 430 431 if (irq >= AU1000_INTC1_INT_BASE) { 432 bit = irq - AU1000_INTC1_INT_BASE; 433 chip = &au1x_ic1_chip; 434 ic = 1; 435 } else { 436 bit = irq - AU1000_INTC0_INT_BASE; 437 chip = &au1x_ic0_chip; 438 ic = 0; 439 } 440 441 if (bit > 31) 442 return -EINVAL; 443 444 icr[0] = ic ? IC1_CFG0SET : IC0_CFG0SET; 445 icr[1] = ic ? IC1_CFG1SET : IC0_CFG1SET; 446 icr[2] = ic ? IC1_CFG2SET : IC0_CFG2SET; 447 icr[3] = ic ? IC1_CFG0CLR : IC0_CFG0CLR; 448 icr[4] = ic ? IC1_CFG1CLR : IC0_CFG1CLR; 449 icr[5] = ic ? IC1_CFG2CLR : IC0_CFG2CLR; 450 451 ret = 0; 452 453 switch (flow_type) { /* cfgregs 2:1:0 */ 454 case IRQ_TYPE_EDGE_RISING: /* 0:0:1 */ 455 au_writel(1 << bit, icr[5]); 456 au_writel(1 << bit, icr[4]); 457 au_writel(1 << bit, icr[0]); 458 set_irq_chip_and_handler_name(irq, chip, 459 handle_edge_irq, "riseedge"); 460 break; 461 case IRQ_TYPE_EDGE_FALLING: /* 0:1:0 */ 462 au_writel(1 << bit, icr[5]); 463 au_writel(1 << bit, icr[1]); 464 au_writel(1 << bit, icr[3]); 465 set_irq_chip_and_handler_name(irq, chip, 466 handle_edge_irq, "falledge"); 467 break; 468 case IRQ_TYPE_EDGE_BOTH: /* 0:1:1 */ 469 au_writel(1 << bit, icr[5]); 470 au_writel(1 << bit, icr[1]); 471 au_writel(1 << bit, icr[0]); 472 set_irq_chip_and_handler_name(irq, chip, 473 handle_edge_irq, "bothedge"); 474 break; 475 case IRQ_TYPE_LEVEL_HIGH: /* 1:0:1 */ 476 au_writel(1 << bit, icr[2]); 477 au_writel(1 << bit, icr[4]); 478 au_writel(1 << bit, icr[0]); 479 set_irq_chip_and_handler_name(irq, chip, 480 handle_level_irq, "hilevel"); 481 break; 482 case IRQ_TYPE_LEVEL_LOW: /* 1:1:0 */ 483 au_writel(1 << bit, icr[2]); 484 au_writel(1 << bit, icr[1]); 485 au_writel(1 << bit, icr[3]); 486 set_irq_chip_and_handler_name(irq, chip, 487 handle_level_irq, "lowlevel"); 488 break; 489 case IRQ_TYPE_NONE: /* 0:0:0 */ 490 au_writel(1 << bit, icr[5]); 491 au_writel(1 << bit, icr[4]); 492 au_writel(1 << bit, icr[3]); 493 /* set at least chip so we can call set_irq_type() on it */ 494 set_irq_chip(irq, chip); 495 break; 496 default: 497 ret = -EINVAL; 498 } 499 au_sync(); 500 501 return ret; 502 } 503 504 asmlinkage void plat_irq_dispatch(void) 505 { 506 unsigned int pending = read_c0_status() & read_c0_cause(); 507 unsigned long s, off, bit; 508 509 if (pending & CAUSEF_IP7) { 510 do_IRQ(MIPS_CPU_IRQ_BASE + 7); 511 return; 512 } else if (pending & CAUSEF_IP2) { 513 s = IC0_REQ0INT; 514 off = AU1000_INTC0_INT_BASE; 515 } else if (pending & CAUSEF_IP3) { 516 s = IC0_REQ1INT; 517 off = AU1000_INTC0_INT_BASE; 518 } else if (pending & CAUSEF_IP4) { 519 s = IC1_REQ0INT; 520 off = AU1000_INTC1_INT_BASE; 521 } else if (pending & CAUSEF_IP5) { 522 s = IC1_REQ1INT; 523 off = AU1000_INTC1_INT_BASE; 524 } else 525 goto spurious; 526 527 bit = 0; 528 s = au_readl(s); 529 if (unlikely(!s)) { 530 spurious: 531 spurious_interrupt(); 532 return; 533 } 534 #ifdef AU1000_USB_DEV_REQ_INT 535 /* 536 * Because of the tight timing of SETUP token to reply 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 } 548 549 /* setup edge/level and assign request 0/1 */ 550 void __init au1xxx_setup_irqmap(struct au1xxx_irqmap *map, int count) 551 { 552 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; 580 581 /* 582 * Initialize interrupt controllers to a safe state. 583 */ 584 au_writel(0xffffffff, IC0_CFG0CLR); 585 au_writel(0xffffffff, IC0_CFG1CLR); 586 au_writel(0xffffffff, IC0_CFG2CLR); 587 au_writel(0xffffffff, IC0_MASKCLR); 588 au_writel(0xffffffff, IC0_ASSIGNSET); 589 au_writel(0xffffffff, IC0_WAKECLR); 590 au_writel(0xffffffff, IC0_SRCSET); 591 au_writel(0xffffffff, IC0_FALLINGCLR); 592 au_writel(0xffffffff, IC0_RISINGCLR); 593 au_writel(0x00000000, IC0_TESTBIT); 594 595 au_writel(0xffffffff, IC1_CFG0CLR); 596 au_writel(0xffffffff, IC1_CFG1CLR); 597 au_writel(0xffffffff, IC1_CFG2CLR); 598 au_writel(0xffffffff, IC1_MASKCLR); 599 au_writel(0xffffffff, IC1_ASSIGNSET); 600 au_writel(0xffffffff, IC1_WAKECLR); 601 au_writel(0xffffffff, IC1_SRCSET); 602 au_writel(0xffffffff, IC1_FALLINGCLR); 603 au_writel(0xffffffff, IC1_RISINGCLR); 604 au_writel(0x00000000, IC1_TESTBIT); 605 606 mips_cpu_irq_init(); 607 608 /* register all 64 possible IC0+IC1 irq sources as type "none". 609 * Use set_irq_type() to set edge/level behaviour at runtime. 610 */ 611 for (i = AU1000_INTC0_INT_BASE; 612 (i < AU1000_INTC0_INT_BASE + 32); i++) 613 au1x_ic_settype(i, IRQ_TYPE_NONE); 614 615 for (i = AU1000_INTC1_INT_BASE; 616 (i < AU1000_INTC1_INT_BASE + 32); i++) 617 au1x_ic_settype(i, IRQ_TYPE_NONE); 618 619 /* 620 * Initialize IC0, which is fixed per processor. 621 */ 622 au1xxx_setup_irqmap(au1xxx_ic0_map, ARRAY_SIZE(au1xxx_ic0_map)); 623 624 /* Boards can register additional (GPIO-based) IRQs. 625 */ 626 board_init_irq(); 627 628 set_c0_status(IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3); 629 } 630