mfd: fix pcap irq bottom handler
Mask interrupts before servicing them and loop while pcap asserts the interrupt line. Signed-off-by: Daniel Ribeiro <drwyrm@gmail.com> Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
This commit is contained in:
committed by
Samuel Ortiz
parent
ecd78cbdb9
commit
b1148fd46c
@@ -17,6 +17,7 @@
|
||||
#include <linux/irq.h>
|
||||
#include <linux/mfd/ezx-pcap.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/gpio.h>
|
||||
|
||||
#define PCAP_ADC_MAXQ 8
|
||||
struct pcap_adc_request {
|
||||
@@ -155,6 +156,7 @@ static void pcap_isr_work(struct work_struct *work)
|
||||
u32 msr, isr, int_sel, service;
|
||||
int irq;
|
||||
|
||||
do {
|
||||
ezx_pcap_read(pcap, PCAP_REG_MSR, &msr);
|
||||
ezx_pcap_read(pcap, PCAP_REG_ISR, &isr);
|
||||
|
||||
@@ -163,11 +165,12 @@ static void pcap_isr_work(struct work_struct *work)
|
||||
ezx_pcap_read(pcap, PCAP_REG_INT_SEL, &int_sel);
|
||||
isr &= ~int_sel;
|
||||
}
|
||||
|
||||
ezx_pcap_write(pcap, PCAP_REG_MSR, isr | msr);
|
||||
ezx_pcap_write(pcap, PCAP_REG_ISR, isr);
|
||||
|
||||
local_irq_disable();
|
||||
service = isr & ~msr;
|
||||
|
||||
for (irq = pcap->irq_base; service; service >>= 1, irq++) {
|
||||
if (service & 1) {
|
||||
struct irq_desc *desc = irq_to_desc(irq);
|
||||
@@ -183,6 +186,8 @@ static void pcap_isr_work(struct work_struct *work)
|
||||
}
|
||||
}
|
||||
local_irq_enable();
|
||||
ezx_pcap_write(pcap, PCAP_REG_MSR, pcap->msr);
|
||||
} while (gpio_get_value(irq_to_gpio(pcap->spi->irq)));
|
||||
}
|
||||
|
||||
static void pcap_irq_handler(unsigned int irq, struct irq_desc *desc)
|
||||
|
Reference in New Issue
Block a user