All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 4/4] MFD/PCAP: fix irq bottom handler
@ 2009-06-23 15:34 Daniel Ribeiro
  0 siblings, 0 replies; only message in thread
From: Daniel Ribeiro @ 2009-06-23 15:34 UTC (permalink / raw)
  To: Samuel Ortiz; +Cc: linux-kernel, openezx-devel

[-- Attachment #1: Type: text/plain, Size: 2619 bytes --]

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

Signed-off-by: Daniel Ribeiro <drwyrm@gmail.com>

---
 drivers/mfd/ezx-pcap.c |   49 ++++++++++++++++++++++++++---------------------
 1 files changed, 27 insertions(+), 22 deletions(-)

diff --git a/drivers/mfd/ezx-pcap.c b/drivers/mfd/ezx-pcap.c
index c512202..732664f 100644
--- a/drivers/mfd/ezx-pcap.c
+++ b/drivers/mfd/ezx-pcap.c
@@ -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)
-- 
tg: (524551c..) pcap/fix-irq-handler (depends on: pcap/set_ts_bits)

-- 
Daniel Ribeiro

[-- Attachment #2: Esta é uma parte de mensagem assinada digitalmente --]
[-- Type: application/pgp-signature, Size: 197 bytes --]

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2009-06-23 15:34 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-06-23 15:34 [PATCH 4/4] MFD/PCAP: fix irq bottom handler Daniel Ribeiro

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.