aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mfd
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mfd')
-rw-r--r--drivers/mfd/wm831x-irq.c30
1 files changed, 13 insertions, 17 deletions
diff --git a/drivers/mfd/wm831x-irq.c b/drivers/mfd/wm831x-irq.c
index 6c3408ca2c2d..ada1835a5455 100644
--- a/drivers/mfd/wm831x-irq.c
+++ b/drivers/mfd/wm831x-irq.c
@@ -449,7 +449,7 @@ static irqreturn_t wm831x_irq_thread(int irq, void *data)
449{ 449{
450 struct wm831x *wm831x = data; 450 struct wm831x *wm831x = data;
451 unsigned int i; 451 unsigned int i;
452 int primary; 452 int primary, status_addr;
453 int status_regs[WM831X_NUM_IRQ_REGS] = { 0 }; 453 int status_regs[WM831X_NUM_IRQ_REGS] = { 0 };
454 int read[WM831X_NUM_IRQ_REGS] = { 0 }; 454 int read[WM831X_NUM_IRQ_REGS] = { 0 };
455 int *status; 455 int *status;
@@ -484,8 +484,9 @@ static irqreturn_t wm831x_irq_thread(int irq, void *data)
484 /* Hopefully there should only be one register to read 484 /* Hopefully there should only be one register to read
485 * each time otherwise we ought to do a block read. */ 485 * each time otherwise we ought to do a block read. */
486 if (!read[offset]) { 486 if (!read[offset]) {
487 *status = wm831x_reg_read(wm831x, 487 status_addr = irq_data_to_status_reg(&wm831x_irqs[i]);
488 irq_data_to_status_reg(&wm831x_irqs[i])); 488
489 *status = wm831x_reg_read(wm831x, status_addr);
489 if (*status < 0) { 490 if (*status < 0) {
490 dev_err(wm831x->dev, 491 dev_err(wm831x->dev,
491 "Failed to read IRQ status: %d\n", 492 "Failed to read IRQ status: %d\n",
@@ -494,26 +495,21 @@ static irqreturn_t wm831x_irq_thread(int irq, void *data)
494 } 495 }
495 496
496 read[offset] = 1; 497 read[offset] = 1;
498
499 /* Ignore any bits that we don't think are masked */
500 *status &= ~wm831x->irq_masks_cur[offset];
501
502 /* Acknowledge now so we don't miss
503 * notifications while we handle.
504 */
505 wm831x_reg_write(wm831x, status_addr, *status);
497 } 506 }
498 507
499 /* Report it if it isn't masked, or forget the status. */ 508 if (*status & wm831x_irqs[i].mask)
500 if ((*status & ~wm831x->irq_masks_cur[offset])
501 & wm831x_irqs[i].mask)
502 handle_nested_irq(wm831x->irq_base + i); 509 handle_nested_irq(wm831x->irq_base + i);
503 else
504 *status &= ~wm831x_irqs[i].mask;
505 } 510 }
506 511
507out: 512out:
508 /* Touchscreen interrupts are handled specially in the driver */
509 status_regs[0] &= ~(WM831X_TCHDATA_EINT | WM831X_TCHPD_EINT);
510
511 for (i = 0; i < ARRAY_SIZE(status_regs); i++) {
512 if (status_regs[i])
513 wm831x_reg_write(wm831x, WM831X_INTERRUPT_STATUS_1 + i,
514 status_regs[i]);
515 }
516
517 return IRQ_HANDLED; 513 return IRQ_HANDLED;
518} 514}
519 515