1/* 2 * arch/arm/mach-lpc32xx/irq.c 3 * 4 * Author: Kevin Wells <kevin.wells@nxp.com> 5 * 6 * Copyright (C) 2010 NXP Semiconductors 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 */ 18 19#include <linux/kernel.h> 20#include <linux/types.h> 21#include <linux/interrupt.h> 22#include <linux/irq.h> 23#include <linux/err.h> 24#include <linux/io.h> 25 26#include <mach/irqs.h> 27#include <mach/hardware.h> 28#include <mach/platform.h> 29#include "common.h" 30 31/* 32 * Default value representing the Activation polarity of all internal 33 * interrupt sources 34 */ 35#define MIC_APR_DEFAULT 0x3FF0EFE0 36#define SIC1_APR_DEFAULT 0xFBD27186 37#define SIC2_APR_DEFAULT 0x801810C0 38 39/* 40 * Default value representing the Activation Type of all internal 41 * interrupt sources. All are level sensitive. 42 */ 43#define MIC_ATR_DEFAULT 0x00000000 44#define SIC1_ATR_DEFAULT 0x00026000 45#define SIC2_ATR_DEFAULT 0x00000000 46 47struct lpc32xx_event_group_regs { 48 void __iomem *enab_reg; 49 void __iomem *edge_reg; 50 void __iomem *maskstat_reg; 51 void __iomem *rawstat_reg; 52}; 53 54static const struct lpc32xx_event_group_regs lpc32xx_event_int_regs = { 55 .enab_reg = LPC32XX_CLKPWR_INT_ER, 56 .edge_reg = LPC32XX_CLKPWR_INT_AP, 57 .maskstat_reg = LPC32XX_CLKPWR_INT_SR, 58 .rawstat_reg = LPC32XX_CLKPWR_INT_RS, 59}; 60 61static const struct lpc32xx_event_group_regs lpc32xx_event_pin_regs = { 62 .enab_reg = LPC32XX_CLKPWR_PIN_ER, 63 .edge_reg = LPC32XX_CLKPWR_PIN_AP, 64 .maskstat_reg = LPC32XX_CLKPWR_PIN_SR, 65 .rawstat_reg = LPC32XX_CLKPWR_PIN_RS, 66}; 67 68struct lpc32xx_event_info { 69 const struct lpc32xx_event_group_regs *event_group; 70 u32 mask; 71}; 72 73/* 74 * Maps an IRQ number to and event mask and register 75 */ 76static const struct lpc32xx_event_info lpc32xx_events[NR_IRQS] = { 77 [IRQ_LPC32XX_GPI_08] = { 78 .event_group = &lpc32xx_event_pin_regs, 79 .mask = LPC32XX_CLKPWR_EXTSRC_GPI_08_BIT, 80 }, 81 [IRQ_LPC32XX_GPI_09] = { 82 .event_group = &lpc32xx_event_pin_regs, 83 .mask = LPC32XX_CLKPWR_EXTSRC_GPI_09_BIT, 84 }, 85 [IRQ_LPC32XX_GPI_19] = { 86 .event_group = &lpc32xx_event_pin_regs, 87 .mask = LPC32XX_CLKPWR_EXTSRC_GPI_19_BIT, 88 }, 89 [IRQ_LPC32XX_GPI_07] = { 90 .event_group = &lpc32xx_event_pin_regs, 91 .mask = LPC32XX_CLKPWR_EXTSRC_GPI_07_BIT, 92 }, 93 [IRQ_LPC32XX_GPI_00] = { 94 .event_group = &lpc32xx_event_pin_regs, 95 .mask = LPC32XX_CLKPWR_EXTSRC_GPI_00_BIT, 96 }, 97 [IRQ_LPC32XX_GPI_01] = { 98 .event_group = &lpc32xx_event_pin_regs, 99 .mask = LPC32XX_CLKPWR_EXTSRC_GPI_01_BIT, 100 }, 101 [IRQ_LPC32XX_GPI_02] = { 102 .event_group = &lpc32xx_event_pin_regs, 103 .mask = LPC32XX_CLKPWR_EXTSRC_GPI_02_BIT, 104 }, 105 [IRQ_LPC32XX_GPI_03] = { 106 .event_group = &lpc32xx_event_pin_regs, 107 .mask = LPC32XX_CLKPWR_EXTSRC_GPI_03_BIT, 108 }, 109 [IRQ_LPC32XX_GPI_04] = { 110 .event_group = &lpc32xx_event_pin_regs, 111 .mask = LPC32XX_CLKPWR_EXTSRC_GPI_04_BIT, 112 }, 113 [IRQ_LPC32XX_GPI_05] = { 114 .event_group = &lpc32xx_event_pin_regs, 115 .mask = LPC32XX_CLKPWR_EXTSRC_GPI_05_BIT, 116 }, 117 [IRQ_LPC32XX_GPI_06] = { 118 .event_group = &lpc32xx_event_pin_regs, 119 .mask = LPC32XX_CLKPWR_EXTSRC_GPI_06_BIT, 120 }, 121 [IRQ_LPC32XX_GPIO_00] = { 122 .event_group = &lpc32xx_event_int_regs, 123 .mask = LPC32XX_CLKPWR_INTSRC_GPIO_00_BIT, 124 }, 125 [IRQ_LPC32XX_GPIO_01] = { 126 .event_group = &lpc32xx_event_int_regs, 127 .mask = LPC32XX_CLKPWR_INTSRC_GPIO_01_BIT, 128 }, 129 [IRQ_LPC32XX_GPIO_02] = { 130 .event_group = &lpc32xx_event_int_regs, 131 .mask = LPC32XX_CLKPWR_INTSRC_GPIO_02_BIT, 132 }, 133 [IRQ_LPC32XX_GPIO_03] = { 134 .event_group = &lpc32xx_event_int_regs, 135 .mask = LPC32XX_CLKPWR_INTSRC_GPIO_03_BIT, 136 }, 137 [IRQ_LPC32XX_GPIO_04] = { 138 .event_group = &lpc32xx_event_int_regs, 139 .mask = LPC32XX_CLKPWR_INTSRC_GPIO_04_BIT, 140 }, 141 [IRQ_LPC32XX_GPIO_05] = { 142 .event_group = &lpc32xx_event_int_regs, 143 .mask = LPC32XX_CLKPWR_INTSRC_GPIO_05_BIT, 144 }, 145 [IRQ_LPC32XX_KEY] = { 146 .event_group = &lpc32xx_event_int_regs, 147 .mask = LPC32XX_CLKPWR_INTSRC_KEY_BIT, 148 }, 149 [IRQ_LPC32XX_USB_OTG_ATX] = { 150 .event_group = &lpc32xx_event_int_regs, 151 .mask = LPC32XX_CLKPWR_INTSRC_USBATXINT_BIT, 152 }, 153 [IRQ_LPC32XX_USB_HOST] = { 154 .event_group = &lpc32xx_event_int_regs, 155 .mask = LPC32XX_CLKPWR_INTSRC_USB_BIT, 156 }, 157 [IRQ_LPC32XX_RTC] = { 158 .event_group = &lpc32xx_event_int_regs, 159 .mask = LPC32XX_CLKPWR_INTSRC_RTC_BIT, 160 }, 161 [IRQ_LPC32XX_MSTIMER] = { 162 .event_group = &lpc32xx_event_int_regs, 163 .mask = LPC32XX_CLKPWR_INTSRC_MSTIMER_BIT, 164 }, 165 [IRQ_LPC32XX_TS_AUX] = { 166 .event_group = &lpc32xx_event_int_regs, 167 .mask = LPC32XX_CLKPWR_INTSRC_TS_AUX_BIT, 168 }, 169 [IRQ_LPC32XX_TS_P] = { 170 .event_group = &lpc32xx_event_int_regs, 171 .mask = LPC32XX_CLKPWR_INTSRC_TS_P_BIT, 172 }, 173 [IRQ_LPC32XX_TS_IRQ] = { 174 .event_group = &lpc32xx_event_int_regs, 175 .mask = LPC32XX_CLKPWR_INTSRC_ADC_BIT, 176 }, 177}; 178 179static void get_controller(unsigned int irq, unsigned int *base, 180 unsigned int *irqbit) 181{ 182 if (irq < 32) { 183 *base = LPC32XX_MIC_BASE; 184 *irqbit = 1 << irq; 185 } else if (irq < 64) { 186 *base = LPC32XX_SIC1_BASE; 187 *irqbit = 1 << (irq - 32); 188 } else { 189 *base = LPC32XX_SIC2_BASE; 190 *irqbit = 1 << (irq - 64); 191 } 192} 193 194static void lpc32xx_mask_irq(unsigned int irq) 195{ 196 unsigned int reg, ctrl, mask; 197 198 get_controller(irq, &ctrl, &mask); 199 200 reg = __raw_readl(LPC32XX_INTC_MASK(ctrl)) & ~mask; 201 __raw_writel(reg, LPC32XX_INTC_MASK(ctrl)); 202} 203 204static void lpc32xx_unmask_irq(unsigned int irq) 205{ 206 unsigned int reg, ctrl, mask; 207 208 get_controller(irq, &ctrl, &mask); 209 210 reg = __raw_readl(LPC32XX_INTC_MASK(ctrl)) | mask; 211 __raw_writel(reg, LPC32XX_INTC_MASK(ctrl)); 212} 213 214static void lpc32xx_ack_irq(unsigned int irq) 215{ 216 unsigned int ctrl, mask; 217 218 get_controller(irq, &ctrl, &mask); 219 220 __raw_writel(mask, LPC32XX_INTC_RAW_STAT(ctrl)); 221 222 /* Also need to clear pending wake event */ 223 if (lpc32xx_events[irq].mask != 0) 224 __raw_writel(lpc32xx_events[irq].mask, 225 lpc32xx_events[irq].event_group->rawstat_reg); 226} 227 228static void __lpc32xx_set_irq_type(unsigned int irq, int use_high_level, 229 int use_edge) 230{ 231 unsigned int reg, ctrl, mask; 232 233 get_controller(irq, &ctrl, &mask); 234 235 /* Activation level, high or low */ 236 reg = __raw_readl(LPC32XX_INTC_POLAR(ctrl)); 237 if (use_high_level) 238 reg |= mask; 239 else 240 reg &= ~mask; 241 __raw_writel(reg, LPC32XX_INTC_POLAR(ctrl)); 242 243 /* Activation type, edge or level */ 244 reg = __raw_readl(LPC32XX_INTC_ACT_TYPE(ctrl)); 245 if (use_edge) 246 reg |= mask; 247 else 248 reg &= ~mask; 249 __raw_writel(reg, LPC32XX_INTC_ACT_TYPE(ctrl)); 250 251 /* Use same polarity for the wake events */ 252 if (lpc32xx_events[irq].mask != 0) { 253 reg = __raw_readl(lpc32xx_events[irq].event_group->edge_reg); 254 255 if (use_high_level) 256 reg |= lpc32xx_events[irq].mask; 257 else 258 reg &= ~lpc32xx_events[irq].mask; 259 260 __raw_writel(reg, lpc32xx_events[irq].event_group->edge_reg); 261 } 262} 263 264static int lpc32xx_set_irq_type(unsigned int irq, unsigned int type) 265{ 266 switch (type) { 267 case IRQ_TYPE_EDGE_RISING: 268 /* Rising edge sensitive */ 269 __lpc32xx_set_irq_type(irq, 1, 1); 270 break; 271 272 case IRQ_TYPE_EDGE_FALLING: 273 /* Falling edge sensitive */ 274 __lpc32xx_set_irq_type(irq, 0, 1); 275 break; 276 277 case IRQ_TYPE_LEVEL_LOW: 278 /* Low level sensitive */ 279 __lpc32xx_set_irq_type(irq, 0, 0); 280 break; 281 282 case IRQ_TYPE_LEVEL_HIGH: 283 /* High level sensitive */ 284 __lpc32xx_set_irq_type(irq, 1, 0); 285 break; 286 287 /* Other modes are not supported */ 288 default: 289 return -EINVAL; 290 } 291 292 /* Ok to use the level handler for all types */ 293 set_irq_handler(irq, handle_level_irq); 294 295 return 0; 296} 297 298static int lpc32xx_irq_wake(unsigned int irqno, unsigned int state) 299{ 300 unsigned long eventreg; 301 302 if (lpc32xx_events[irqno].mask != 0) { 303 eventreg = __raw_readl(lpc32xx_events[irqno]. 304 event_group->enab_reg); 305 306 if (state) 307 eventreg |= lpc32xx_events[irqno].mask; 308 else 309 eventreg &= ~lpc32xx_events[irqno].mask; 310 311 __raw_writel(eventreg, 312 lpc32xx_events[irqno].event_group->enab_reg); 313 314 return 0; 315 } 316 317 /* Clear event */ 318 __raw_writel(lpc32xx_events[irqno].mask, 319 lpc32xx_events[irqno].event_group->rawstat_reg); 320 321 return -ENODEV; 322} 323 324static void __init lpc32xx_set_default_mappings(unsigned int apr, 325 unsigned int atr, unsigned int offset) 326{ 327 unsigned int i; 328 329 /* Set activation levels for each interrupt */ 330 i = 0; 331 while (i < 32) { 332 __lpc32xx_set_irq_type(offset + i, ((apr >> i) & 0x1), 333 ((atr >> i) & 0x1)); 334 i++; 335 } 336} 337 338static struct irq_chip lpc32xx_irq_chip = { 339 .ack = lpc32xx_ack_irq, 340 .mask = lpc32xx_mask_irq, 341 .unmask = lpc32xx_unmask_irq, 342 .set_type = lpc32xx_set_irq_type, 343 .set_wake = lpc32xx_irq_wake 344}; 345 346static void lpc32xx_sic1_handler(unsigned int irq, struct irq_desc *desc) 347{ 348 unsigned long ints = __raw_readl(LPC32XX_INTC_STAT(LPC32XX_SIC1_BASE)); 349 350 while (ints != 0) { 351 int irqno = fls(ints) - 1; 352 353 ints &= ~(1 << irqno); 354 355 generic_handle_irq(LPC32XX_SIC1_IRQ(irqno)); 356 } 357} 358 359static void lpc32xx_sic2_handler(unsigned int irq, struct irq_desc *desc) 360{ 361 unsigned long ints = __raw_readl(LPC32XX_INTC_STAT(LPC32XX_SIC2_BASE)); 362 363 while (ints != 0) { 364 int irqno = fls(ints) - 1; 365 366 ints &= ~(1 << irqno); 367 368 generic_handle_irq(LPC32XX_SIC2_IRQ(irqno)); 369 } 370} 371 372void __init lpc32xx_init_irq(void) 373{ 374 unsigned int i; 375 376 /* Setup MIC */ 377 __raw_writel(0, LPC32XX_INTC_MASK(LPC32XX_MIC_BASE)); 378 __raw_writel(MIC_APR_DEFAULT, LPC32XX_INTC_POLAR(LPC32XX_MIC_BASE)); 379 __raw_writel(MIC_ATR_DEFAULT, LPC32XX_INTC_ACT_TYPE(LPC32XX_MIC_BASE)); 380 381 /* Setup SIC1 */ 382 __raw_writel(0, LPC32XX_INTC_MASK(LPC32XX_SIC1_BASE)); 383 __raw_writel(MIC_APR_DEFAULT, LPC32XX_INTC_POLAR(LPC32XX_SIC1_BASE)); 384 __raw_writel(MIC_ATR_DEFAULT, LPC32XX_INTC_ACT_TYPE(LPC32XX_SIC1_BASE)); 385 386 /* Setup SIC2 */ 387 __raw_writel(0, LPC32XX_INTC_MASK(LPC32XX_SIC2_BASE)); 388 __raw_writel(MIC_APR_DEFAULT, LPC32XX_INTC_POLAR(LPC32XX_SIC2_BASE)); 389 __raw_writel(MIC_ATR_DEFAULT, LPC32XX_INTC_ACT_TYPE(LPC32XX_SIC2_BASE)); 390 391 /* Configure supported IRQ's */ 392 for (i = 0; i < NR_IRQS; i++) { 393 set_irq_chip(i, &lpc32xx_irq_chip); 394 set_irq_handler(i, handle_level_irq); 395 set_irq_flags(i, IRQF_VALID); 396 } 397 398 /* Set default mappings */ 399 lpc32xx_set_default_mappings(MIC_APR_DEFAULT, MIC_ATR_DEFAULT, 0); 400 lpc32xx_set_default_mappings(SIC1_APR_DEFAULT, SIC1_ATR_DEFAULT, 32); 401 lpc32xx_set_default_mappings(SIC2_APR_DEFAULT, SIC2_ATR_DEFAULT, 64); 402 403 /* mask all interrupts except SUBIRQ */ 404 __raw_writel(0, LPC32XX_INTC_MASK(LPC32XX_MIC_BASE)); 405 __raw_writel(0, LPC32XX_INTC_MASK(LPC32XX_SIC1_BASE)); 406 __raw_writel(0, LPC32XX_INTC_MASK(LPC32XX_SIC2_BASE)); 407 408 /* MIC SUBIRQx interrupts will route handling to the chain handlers */ 409 set_irq_chained_handler(IRQ_LPC32XX_SUB1IRQ, lpc32xx_sic1_handler); 410 set_irq_chained_handler(IRQ_LPC32XX_SUB2IRQ, lpc32xx_sic2_handler); 411 412 /* Initially disable all wake events */ 413 __raw_writel(0, LPC32XX_CLKPWR_P01_ER); 414 __raw_writel(0, LPC32XX_CLKPWR_INT_ER); 415 __raw_writel(0, LPC32XX_CLKPWR_PIN_ER); 416 417 /* 418 * Default wake activation polarities, all pin sources are low edge 419 * triggered 420 */ 421 __raw_writel(LPC32XX_CLKPWR_INTSRC_TS_P_BIT | 422 LPC32XX_CLKPWR_INTSRC_MSTIMER_BIT | 423 LPC32XX_CLKPWR_INTSRC_RTC_BIT, 424 LPC32XX_CLKPWR_INT_AP); 425 __raw_writel(0, LPC32XX_CLKPWR_PIN_AP); 426 427 /* Clear latched wake event states */ 428 __raw_writel(__raw_readl(LPC32XX_CLKPWR_PIN_RS), 429 LPC32XX_CLKPWR_PIN_RS); 430 __raw_writel(__raw_readl(LPC32XX_CLKPWR_INT_RS), 431 LPC32XX_CLKPWR_INT_RS); 432} 433