irq.c revision f6737055c1c432a9628a9a731f9881ad8e0a9eee
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_GPI_28] = { 122 .event_group = &lpc32xx_event_pin_regs, 123 .mask = LPC32XX_CLKPWR_EXTSRC_GPI_28_BIT, 124 }, 125 [IRQ_LPC32XX_GPIO_00] = { 126 .event_group = &lpc32xx_event_int_regs, 127 .mask = LPC32XX_CLKPWR_INTSRC_GPIO_00_BIT, 128 }, 129 [IRQ_LPC32XX_GPIO_01] = { 130 .event_group = &lpc32xx_event_int_regs, 131 .mask = LPC32XX_CLKPWR_INTSRC_GPIO_01_BIT, 132 }, 133 [IRQ_LPC32XX_GPIO_02] = { 134 .event_group = &lpc32xx_event_int_regs, 135 .mask = LPC32XX_CLKPWR_INTSRC_GPIO_02_BIT, 136 }, 137 [IRQ_LPC32XX_GPIO_03] = { 138 .event_group = &lpc32xx_event_int_regs, 139 .mask = LPC32XX_CLKPWR_INTSRC_GPIO_03_BIT, 140 }, 141 [IRQ_LPC32XX_GPIO_04] = { 142 .event_group = &lpc32xx_event_int_regs, 143 .mask = LPC32XX_CLKPWR_INTSRC_GPIO_04_BIT, 144 }, 145 [IRQ_LPC32XX_GPIO_05] = { 146 .event_group = &lpc32xx_event_int_regs, 147 .mask = LPC32XX_CLKPWR_INTSRC_GPIO_05_BIT, 148 }, 149 [IRQ_LPC32XX_KEY] = { 150 .event_group = &lpc32xx_event_int_regs, 151 .mask = LPC32XX_CLKPWR_INTSRC_KEY_BIT, 152 }, 153 [IRQ_LPC32XX_USB_OTG_ATX] = { 154 .event_group = &lpc32xx_event_int_regs, 155 .mask = LPC32XX_CLKPWR_INTSRC_USBATXINT_BIT, 156 }, 157 [IRQ_LPC32XX_USB_HOST] = { 158 .event_group = &lpc32xx_event_int_regs, 159 .mask = LPC32XX_CLKPWR_INTSRC_USB_BIT, 160 }, 161 [IRQ_LPC32XX_RTC] = { 162 .event_group = &lpc32xx_event_int_regs, 163 .mask = LPC32XX_CLKPWR_INTSRC_RTC_BIT, 164 }, 165 [IRQ_LPC32XX_MSTIMER] = { 166 .event_group = &lpc32xx_event_int_regs, 167 .mask = LPC32XX_CLKPWR_INTSRC_MSTIMER_BIT, 168 }, 169 [IRQ_LPC32XX_TS_AUX] = { 170 .event_group = &lpc32xx_event_int_regs, 171 .mask = LPC32XX_CLKPWR_INTSRC_TS_AUX_BIT, 172 }, 173 [IRQ_LPC32XX_TS_P] = { 174 .event_group = &lpc32xx_event_int_regs, 175 .mask = LPC32XX_CLKPWR_INTSRC_TS_P_BIT, 176 }, 177 [IRQ_LPC32XX_TS_IRQ] = { 178 .event_group = &lpc32xx_event_int_regs, 179 .mask = LPC32XX_CLKPWR_INTSRC_ADC_BIT, 180 }, 181}; 182 183static void get_controller(unsigned int irq, unsigned int *base, 184 unsigned int *irqbit) 185{ 186 if (irq < 32) { 187 *base = LPC32XX_MIC_BASE; 188 *irqbit = 1 << irq; 189 } else if (irq < 64) { 190 *base = LPC32XX_SIC1_BASE; 191 *irqbit = 1 << (irq - 32); 192 } else { 193 *base = LPC32XX_SIC2_BASE; 194 *irqbit = 1 << (irq - 64); 195 } 196} 197 198static void lpc32xx_mask_irq(struct irq_data *d) 199{ 200 unsigned int reg, ctrl, mask; 201 202 get_controller(d->irq, &ctrl, &mask); 203 204 reg = __raw_readl(LPC32XX_INTC_MASK(ctrl)) & ~mask; 205 __raw_writel(reg, LPC32XX_INTC_MASK(ctrl)); 206} 207 208static void lpc32xx_unmask_irq(struct irq_data *d) 209{ 210 unsigned int reg, ctrl, mask; 211 212 get_controller(d->irq, &ctrl, &mask); 213 214 reg = __raw_readl(LPC32XX_INTC_MASK(ctrl)) | mask; 215 __raw_writel(reg, LPC32XX_INTC_MASK(ctrl)); 216} 217 218static void lpc32xx_ack_irq(struct irq_data *d) 219{ 220 unsigned int ctrl, mask; 221 222 get_controller(d->irq, &ctrl, &mask); 223 224 __raw_writel(mask, LPC32XX_INTC_RAW_STAT(ctrl)); 225 226 /* Also need to clear pending wake event */ 227 if (lpc32xx_events[d->irq].mask != 0) 228 __raw_writel(lpc32xx_events[d->irq].mask, 229 lpc32xx_events[d->irq].event_group->rawstat_reg); 230} 231 232static void __lpc32xx_set_irq_type(unsigned int irq, int use_high_level, 233 int use_edge) 234{ 235 unsigned int reg, ctrl, mask; 236 237 get_controller(irq, &ctrl, &mask); 238 239 /* Activation level, high or low */ 240 reg = __raw_readl(LPC32XX_INTC_POLAR(ctrl)); 241 if (use_high_level) 242 reg |= mask; 243 else 244 reg &= ~mask; 245 __raw_writel(reg, LPC32XX_INTC_POLAR(ctrl)); 246 247 /* Activation type, edge or level */ 248 reg = __raw_readl(LPC32XX_INTC_ACT_TYPE(ctrl)); 249 if (use_edge) 250 reg |= mask; 251 else 252 reg &= ~mask; 253 __raw_writel(reg, LPC32XX_INTC_ACT_TYPE(ctrl)); 254 255 /* Use same polarity for the wake events */ 256 if (lpc32xx_events[irq].mask != 0) { 257 reg = __raw_readl(lpc32xx_events[irq].event_group->edge_reg); 258 259 if (use_high_level) 260 reg |= lpc32xx_events[irq].mask; 261 else 262 reg &= ~lpc32xx_events[irq].mask; 263 264 __raw_writel(reg, lpc32xx_events[irq].event_group->edge_reg); 265 } 266} 267 268static int lpc32xx_set_irq_type(struct irq_data *d, unsigned int type) 269{ 270 switch (type) { 271 case IRQ_TYPE_EDGE_RISING: 272 /* Rising edge sensitive */ 273 __lpc32xx_set_irq_type(d->irq, 1, 1); 274 break; 275 276 case IRQ_TYPE_EDGE_FALLING: 277 /* Falling edge sensitive */ 278 __lpc32xx_set_irq_type(d->irq, 0, 1); 279 break; 280 281 case IRQ_TYPE_LEVEL_LOW: 282 /* Low level sensitive */ 283 __lpc32xx_set_irq_type(d->irq, 0, 0); 284 break; 285 286 case IRQ_TYPE_LEVEL_HIGH: 287 /* High level sensitive */ 288 __lpc32xx_set_irq_type(d->irq, 1, 0); 289 break; 290 291 /* Other modes are not supported */ 292 default: 293 return -EINVAL; 294 } 295 296 /* Ok to use the level handler for all types */ 297 irq_set_handler(d->irq, handle_level_irq); 298 299 return 0; 300} 301 302static int lpc32xx_irq_wake(struct irq_data *d, unsigned int state) 303{ 304 unsigned long eventreg; 305 306 if (lpc32xx_events[d->irq].mask != 0) { 307 eventreg = __raw_readl(lpc32xx_events[d->irq]. 308 event_group->enab_reg); 309 310 if (state) 311 eventreg |= lpc32xx_events[d->irq].mask; 312 else 313 eventreg &= ~lpc32xx_events[d->irq].mask; 314 315 __raw_writel(eventreg, 316 lpc32xx_events[d->irq].event_group->enab_reg); 317 318 return 0; 319 } 320 321 /* Clear event */ 322 __raw_writel(lpc32xx_events[d->irq].mask, 323 lpc32xx_events[d->irq].event_group->rawstat_reg); 324 325 return -ENODEV; 326} 327 328static void __init lpc32xx_set_default_mappings(unsigned int apr, 329 unsigned int atr, unsigned int offset) 330{ 331 unsigned int i; 332 333 /* Set activation levels for each interrupt */ 334 i = 0; 335 while (i < 32) { 336 __lpc32xx_set_irq_type(offset + i, ((apr >> i) & 0x1), 337 ((atr >> i) & 0x1)); 338 i++; 339 } 340} 341 342static struct irq_chip lpc32xx_irq_chip = { 343 .irq_ack = lpc32xx_ack_irq, 344 .irq_mask = lpc32xx_mask_irq, 345 .irq_unmask = lpc32xx_unmask_irq, 346 .irq_set_type = lpc32xx_set_irq_type, 347 .irq_set_wake = lpc32xx_irq_wake 348}; 349 350static void lpc32xx_sic1_handler(unsigned int irq, struct irq_desc *desc) 351{ 352 unsigned long ints = __raw_readl(LPC32XX_INTC_STAT(LPC32XX_SIC1_BASE)); 353 354 while (ints != 0) { 355 int irqno = fls(ints) - 1; 356 357 ints &= ~(1 << irqno); 358 359 generic_handle_irq(LPC32XX_SIC1_IRQ(irqno)); 360 } 361} 362 363static void lpc32xx_sic2_handler(unsigned int irq, struct irq_desc *desc) 364{ 365 unsigned long ints = __raw_readl(LPC32XX_INTC_STAT(LPC32XX_SIC2_BASE)); 366 367 while (ints != 0) { 368 int irqno = fls(ints) - 1; 369 370 ints &= ~(1 << irqno); 371 372 generic_handle_irq(LPC32XX_SIC2_IRQ(irqno)); 373 } 374} 375 376void __init lpc32xx_init_irq(void) 377{ 378 unsigned int i; 379 380 /* Setup MIC */ 381 __raw_writel(0, LPC32XX_INTC_MASK(LPC32XX_MIC_BASE)); 382 __raw_writel(MIC_APR_DEFAULT, LPC32XX_INTC_POLAR(LPC32XX_MIC_BASE)); 383 __raw_writel(MIC_ATR_DEFAULT, LPC32XX_INTC_ACT_TYPE(LPC32XX_MIC_BASE)); 384 385 /* Setup SIC1 */ 386 __raw_writel(0, LPC32XX_INTC_MASK(LPC32XX_SIC1_BASE)); 387 __raw_writel(MIC_APR_DEFAULT, LPC32XX_INTC_POLAR(LPC32XX_SIC1_BASE)); 388 __raw_writel(MIC_ATR_DEFAULT, LPC32XX_INTC_ACT_TYPE(LPC32XX_SIC1_BASE)); 389 390 /* Setup SIC2 */ 391 __raw_writel(0, LPC32XX_INTC_MASK(LPC32XX_SIC2_BASE)); 392 __raw_writel(MIC_APR_DEFAULT, LPC32XX_INTC_POLAR(LPC32XX_SIC2_BASE)); 393 __raw_writel(MIC_ATR_DEFAULT, LPC32XX_INTC_ACT_TYPE(LPC32XX_SIC2_BASE)); 394 395 /* Configure supported IRQ's */ 396 for (i = 0; i < NR_IRQS; i++) { 397 irq_set_chip_and_handler(i, &lpc32xx_irq_chip, 398 handle_level_irq); 399 set_irq_flags(i, IRQF_VALID); 400 } 401 402 /* Set default mappings */ 403 lpc32xx_set_default_mappings(MIC_APR_DEFAULT, MIC_ATR_DEFAULT, 0); 404 lpc32xx_set_default_mappings(SIC1_APR_DEFAULT, SIC1_ATR_DEFAULT, 32); 405 lpc32xx_set_default_mappings(SIC2_APR_DEFAULT, SIC2_ATR_DEFAULT, 64); 406 407 /* mask all interrupts except SUBIRQ */ 408 __raw_writel(0, LPC32XX_INTC_MASK(LPC32XX_MIC_BASE)); 409 __raw_writel(0, LPC32XX_INTC_MASK(LPC32XX_SIC1_BASE)); 410 __raw_writel(0, LPC32XX_INTC_MASK(LPC32XX_SIC2_BASE)); 411 412 /* MIC SUBIRQx interrupts will route handling to the chain handlers */ 413 irq_set_chained_handler(IRQ_LPC32XX_SUB1IRQ, lpc32xx_sic1_handler); 414 irq_set_chained_handler(IRQ_LPC32XX_SUB2IRQ, lpc32xx_sic2_handler); 415 416 /* Initially disable all wake events */ 417 __raw_writel(0, LPC32XX_CLKPWR_P01_ER); 418 __raw_writel(0, LPC32XX_CLKPWR_INT_ER); 419 __raw_writel(0, LPC32XX_CLKPWR_PIN_ER); 420 421 /* 422 * Default wake activation polarities, all pin sources are low edge 423 * triggered 424 */ 425 __raw_writel(LPC32XX_CLKPWR_INTSRC_TS_P_BIT | 426 LPC32XX_CLKPWR_INTSRC_MSTIMER_BIT | 427 LPC32XX_CLKPWR_INTSRC_RTC_BIT, 428 LPC32XX_CLKPWR_INT_AP); 429 __raw_writel(0, LPC32XX_CLKPWR_PIN_AP); 430 431 /* Clear latched wake event states */ 432 __raw_writel(__raw_readl(LPC32XX_CLKPWR_PIN_RS), 433 LPC32XX_CLKPWR_PIN_RS); 434 __raw_writel(__raw_readl(LPC32XX_CLKPWR_INT_RS), 435 LPC32XX_CLKPWR_INT_RS); 436} 437