diff options
| -rw-r--r-- | drivers/mfd/wm831x-irq.c | 30 |
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 | ||
| 507 | out: | 512 | out: |
| 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 | ||
