提交 b1148fd4 编写于 作者: D Daniel Ribeiro 提交者: Samuel Ortiz

mfd: fix pcap irq bottom handler

Mask interrupts before servicing them and loop while pcap asserts the interrupt
line.
Signed-off-by: NDaniel Ribeiro <drwyrm@gmail.com>
Signed-off-by: NSamuel Ortiz <sameo@linux.intel.com>
上级 ecd78cbd
...@@ -17,6 +17,7 @@ ...@@ -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,34 +156,38 @@ static void pcap_isr_work(struct work_struct *work) ...@@ -155,34 +156,38 @@ 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;
ezx_pcap_read(pcap, PCAP_REG_MSR, &msr); do {
ezx_pcap_read(pcap, PCAP_REG_ISR, &isr); ezx_pcap_read(pcap, PCAP_REG_MSR, &msr);
ezx_pcap_read(pcap, PCAP_REG_ISR, &isr);
/* We cant service/ack irqs that are assigned to port 2 */ /* We cant service/ack irqs that are assigned to port 2 */
if (!(pdata->config & PCAP_SECOND_PORT)) { if (!(pdata->config & PCAP_SECOND_PORT)) {
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_ISR, isr);
local_irq_disable(); ezx_pcap_write(pcap, PCAP_REG_MSR, isr | msr);
service = isr & ~msr; ezx_pcap_write(pcap, PCAP_REG_ISR, isr);
for (irq = pcap->irq_base; service; service >>= 1, irq++) { local_irq_disable();
if (service & 1) { service = isr & ~msr;
struct irq_desc *desc = irq_to_desc(irq); for (irq = pcap->irq_base; service; service >>= 1, irq++) {
if (service & 1) {
struct irq_desc *desc = irq_to_desc(irq);
if (WARN(!desc, KERN_WARNING if (WARN(!desc, KERN_WARNING
"Invalid PCAP IRQ %d\n", irq)) "Invalid PCAP IRQ %d\n", irq))
break; break;
if (desc->status & IRQ_DISABLED) if (desc->status & IRQ_DISABLED)
note_interrupt(irq, desc, IRQ_NONE); note_interrupt(irq, desc, IRQ_NONE);
else else
desc->handle_irq(irq, desc); desc->handle_irq(irq, desc);
}
} }
} 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)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册