|
@@ -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,34 +156,38 @@ static void pcap_isr_work(struct work_struct *work)
|
|
|
u32 msr, isr, int_sel, service;
|
|
|
int irq;
|
|
|
|
|
|
- ezx_pcap_read(pcap, PCAP_REG_MSR, &msr);
|
|
|
- ezx_pcap_read(pcap, PCAP_REG_ISR, &isr);
|
|
|
+ do {
|
|
|
+ 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 */
|
|
|
- if (!(pdata->config & PCAP_SECOND_PORT)) {
|
|
|
- ezx_pcap_read(pcap, PCAP_REG_INT_SEL, &int_sel);
|
|
|
- isr &= ~int_sel;
|
|
|
- }
|
|
|
- ezx_pcap_write(pcap, PCAP_REG_ISR, isr);
|
|
|
+ /* We cant service/ack irqs that are assigned to port 2 */
|
|
|
+ if (!(pdata->config & PCAP_SECOND_PORT)) {
|
|
|
+ ezx_pcap_read(pcap, PCAP_REG_INT_SEL, &int_sel);
|
|
|
+ isr &= ~int_sel;
|
|
|
+ }
|
|
|
|
|
|
- local_irq_disable();
|
|
|
- service = isr & ~msr;
|
|
|
+ ezx_pcap_write(pcap, PCAP_REG_MSR, isr | msr);
|
|
|
+ ezx_pcap_write(pcap, PCAP_REG_ISR, isr);
|
|
|
|
|
|
- for (irq = pcap->irq_base; service; service >>= 1, irq++) {
|
|
|
- if (service & 1) {
|
|
|
- struct irq_desc *desc = irq_to_desc(irq);
|
|
|
+ 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);
|
|
|
|
|
|
- if (WARN(!desc, KERN_WARNING
|
|
|
- "Invalid PCAP IRQ %d\n", irq))
|
|
|
- break;
|
|
|
+ if (WARN(!desc, KERN_WARNING
|
|
|
+ "Invalid PCAP IRQ %d\n", irq))
|
|
|
+ break;
|
|
|
|
|
|
- if (desc->status & IRQ_DISABLED)
|
|
|
- note_interrupt(irq, desc, IRQ_NONE);
|
|
|
- else
|
|
|
- desc->handle_irq(irq, desc);
|
|
|
+ if (desc->status & IRQ_DISABLED)
|
|
|
+ note_interrupt(irq, desc, IRQ_NONE);
|
|
|
+ else
|
|
|
+ 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)
|