Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b1148fd4 authored by Daniel Ribeiro's avatar Daniel Ribeiro Committed by Samuel Ortiz
Browse files

mfd: fix pcap irq bottom handler



Mask interrupts before servicing them and loop while pcap asserts the interrupt
line.

Signed-off-by: default avatarDaniel Ribeiro <drwyrm@gmail.com>
Signed-off-by: default avatarSamuel Ortiz <sameo@linux.intel.com>
parent ecd78cbd
Loading
Loading
Loading
Loading
+27 −22
Original line number Diff line number Diff line
@@ -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)