654 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * wm831x-irq.c -- Interrupt controller support for Wolfson WM831x PMICs4 *5 * Copyright 2009 Wolfson Microelectronics PLC.6 *7 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>8 */9 10#include <linux/kernel.h>11#include <linux/module.h>12#include <linux/i2c.h>13#include <linux/irq.h>14#include <linux/mfd/core.h>15#include <linux/interrupt.h>16#include <linux/irqdomain.h>17 18#include <linux/mfd/wm831x/core.h>19#include <linux/mfd/wm831x/pdata.h>20#include <linux/mfd/wm831x/gpio.h>21#include <linux/mfd/wm831x/irq.h>22 23#include <linux/delay.h>24 25struct wm831x_irq_data {26 int primary;27 int reg;28 int mask;29};30 31static struct wm831x_irq_data wm831x_irqs[] = {32 [WM831X_IRQ_TEMP_THW] = {33 .primary = WM831X_TEMP_INT,34 .reg = 1,35 .mask = WM831X_TEMP_THW_EINT,36 },37 [WM831X_IRQ_GPIO_1] = {38 .primary = WM831X_GP_INT,39 .reg = 5,40 .mask = WM831X_GP1_EINT,41 },42 [WM831X_IRQ_GPIO_2] = {43 .primary = WM831X_GP_INT,44 .reg = 5,45 .mask = WM831X_GP2_EINT,46 },47 [WM831X_IRQ_GPIO_3] = {48 .primary = WM831X_GP_INT,49 .reg = 5,50 .mask = WM831X_GP3_EINT,51 },52 [WM831X_IRQ_GPIO_4] = {53 .primary = WM831X_GP_INT,54 .reg = 5,55 .mask = WM831X_GP4_EINT,56 },57 [WM831X_IRQ_GPIO_5] = {58 .primary = WM831X_GP_INT,59 .reg = 5,60 .mask = WM831X_GP5_EINT,61 },62 [WM831X_IRQ_GPIO_6] = {63 .primary = WM831X_GP_INT,64 .reg = 5,65 .mask = WM831X_GP6_EINT,66 },67 [WM831X_IRQ_GPIO_7] = {68 .primary = WM831X_GP_INT,69 .reg = 5,70 .mask = WM831X_GP7_EINT,71 },72 [WM831X_IRQ_GPIO_8] = {73 .primary = WM831X_GP_INT,74 .reg = 5,75 .mask = WM831X_GP8_EINT,76 },77 [WM831X_IRQ_GPIO_9] = {78 .primary = WM831X_GP_INT,79 .reg = 5,80 .mask = WM831X_GP9_EINT,81 },82 [WM831X_IRQ_GPIO_10] = {83 .primary = WM831X_GP_INT,84 .reg = 5,85 .mask = WM831X_GP10_EINT,86 },87 [WM831X_IRQ_GPIO_11] = {88 .primary = WM831X_GP_INT,89 .reg = 5,90 .mask = WM831X_GP11_EINT,91 },92 [WM831X_IRQ_GPIO_12] = {93 .primary = WM831X_GP_INT,94 .reg = 5,95 .mask = WM831X_GP12_EINT,96 },97 [WM831X_IRQ_GPIO_13] = {98 .primary = WM831X_GP_INT,99 .reg = 5,100 .mask = WM831X_GP13_EINT,101 },102 [WM831X_IRQ_GPIO_14] = {103 .primary = WM831X_GP_INT,104 .reg = 5,105 .mask = WM831X_GP14_EINT,106 },107 [WM831X_IRQ_GPIO_15] = {108 .primary = WM831X_GP_INT,109 .reg = 5,110 .mask = WM831X_GP15_EINT,111 },112 [WM831X_IRQ_GPIO_16] = {113 .primary = WM831X_GP_INT,114 .reg = 5,115 .mask = WM831X_GP16_EINT,116 },117 [WM831X_IRQ_ON] = {118 .primary = WM831X_ON_PIN_INT,119 .reg = 1,120 .mask = WM831X_ON_PIN_EINT,121 },122 [WM831X_IRQ_PPM_SYSLO] = {123 .primary = WM831X_PPM_INT,124 .reg = 1,125 .mask = WM831X_PPM_SYSLO_EINT,126 },127 [WM831X_IRQ_PPM_PWR_SRC] = {128 .primary = WM831X_PPM_INT,129 .reg = 1,130 .mask = WM831X_PPM_PWR_SRC_EINT,131 },132 [WM831X_IRQ_PPM_USB_CURR] = {133 .primary = WM831X_PPM_INT,134 .reg = 1,135 .mask = WM831X_PPM_USB_CURR_EINT,136 },137 [WM831X_IRQ_WDOG_TO] = {138 .primary = WM831X_WDOG_INT,139 .reg = 1,140 .mask = WM831X_WDOG_TO_EINT,141 },142 [WM831X_IRQ_RTC_PER] = {143 .primary = WM831X_RTC_INT,144 .reg = 1,145 .mask = WM831X_RTC_PER_EINT,146 },147 [WM831X_IRQ_RTC_ALM] = {148 .primary = WM831X_RTC_INT,149 .reg = 1,150 .mask = WM831X_RTC_ALM_EINT,151 },152 [WM831X_IRQ_CHG_BATT_HOT] = {153 .primary = WM831X_CHG_INT,154 .reg = 2,155 .mask = WM831X_CHG_BATT_HOT_EINT,156 },157 [WM831X_IRQ_CHG_BATT_COLD] = {158 .primary = WM831X_CHG_INT,159 .reg = 2,160 .mask = WM831X_CHG_BATT_COLD_EINT,161 },162 [WM831X_IRQ_CHG_BATT_FAIL] = {163 .primary = WM831X_CHG_INT,164 .reg = 2,165 .mask = WM831X_CHG_BATT_FAIL_EINT,166 },167 [WM831X_IRQ_CHG_OV] = {168 .primary = WM831X_CHG_INT,169 .reg = 2,170 .mask = WM831X_CHG_OV_EINT,171 },172 [WM831X_IRQ_CHG_END] = {173 .primary = WM831X_CHG_INT,174 .reg = 2,175 .mask = WM831X_CHG_END_EINT,176 },177 [WM831X_IRQ_CHG_TO] = {178 .primary = WM831X_CHG_INT,179 .reg = 2,180 .mask = WM831X_CHG_TO_EINT,181 },182 [WM831X_IRQ_CHG_MODE] = {183 .primary = WM831X_CHG_INT,184 .reg = 2,185 .mask = WM831X_CHG_MODE_EINT,186 },187 [WM831X_IRQ_CHG_START] = {188 .primary = WM831X_CHG_INT,189 .reg = 2,190 .mask = WM831X_CHG_START_EINT,191 },192 [WM831X_IRQ_TCHDATA] = {193 .primary = WM831X_TCHDATA_INT,194 .reg = 1,195 .mask = WM831X_TCHDATA_EINT,196 },197 [WM831X_IRQ_TCHPD] = {198 .primary = WM831X_TCHPD_INT,199 .reg = 1,200 .mask = WM831X_TCHPD_EINT,201 },202 [WM831X_IRQ_AUXADC_DATA] = {203 .primary = WM831X_AUXADC_INT,204 .reg = 1,205 .mask = WM831X_AUXADC_DATA_EINT,206 },207 [WM831X_IRQ_AUXADC_DCOMP1] = {208 .primary = WM831X_AUXADC_INT,209 .reg = 1,210 .mask = WM831X_AUXADC_DCOMP1_EINT,211 },212 [WM831X_IRQ_AUXADC_DCOMP2] = {213 .primary = WM831X_AUXADC_INT,214 .reg = 1,215 .mask = WM831X_AUXADC_DCOMP2_EINT,216 },217 [WM831X_IRQ_AUXADC_DCOMP3] = {218 .primary = WM831X_AUXADC_INT,219 .reg = 1,220 .mask = WM831X_AUXADC_DCOMP3_EINT,221 },222 [WM831X_IRQ_AUXADC_DCOMP4] = {223 .primary = WM831X_AUXADC_INT,224 .reg = 1,225 .mask = WM831X_AUXADC_DCOMP4_EINT,226 },227 [WM831X_IRQ_CS1] = {228 .primary = WM831X_CS_INT,229 .reg = 2,230 .mask = WM831X_CS1_EINT,231 },232 [WM831X_IRQ_CS2] = {233 .primary = WM831X_CS_INT,234 .reg = 2,235 .mask = WM831X_CS2_EINT,236 },237 [WM831X_IRQ_HC_DC1] = {238 .primary = WM831X_HC_INT,239 .reg = 4,240 .mask = WM831X_HC_DC1_EINT,241 },242 [WM831X_IRQ_HC_DC2] = {243 .primary = WM831X_HC_INT,244 .reg = 4,245 .mask = WM831X_HC_DC2_EINT,246 },247 [WM831X_IRQ_UV_LDO1] = {248 .primary = WM831X_UV_INT,249 .reg = 3,250 .mask = WM831X_UV_LDO1_EINT,251 },252 [WM831X_IRQ_UV_LDO2] = {253 .primary = WM831X_UV_INT,254 .reg = 3,255 .mask = WM831X_UV_LDO2_EINT,256 },257 [WM831X_IRQ_UV_LDO3] = {258 .primary = WM831X_UV_INT,259 .reg = 3,260 .mask = WM831X_UV_LDO3_EINT,261 },262 [WM831X_IRQ_UV_LDO4] = {263 .primary = WM831X_UV_INT,264 .reg = 3,265 .mask = WM831X_UV_LDO4_EINT,266 },267 [WM831X_IRQ_UV_LDO5] = {268 .primary = WM831X_UV_INT,269 .reg = 3,270 .mask = WM831X_UV_LDO5_EINT,271 },272 [WM831X_IRQ_UV_LDO6] = {273 .primary = WM831X_UV_INT,274 .reg = 3,275 .mask = WM831X_UV_LDO6_EINT,276 },277 [WM831X_IRQ_UV_LDO7] = {278 .primary = WM831X_UV_INT,279 .reg = 3,280 .mask = WM831X_UV_LDO7_EINT,281 },282 [WM831X_IRQ_UV_LDO8] = {283 .primary = WM831X_UV_INT,284 .reg = 3,285 .mask = WM831X_UV_LDO8_EINT,286 },287 [WM831X_IRQ_UV_LDO9] = {288 .primary = WM831X_UV_INT,289 .reg = 3,290 .mask = WM831X_UV_LDO9_EINT,291 },292 [WM831X_IRQ_UV_LDO10] = {293 .primary = WM831X_UV_INT,294 .reg = 3,295 .mask = WM831X_UV_LDO10_EINT,296 },297 [WM831X_IRQ_UV_DC1] = {298 .primary = WM831X_UV_INT,299 .reg = 4,300 .mask = WM831X_UV_DC1_EINT,301 },302 [WM831X_IRQ_UV_DC2] = {303 .primary = WM831X_UV_INT,304 .reg = 4,305 .mask = WM831X_UV_DC2_EINT,306 },307 [WM831X_IRQ_UV_DC3] = {308 .primary = WM831X_UV_INT,309 .reg = 4,310 .mask = WM831X_UV_DC3_EINT,311 },312 [WM831X_IRQ_UV_DC4] = {313 .primary = WM831X_UV_INT,314 .reg = 4,315 .mask = WM831X_UV_DC4_EINT,316 },317};318 319static inline int irq_data_to_status_reg(struct wm831x_irq_data *irq_data)320{321 return WM831X_INTERRUPT_STATUS_1 - 1 + irq_data->reg;322}323 324static inline struct wm831x_irq_data *irq_to_wm831x_irq(struct wm831x *wm831x,325 int irq)326{327 return &wm831x_irqs[irq];328}329 330static void wm831x_irq_lock(struct irq_data *data)331{332 struct wm831x *wm831x = irq_data_get_irq_chip_data(data);333 334 mutex_lock(&wm831x->irq_lock);335}336 337static void wm831x_irq_sync_unlock(struct irq_data *data)338{339 struct wm831x *wm831x = irq_data_get_irq_chip_data(data);340 int i;341 342 for (i = 0; i < ARRAY_SIZE(wm831x->gpio_update); i++) {343 if (wm831x->gpio_update[i]) {344 wm831x_set_bits(wm831x, WM831X_GPIO1_CONTROL + i,345 WM831X_GPN_INT_MODE | WM831X_GPN_POL,346 wm831x->gpio_update[i]);347 wm831x->gpio_update[i] = 0;348 }349 }350 351 for (i = 0; i < ARRAY_SIZE(wm831x->irq_masks_cur); i++) {352 /* If there's been a change in the mask write it back353 * to the hardware. */354 if (wm831x->irq_masks_cur[i] != wm831x->irq_masks_cache[i]) {355 dev_dbg(wm831x->dev, "IRQ mask sync: %x = %x\n",356 WM831X_INTERRUPT_STATUS_1_MASK + i,357 wm831x->irq_masks_cur[i]);358 359 wm831x->irq_masks_cache[i] = wm831x->irq_masks_cur[i];360 wm831x_reg_write(wm831x,361 WM831X_INTERRUPT_STATUS_1_MASK + i,362 wm831x->irq_masks_cur[i]);363 }364 }365 366 mutex_unlock(&wm831x->irq_lock);367}368 369static void wm831x_irq_enable(struct irq_data *data)370{371 struct wm831x *wm831x = irq_data_get_irq_chip_data(data);372 struct wm831x_irq_data *irq_data = irq_to_wm831x_irq(wm831x,373 data->hwirq);374 375 wm831x->irq_masks_cur[irq_data->reg - 1] &= ~irq_data->mask;376}377 378static void wm831x_irq_disable(struct irq_data *data)379{380 struct wm831x *wm831x = irq_data_get_irq_chip_data(data);381 struct wm831x_irq_data *irq_data = irq_to_wm831x_irq(wm831x,382 data->hwirq);383 384 wm831x->irq_masks_cur[irq_data->reg - 1] |= irq_data->mask;385}386 387static int wm831x_irq_set_type(struct irq_data *data, unsigned int type)388{389 struct wm831x *wm831x = irq_data_get_irq_chip_data(data);390 int irq;391 392 irq = data->hwirq;393 394 if (irq < WM831X_IRQ_GPIO_1 || irq > WM831X_IRQ_GPIO_11) {395 /* Ignore internal-only IRQs */396 if (irq >= 0 && irq < WM831X_NUM_IRQS)397 return 0;398 else399 return -EINVAL;400 }401 402 /* Rebase the IRQ into the GPIO range so we've got a sensible array403 * index.404 */405 irq -= WM831X_IRQ_GPIO_1;406 407 /* We set the high bit to flag that we need an update; don't408 * do the update here as we can be called with the bus lock409 * held.410 */411 wm831x->gpio_level_low[irq] = false;412 wm831x->gpio_level_high[irq] = false;413 switch (type) {414 case IRQ_TYPE_EDGE_BOTH:415 wm831x->gpio_update[irq] = 0x10000 | WM831X_GPN_INT_MODE;416 break;417 case IRQ_TYPE_EDGE_RISING:418 wm831x->gpio_update[irq] = 0x10000 | WM831X_GPN_POL;419 break;420 case IRQ_TYPE_EDGE_FALLING:421 wm831x->gpio_update[irq] = 0x10000;422 break;423 case IRQ_TYPE_LEVEL_HIGH:424 wm831x->gpio_update[irq] = 0x10000 | WM831X_GPN_POL;425 wm831x->gpio_level_high[irq] = true;426 break;427 case IRQ_TYPE_LEVEL_LOW:428 wm831x->gpio_update[irq] = 0x10000;429 wm831x->gpio_level_low[irq] = true;430 break;431 default:432 return -EINVAL;433 }434 435 return 0;436}437 438static struct irq_chip wm831x_irq_chip = {439 .name = "wm831x",440 .irq_bus_lock = wm831x_irq_lock,441 .irq_bus_sync_unlock = wm831x_irq_sync_unlock,442 .irq_disable = wm831x_irq_disable,443 .irq_enable = wm831x_irq_enable,444 .irq_set_type = wm831x_irq_set_type,445};446 447/* The processing of the primary interrupt occurs in a thread so that448 * we can interact with the device over I2C or SPI. */449static irqreturn_t wm831x_irq_thread(int irq, void *data)450{451 struct wm831x *wm831x = data;452 unsigned int i;453 int primary, status_addr, ret;454 int status_regs[WM831X_NUM_IRQ_REGS] = { 0 };455 int read[WM831X_NUM_IRQ_REGS] = { 0 };456 int *status;457 458 primary = wm831x_reg_read(wm831x, WM831X_SYSTEM_INTERRUPTS);459 if (primary < 0) {460 dev_err(wm831x->dev, "Failed to read system interrupt: %d\n",461 primary);462 goto out;463 }464 465 /* The touch interrupts are visible in the primary register as466 * an optimisation; open code this to avoid complicating the467 * main handling loop and so we can also skip iterating the468 * descriptors.469 */470 if (primary & WM831X_TCHPD_INT)471 handle_nested_irq(irq_find_mapping(wm831x->irq_domain,472 WM831X_IRQ_TCHPD));473 if (primary & WM831X_TCHDATA_INT)474 handle_nested_irq(irq_find_mapping(wm831x->irq_domain,475 WM831X_IRQ_TCHDATA));476 primary &= ~(WM831X_TCHDATA_EINT | WM831X_TCHPD_EINT);477 478 for (i = 0; i < ARRAY_SIZE(wm831x_irqs); i++) {479 int offset = wm831x_irqs[i].reg - 1;480 481 if (!(primary & wm831x_irqs[i].primary))482 continue;483 484 status = &status_regs[offset];485 486 /* Hopefully there should only be one register to read487 * each time otherwise we ought to do a block read. */488 if (!read[offset]) {489 status_addr = irq_data_to_status_reg(&wm831x_irqs[i]);490 491 *status = wm831x_reg_read(wm831x, status_addr);492 if (*status < 0) {493 dev_err(wm831x->dev,494 "Failed to read IRQ status: %d\n",495 *status);496 goto out;497 }498 499 read[offset] = 1;500 501 /* Ignore any bits that we don't think are masked */502 *status &= ~wm831x->irq_masks_cur[offset];503 504 /* Acknowledge now so we don't miss505 * notifications while we handle.506 */507 wm831x_reg_write(wm831x, status_addr, *status);508 }509 510 if (*status & wm831x_irqs[i].mask)511 handle_nested_irq(irq_find_mapping(wm831x->irq_domain,512 i));513 514 /* Simulate an edge triggered IRQ by polling the input515 * status. This is sucky but improves interoperability.516 */517 if (primary == WM831X_GP_INT &&518 wm831x->gpio_level_high[i - WM831X_IRQ_GPIO_1]) {519 ret = wm831x_reg_read(wm831x, WM831X_GPIO_LEVEL);520 while (ret & 1 << (i - WM831X_IRQ_GPIO_1)) {521 handle_nested_irq(irq_find_mapping(wm831x->irq_domain,522 i));523 ret = wm831x_reg_read(wm831x,524 WM831X_GPIO_LEVEL);525 }526 }527 528 if (primary == WM831X_GP_INT &&529 wm831x->gpio_level_low[i - WM831X_IRQ_GPIO_1]) {530 ret = wm831x_reg_read(wm831x, WM831X_GPIO_LEVEL);531 while (!(ret & 1 << (i - WM831X_IRQ_GPIO_1))) {532 handle_nested_irq(irq_find_mapping(wm831x->irq_domain,533 i));534 ret = wm831x_reg_read(wm831x,535 WM831X_GPIO_LEVEL);536 }537 }538 }539 540out:541 return IRQ_HANDLED;542}543 544static int wm831x_irq_map(struct irq_domain *h, unsigned int virq,545 irq_hw_number_t hw)546{547 irq_set_chip_data(virq, h->host_data);548 irq_set_chip_and_handler(virq, &wm831x_irq_chip, handle_edge_irq);549 irq_set_nested_thread(virq, 1);550 irq_set_noprobe(virq);551 552 return 0;553}554 555static const struct irq_domain_ops wm831x_irq_domain_ops = {556 .map = wm831x_irq_map,557 .xlate = irq_domain_xlate_twocell,558};559 560int wm831x_irq_init(struct wm831x *wm831x, int irq)561{562 struct wm831x_pdata *pdata = &wm831x->pdata;563 struct irq_domain *domain;564 int i, ret, irq_base;565 566 mutex_init(&wm831x->irq_lock);567 568 /* Mask the individual interrupt sources */569 for (i = 0; i < ARRAY_SIZE(wm831x->irq_masks_cur); i++) {570 wm831x->irq_masks_cur[i] = 0xffff;571 wm831x->irq_masks_cache[i] = 0xffff;572 wm831x_reg_write(wm831x, WM831X_INTERRUPT_STATUS_1_MASK + i,573 0xffff);574 }575 576 /* Try to dynamically allocate IRQs if no base is specified */577 if (pdata->irq_base) {578 irq_base = irq_alloc_descs(pdata->irq_base, 0,579 WM831X_NUM_IRQS, 0);580 if (irq_base < 0) {581 dev_warn(wm831x->dev, "Failed to allocate IRQs: %d\n",582 irq_base);583 irq_base = 0;584 }585 } else {586 irq_base = 0;587 }588 589 if (irq_base)590 domain = irq_domain_add_legacy(wm831x->dev->of_node,591 ARRAY_SIZE(wm831x_irqs),592 irq_base, 0,593 &wm831x_irq_domain_ops,594 wm831x);595 else596 domain = irq_domain_add_linear(wm831x->dev->of_node,597 ARRAY_SIZE(wm831x_irqs),598 &wm831x_irq_domain_ops,599 wm831x);600 601 if (!domain) {602 dev_warn(wm831x->dev, "Failed to allocate IRQ domain\n");603 return -EINVAL;604 }605 606 if (pdata->irq_cmos)607 i = 0;608 else609 i = WM831X_IRQ_OD;610 611 wm831x_set_bits(wm831x, WM831X_IRQ_CONFIG,612 WM831X_IRQ_OD, i);613 614 wm831x->irq = irq;615 wm831x->irq_domain = domain;616 617 if (irq) {618 /* Try to flag /IRQ as a wake source; there are a number of619 * unconditional wake sources in the PMIC so this isn't620 * conditional but we don't actually care *too* much if it621 * fails.622 */623 ret = enable_irq_wake(irq);624 if (ret != 0) {625 dev_warn(wm831x->dev,626 "Can't enable IRQ as wake source: %d\n",627 ret);628 }629 630 ret = request_threaded_irq(irq, NULL, wm831x_irq_thread,631 IRQF_TRIGGER_LOW | IRQF_ONESHOT,632 "wm831x", wm831x);633 if (ret != 0) {634 dev_err(wm831x->dev, "Failed to request IRQ %d: %d\n",635 irq, ret);636 return ret;637 }638 } else {639 dev_warn(wm831x->dev,640 "No interrupt specified - functionality limited\n");641 }642 643 /* Enable top level interrupts, we mask at secondary level */644 wm831x_reg_write(wm831x, WM831X_SYSTEM_INTERRUPTS_MASK, 0);645 646 return 0;647}648 649void wm831x_irq_exit(struct wm831x *wm831x)650{651 if (wm831x->irq)652 free_irq(wm831x->irq, wm831x);653}654