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/irq.h>
|
||||||
#include <linux/mfd/ezx-pcap.h>
|
#include <linux/mfd/ezx-pcap.h>
|
||||||
#include <linux/spi/spi.h>
|
#include <linux/spi/spi.h>
|
||||||
|
#include <linux/gpio.h>
|
||||||
|
|
||||||
#define PCAP_ADC_MAXQ 8
|
#define PCAP_ADC_MAXQ 8
|
||||||
struct pcap_adc_request {
|
struct pcap_adc_request {
|
||||||
@@ -155,6 +156,7 @@ static void pcap_isr_work(struct work_struct *work)
|
|||||||
u32 msr, isr, int_sel, service;
|
u32 msr, isr, int_sel, service;
|
||||||
int irq;
|
int irq;
|
||||||
|
|
||||||
|
do {
|
||||||
ezx_pcap_read(pcap, PCAP_REG_MSR, &msr);
|
ezx_pcap_read(pcap, PCAP_REG_MSR, &msr);
|
||||||
ezx_pcap_read(pcap, PCAP_REG_ISR, &isr);
|
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);
|
ezx_pcap_read(pcap, PCAP_REG_INT_SEL, &int_sel);
|
||||||
isr &= ~int_sel;
|
isr &= ~int_sel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ezx_pcap_write(pcap, PCAP_REG_MSR, isr | msr);
|
||||||
ezx_pcap_write(pcap, PCAP_REG_ISR, isr);
|
ezx_pcap_write(pcap, PCAP_REG_ISR, isr);
|
||||||
|
|
||||||
local_irq_disable();
|
local_irq_disable();
|
||||||
service = isr & ~msr;
|
service = isr & ~msr;
|
||||||
|
|
||||||
for (irq = pcap->irq_base; service; service >>= 1, irq++) {
|
for (irq = pcap->irq_base; service; service >>= 1, irq++) {
|
||||||
if (service & 1) {
|
if (service & 1) {
|
||||||
struct irq_desc *desc = irq_to_desc(irq);
|
struct irq_desc *desc = irq_to_desc(irq);
|
||||||
@@ -183,6 +186,8 @@ static void pcap_isr_work(struct work_struct *work)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
local_irq_enable();
|
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)
|
static void pcap_irq_handler(unsigned int irq, struct irq_desc *desc)
|
||||||
|
Reference in New Issue
Block a user