diff options
Diffstat (limited to 'drivers/mfd/wm831x-irq.c')
-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 6c3408ca2c2..ada1835a545 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 | ||