Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at 17431928194b36a0f88082df875e2e036da7fddf 555 lines 13 kB view raw
1/* 2 * wm831x-irq.c -- Interrupt controller support for Wolfson WM831x PMICs 3 * 4 * Copyright 2009 Wolfson Microelectronics PLC. 5 * 6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> 7 * 8 * This program is free software; you can redistribute it and/or modify it 9 * under the terms of the GNU General Public License as published by the 10 * Free Software Foundation; either version 2 of the License, or (at your 11 * option) any later version. 12 * 13 */ 14 15#include <linux/kernel.h> 16#include <linux/module.h> 17#include <linux/i2c.h> 18#include <linux/irq.h> 19#include <linux/mfd/core.h> 20#include <linux/interrupt.h> 21 22#include <linux/mfd/wm831x/core.h> 23#include <linux/mfd/wm831x/pdata.h> 24#include <linux/mfd/wm831x/gpio.h> 25#include <linux/mfd/wm831x/irq.h> 26 27#include <linux/delay.h> 28 29/* 30 * Since generic IRQs don't currently support interrupt controllers on 31 * interrupt driven buses we don't use genirq but instead provide an 32 * interface that looks very much like the standard ones. This leads 33 * to some bodges, including storing interrupt handler information in 34 * the static irq_data table we use to look up the data for individual 35 * interrupts, but hopefully won't last too long. 36 */ 37 38struct wm831x_irq_data { 39 int primary; 40 int reg; 41 int mask; 42 irq_handler_t handler; 43 void *handler_data; 44}; 45 46static struct wm831x_irq_data wm831x_irqs[] = { 47 [WM831X_IRQ_TEMP_THW] = { 48 .primary = WM831X_TEMP_INT, 49 .reg = 1, 50 .mask = WM831X_TEMP_THW_EINT, 51 }, 52 [WM831X_IRQ_GPIO_1] = { 53 .primary = WM831X_GP_INT, 54 .reg = 5, 55 .mask = WM831X_GP1_EINT, 56 }, 57 [WM831X_IRQ_GPIO_2] = { 58 .primary = WM831X_GP_INT, 59 .reg = 5, 60 .mask = WM831X_GP2_EINT, 61 }, 62 [WM831X_IRQ_GPIO_3] = { 63 .primary = WM831X_GP_INT, 64 .reg = 5, 65 .mask = WM831X_GP3_EINT, 66 }, 67 [WM831X_IRQ_GPIO_4] = { 68 .primary = WM831X_GP_INT, 69 .reg = 5, 70 .mask = WM831X_GP4_EINT, 71 }, 72 [WM831X_IRQ_GPIO_5] = { 73 .primary = WM831X_GP_INT, 74 .reg = 5, 75 .mask = WM831X_GP5_EINT, 76 }, 77 [WM831X_IRQ_GPIO_6] = { 78 .primary = WM831X_GP_INT, 79 .reg = 5, 80 .mask = WM831X_GP6_EINT, 81 }, 82 [WM831X_IRQ_GPIO_7] = { 83 .primary = WM831X_GP_INT, 84 .reg = 5, 85 .mask = WM831X_GP7_EINT, 86 }, 87 [WM831X_IRQ_GPIO_8] = { 88 .primary = WM831X_GP_INT, 89 .reg = 5, 90 .mask = WM831X_GP8_EINT, 91 }, 92 [WM831X_IRQ_GPIO_9] = { 93 .primary = WM831X_GP_INT, 94 .reg = 5, 95 .mask = WM831X_GP9_EINT, 96 }, 97 [WM831X_IRQ_GPIO_10] = { 98 .primary = WM831X_GP_INT, 99 .reg = 5, 100 .mask = WM831X_GP10_EINT, 101 }, 102 [WM831X_IRQ_GPIO_11] = { 103 .primary = WM831X_GP_INT, 104 .reg = 5, 105 .mask = WM831X_GP11_EINT, 106 }, 107 [WM831X_IRQ_GPIO_12] = { 108 .primary = WM831X_GP_INT, 109 .reg = 5, 110 .mask = WM831X_GP12_EINT, 111 }, 112 [WM831X_IRQ_GPIO_13] = { 113 .primary = WM831X_GP_INT, 114 .reg = 5, 115 .mask = WM831X_GP13_EINT, 116 }, 117 [WM831X_IRQ_GPIO_14] = { 118 .primary = WM831X_GP_INT, 119 .reg = 5, 120 .mask = WM831X_GP14_EINT, 121 }, 122 [WM831X_IRQ_GPIO_15] = { 123 .primary = WM831X_GP_INT, 124 .reg = 5, 125 .mask = WM831X_GP15_EINT, 126 }, 127 [WM831X_IRQ_GPIO_16] = { 128 .primary = WM831X_GP_INT, 129 .reg = 5, 130 .mask = WM831X_GP16_EINT, 131 }, 132 [WM831X_IRQ_ON] = { 133 .primary = WM831X_ON_PIN_INT, 134 .reg = 1, 135 .mask = WM831X_ON_PIN_EINT, 136 }, 137 [WM831X_IRQ_PPM_SYSLO] = { 138 .primary = WM831X_PPM_INT, 139 .reg = 1, 140 .mask = WM831X_PPM_SYSLO_EINT, 141 }, 142 [WM831X_IRQ_PPM_PWR_SRC] = { 143 .primary = WM831X_PPM_INT, 144 .reg = 1, 145 .mask = WM831X_PPM_PWR_SRC_EINT, 146 }, 147 [WM831X_IRQ_PPM_USB_CURR] = { 148 .primary = WM831X_PPM_INT, 149 .reg = 1, 150 .mask = WM831X_PPM_USB_CURR_EINT, 151 }, 152 [WM831X_IRQ_WDOG_TO] = { 153 .primary = WM831X_WDOG_INT, 154 .reg = 1, 155 .mask = WM831X_WDOG_TO_EINT, 156 }, 157 [WM831X_IRQ_RTC_PER] = { 158 .primary = WM831X_RTC_INT, 159 .reg = 1, 160 .mask = WM831X_RTC_PER_EINT, 161 }, 162 [WM831X_IRQ_RTC_ALM] = { 163 .primary = WM831X_RTC_INT, 164 .reg = 1, 165 .mask = WM831X_RTC_ALM_EINT, 166 }, 167 [WM831X_IRQ_CHG_BATT_HOT] = { 168 .primary = WM831X_CHG_INT, 169 .reg = 2, 170 .mask = WM831X_CHG_BATT_HOT_EINT, 171 }, 172 [WM831X_IRQ_CHG_BATT_COLD] = { 173 .primary = WM831X_CHG_INT, 174 .reg = 2, 175 .mask = WM831X_CHG_BATT_COLD_EINT, 176 }, 177 [WM831X_IRQ_CHG_BATT_FAIL] = { 178 .primary = WM831X_CHG_INT, 179 .reg = 2, 180 .mask = WM831X_CHG_BATT_FAIL_EINT, 181 }, 182 [WM831X_IRQ_CHG_OV] = { 183 .primary = WM831X_CHG_INT, 184 .reg = 2, 185 .mask = WM831X_CHG_OV_EINT, 186 }, 187 [WM831X_IRQ_CHG_END] = { 188 .primary = WM831X_CHG_INT, 189 .reg = 2, 190 .mask = WM831X_CHG_END_EINT, 191 }, 192 [WM831X_IRQ_CHG_TO] = { 193 .primary = WM831X_CHG_INT, 194 .reg = 2, 195 .mask = WM831X_CHG_TO_EINT, 196 }, 197 [WM831X_IRQ_CHG_MODE] = { 198 .primary = WM831X_CHG_INT, 199 .reg = 2, 200 .mask = WM831X_CHG_MODE_EINT, 201 }, 202 [WM831X_IRQ_CHG_START] = { 203 .primary = WM831X_CHG_INT, 204 .reg = 2, 205 .mask = WM831X_CHG_START_EINT, 206 }, 207 [WM831X_IRQ_TCHDATA] = { 208 .primary = WM831X_TCHDATA_INT, 209 .reg = 1, 210 .mask = WM831X_TCHDATA_EINT, 211 }, 212 [WM831X_IRQ_TCHPD] = { 213 .primary = WM831X_TCHPD_INT, 214 .reg = 1, 215 .mask = WM831X_TCHPD_EINT, 216 }, 217 [WM831X_IRQ_AUXADC_DATA] = { 218 .primary = WM831X_AUXADC_INT, 219 .reg = 1, 220 .mask = WM831X_AUXADC_DATA_EINT, 221 }, 222 [WM831X_IRQ_AUXADC_DCOMP1] = { 223 .primary = WM831X_AUXADC_INT, 224 .reg = 1, 225 .mask = WM831X_AUXADC_DCOMP1_EINT, 226 }, 227 [WM831X_IRQ_AUXADC_DCOMP2] = { 228 .primary = WM831X_AUXADC_INT, 229 .reg = 1, 230 .mask = WM831X_AUXADC_DCOMP2_EINT, 231 }, 232 [WM831X_IRQ_AUXADC_DCOMP3] = { 233 .primary = WM831X_AUXADC_INT, 234 .reg = 1, 235 .mask = WM831X_AUXADC_DCOMP3_EINT, 236 }, 237 [WM831X_IRQ_AUXADC_DCOMP4] = { 238 .primary = WM831X_AUXADC_INT, 239 .reg = 1, 240 .mask = WM831X_AUXADC_DCOMP4_EINT, 241 }, 242 [WM831X_IRQ_CS1] = { 243 .primary = WM831X_CS_INT, 244 .reg = 2, 245 .mask = WM831X_CS1_EINT, 246 }, 247 [WM831X_IRQ_CS2] = { 248 .primary = WM831X_CS_INT, 249 .reg = 2, 250 .mask = WM831X_CS2_EINT, 251 }, 252 [WM831X_IRQ_HC_DC1] = { 253 .primary = WM831X_HC_INT, 254 .reg = 4, 255 .mask = WM831X_HC_DC1_EINT, 256 }, 257 [WM831X_IRQ_HC_DC2] = { 258 .primary = WM831X_HC_INT, 259 .reg = 4, 260 .mask = WM831X_HC_DC2_EINT, 261 }, 262 [WM831X_IRQ_UV_LDO1] = { 263 .primary = WM831X_UV_INT, 264 .reg = 3, 265 .mask = WM831X_UV_LDO1_EINT, 266 }, 267 [WM831X_IRQ_UV_LDO2] = { 268 .primary = WM831X_UV_INT, 269 .reg = 3, 270 .mask = WM831X_UV_LDO2_EINT, 271 }, 272 [WM831X_IRQ_UV_LDO3] = { 273 .primary = WM831X_UV_INT, 274 .reg = 3, 275 .mask = WM831X_UV_LDO3_EINT, 276 }, 277 [WM831X_IRQ_UV_LDO4] = { 278 .primary = WM831X_UV_INT, 279 .reg = 3, 280 .mask = WM831X_UV_LDO4_EINT, 281 }, 282 [WM831X_IRQ_UV_LDO5] = { 283 .primary = WM831X_UV_INT, 284 .reg = 3, 285 .mask = WM831X_UV_LDO5_EINT, 286 }, 287 [WM831X_IRQ_UV_LDO6] = { 288 .primary = WM831X_UV_INT, 289 .reg = 3, 290 .mask = WM831X_UV_LDO6_EINT, 291 }, 292 [WM831X_IRQ_UV_LDO7] = { 293 .primary = WM831X_UV_INT, 294 .reg = 3, 295 .mask = WM831X_UV_LDO7_EINT, 296 }, 297 [WM831X_IRQ_UV_LDO8] = { 298 .primary = WM831X_UV_INT, 299 .reg = 3, 300 .mask = WM831X_UV_LDO8_EINT, 301 }, 302 [WM831X_IRQ_UV_LDO9] = { 303 .primary = WM831X_UV_INT, 304 .reg = 3, 305 .mask = WM831X_UV_LDO9_EINT, 306 }, 307 [WM831X_IRQ_UV_LDO10] = { 308 .primary = WM831X_UV_INT, 309 .reg = 3, 310 .mask = WM831X_UV_LDO10_EINT, 311 }, 312 [WM831X_IRQ_UV_DC1] = { 313 .primary = WM831X_UV_INT, 314 .reg = 4, 315 .mask = WM831X_UV_DC1_EINT, 316 }, 317 [WM831X_IRQ_UV_DC2] = { 318 .primary = WM831X_UV_INT, 319 .reg = 4, 320 .mask = WM831X_UV_DC2_EINT, 321 }, 322 [WM831X_IRQ_UV_DC3] = { 323 .primary = WM831X_UV_INT, 324 .reg = 4, 325 .mask = WM831X_UV_DC3_EINT, 326 }, 327 [WM831X_IRQ_UV_DC4] = { 328 .primary = WM831X_UV_INT, 329 .reg = 4, 330 .mask = WM831X_UV_DC4_EINT, 331 }, 332}; 333 334static inline int irq_data_to_status_reg(struct wm831x_irq_data *irq_data) 335{ 336 return WM831X_INTERRUPT_STATUS_1 - 1 + irq_data->reg; 337} 338 339static inline int irq_data_to_mask_reg(struct wm831x_irq_data *irq_data) 340{ 341 return WM831X_INTERRUPT_STATUS_1_MASK - 1 + irq_data->reg; 342} 343 344static inline struct wm831x_irq_data *irq_to_wm831x_irq(struct wm831x *wm831x, 345 int irq) 346{ 347 return &wm831x_irqs[irq - wm831x->irq_base]; 348} 349 350static void wm831x_irq_lock(unsigned int irq) 351{ 352 struct wm831x *wm831x = get_irq_chip_data(irq); 353 354 mutex_lock(&wm831x->irq_lock); 355} 356 357static void wm831x_irq_sync_unlock(unsigned int irq) 358{ 359 struct wm831x *wm831x = get_irq_chip_data(irq); 360 int i; 361 362 for (i = 0; i < ARRAY_SIZE(wm831x->irq_masks_cur); i++) { 363 /* If there's been a change in the mask write it back 364 * to the hardware. */ 365 if (wm831x->irq_masks_cur[i] != wm831x->irq_masks_cache[i]) { 366 wm831x->irq_masks_cache[i] = wm831x->irq_masks_cur[i]; 367 wm831x_reg_write(wm831x, 368 WM831X_INTERRUPT_STATUS_1_MASK + i, 369 wm831x->irq_masks_cur[i]); 370 } 371 } 372 373 mutex_unlock(&wm831x->irq_lock); 374} 375 376static void wm831x_irq_unmask(unsigned int irq) 377{ 378 struct wm831x *wm831x = get_irq_chip_data(irq); 379 struct wm831x_irq_data *irq_data = irq_to_wm831x_irq(wm831x, irq); 380 381 wm831x->irq_masks_cur[irq_data->reg - 1] &= ~irq_data->mask; 382} 383 384static void wm831x_irq_mask(unsigned int irq) 385{ 386 struct wm831x *wm831x = get_irq_chip_data(irq); 387 struct wm831x_irq_data *irq_data = irq_to_wm831x_irq(wm831x, irq); 388 389 wm831x->irq_masks_cur[irq_data->reg - 1] |= irq_data->mask; 390} 391 392static int wm831x_irq_set_type(unsigned int irq, unsigned int type) 393{ 394 struct wm831x *wm831x = get_irq_chip_data(irq); 395 int val; 396 397 irq = irq - wm831x->irq_base; 398 399 if (irq < WM831X_IRQ_GPIO_1 || irq > WM831X_IRQ_GPIO_11) 400 return -EINVAL; 401 402 switch (type) { 403 case IRQ_TYPE_EDGE_BOTH: 404 val = WM831X_GPN_INT_MODE; 405 break; 406 case IRQ_TYPE_EDGE_RISING: 407 val = WM831X_GPN_POL; 408 break; 409 case IRQ_TYPE_EDGE_FALLING: 410 val = 0; 411 break; 412 default: 413 return -EINVAL; 414 } 415 416 return wm831x_set_bits(wm831x, WM831X_GPIO1_CONTROL + irq, 417 WM831X_GPN_INT_MODE | WM831X_GPN_POL, val); 418} 419 420static struct irq_chip wm831x_irq_chip = { 421 .name = "wm831x", 422 .bus_lock = wm831x_irq_lock, 423 .bus_sync_unlock = wm831x_irq_sync_unlock, 424 .mask = wm831x_irq_mask, 425 .unmask = wm831x_irq_unmask, 426 .set_type = wm831x_irq_set_type, 427}; 428 429/* The processing of the primary interrupt occurs in a thread so that 430 * we can interact with the device over I2C or SPI. */ 431static irqreturn_t wm831x_irq_thread(int irq, void *data) 432{ 433 struct wm831x *wm831x = data; 434 unsigned int i; 435 int primary; 436 int status_regs[WM831X_NUM_IRQ_REGS] = { 0 }; 437 int read[WM831X_NUM_IRQ_REGS] = { 0 }; 438 int *status; 439 440 primary = wm831x_reg_read(wm831x, WM831X_SYSTEM_INTERRUPTS); 441 if (primary < 0) { 442 dev_err(wm831x->dev, "Failed to read system interrupt: %d\n", 443 primary); 444 goto out; 445 } 446 447 for (i = 0; i < ARRAY_SIZE(wm831x_irqs); i++) { 448 int offset = wm831x_irqs[i].reg - 1; 449 450 if (!(primary & wm831x_irqs[i].primary)) 451 continue; 452 453 status = &status_regs[offset]; 454 455 /* Hopefully there should only be one register to read 456 * each time otherwise we ought to do a block read. */ 457 if (!read[offset]) { 458 *status = wm831x_reg_read(wm831x, 459 irq_data_to_status_reg(&wm831x_irqs[i])); 460 if (*status < 0) { 461 dev_err(wm831x->dev, 462 "Failed to read IRQ status: %d\n", 463 *status); 464 goto out; 465 } 466 467 read[offset] = 1; 468 } 469 470 /* Report it if it isn't masked, or forget the status. */ 471 if ((*status & ~wm831x->irq_masks_cur[offset]) 472 & wm831x_irqs[i].mask) 473 handle_nested_irq(wm831x->irq_base + i); 474 else 475 *status &= ~wm831x_irqs[i].mask; 476 } 477 478out: 479 for (i = 0; i < ARRAY_SIZE(status_regs); i++) { 480 if (status_regs[i]) 481 wm831x_reg_write(wm831x, WM831X_INTERRUPT_STATUS_1 + i, 482 status_regs[i]); 483 } 484 485 return IRQ_HANDLED; 486} 487 488int wm831x_irq_init(struct wm831x *wm831x, int irq) 489{ 490 struct wm831x_pdata *pdata = wm831x->dev->platform_data; 491 int i, cur_irq, ret; 492 493 mutex_init(&wm831x->irq_lock); 494 495 if (!irq) { 496 dev_warn(wm831x->dev, 497 "No interrupt specified - functionality limited\n"); 498 return 0; 499 } 500 501 if (!pdata || !pdata->irq_base) { 502 dev_err(wm831x->dev, 503 "No interrupt base specified, no interrupts\n"); 504 return 0; 505 } 506 507 wm831x->irq = irq; 508 wm831x->irq_base = pdata->irq_base; 509 510 /* Mask the individual interrupt sources */ 511 for (i = 0; i < ARRAY_SIZE(wm831x->irq_masks_cur); i++) { 512 wm831x->irq_masks_cur[i] = 0xffff; 513 wm831x->irq_masks_cache[i] = 0xffff; 514 wm831x_reg_write(wm831x, WM831X_INTERRUPT_STATUS_1_MASK + i, 515 0xffff); 516 } 517 518 /* Register them with genirq */ 519 for (cur_irq = wm831x->irq_base; 520 cur_irq < ARRAY_SIZE(wm831x_irqs) + wm831x->irq_base; 521 cur_irq++) { 522 set_irq_chip_data(cur_irq, wm831x); 523 set_irq_chip_and_handler(cur_irq, &wm831x_irq_chip, 524 handle_edge_irq); 525 set_irq_nested_thread(cur_irq, 1); 526 527 /* ARM needs us to explicitly flag the IRQ as valid 528 * and will set them noprobe when we do so. */ 529#ifdef CONFIG_ARM 530 set_irq_flags(cur_irq, IRQF_VALID); 531#else 532 set_irq_noprobe(cur_irq); 533#endif 534 } 535 536 ret = request_threaded_irq(irq, NULL, wm831x_irq_thread, 537 IRQF_TRIGGER_LOW | IRQF_ONESHOT, 538 "wm831x", wm831x); 539 if (ret != 0) { 540 dev_err(wm831x->dev, "Failed to request IRQ %d: %d\n", 541 irq, ret); 542 return ret; 543 } 544 545 /* Enable top level interrupts, we mask at secondary level */ 546 wm831x_reg_write(wm831x, WM831X_SYSTEM_INTERRUPTS_MASK, 0); 547 548 return 0; 549} 550 551void wm831x_irq_exit(struct wm831x *wm831x) 552{ 553 if (wm831x->irq) 554 free_irq(wm831x->irq, wm831x); 555}