All of lore.kernel.org
 help / color / mirror / Atom feed
* timbgpio: Add support for interrupt triggering on both flanks
@ 2010-01-20 13:08 Richard Röjfors
  0 siblings, 0 replies; only message in thread
From: Richard Röjfors @ 2010-01-20 13:08 UTC (permalink / raw)
  To: Linux Kernel Mailing List; +Cc: Andrew Morton

This patch introduces support for triggering interrupts on both rising
and falling edge.

This feature requires version 3 or newer of the IP, a version check is done
when triggering on both edges is requested.

Signed-off-by: Richard Röjfors <richard.rojfors@pelagicore.com>
---
diff --git a/drivers/gpio/timbgpio.c b/drivers/gpio/timbgpio.c
index a4d344b..471be03 100644
--- a/drivers/gpio/timbgpio.c
+++ b/drivers/gpio/timbgpio.c
@@ -37,6 +37,8 @@
 #define TGPIO_ICR	0x14
 #define TGPIO_FLR	0x18
 #define TGPIO_LVR	0x1c
+#define TGPIO_VER	0x20
+#define TGPIO_BFLR	0x24

 struct timbgpio {
 	void __iomem		*membase;
@@ -125,17 +127,23 @@ static int timbgpio_irq_type(unsigned irq, unsigned trigger)
 	struct timbgpio *tgpio = get_irq_chip_data(irq);
 	int offset = irq - tgpio->irq_base;
 	unsigned long flags;
-	u32 lvr, flr;
+	u32 lvr, flr, bflr = 0;
+	u32 ver;

 	if (offset < 0 || offset > tgpio->gpio.ngpio)
 		return -EINVAL;

+	ver = ioread32(tgpio->membase + TGPIO_VER);
+
 	spin_lock_irqsave(&tgpio->lock, flags);

 	lvr = ioread32(tgpio->membase + TGPIO_LVR);
 	flr = ioread32(tgpio->membase + TGPIO_FLR);
+	if (ver > 2)
+		bflr = ioread32(tgpio->membase + TGPIO_BFLR);

 	if (trigger & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) {
+		bflr &= ~(1 << offset);
 		flr &= ~(1 << offset);
 		if (trigger & IRQ_TYPE_LEVEL_HIGH)
 			lvr |= 1 << offset;
@@ -143,21 +151,27 @@ static int timbgpio_irq_type(unsigned irq, unsigned trigger)
 			lvr &= ~(1 << offset);
 	}

-	if ((trigger & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH)
-		return -EINVAL;
-	else {
+	if ((trigger & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH) {
+		if (ver < 3)
+			return -EINVAL;
+		else {
+			flr |= 1 << offset;
+			bflr |= 1 << offset;
+		}
+	} else {
+		bflr &= ~(1 << offset);
 		flr |= 1 << offset;
-		/* opposite compared to the datasheet, but it mirrors the
-		 * reality
-		 */
 		if (trigger & IRQ_TYPE_EDGE_FALLING)
-			lvr |= 1 << offset;
-		else
 			lvr &= ~(1 << offset);
+		else
+			lvr |= 1 << offset;
 	}

 	iowrite32(lvr, tgpio->membase + TGPIO_LVR);
 	iowrite32(flr, tgpio->membase + TGPIO_FLR);
+	if (ver > 2)
+		iowrite32(bflr, tgpio->membase + TGPIO_BFLR);
+
 	iowrite32(1 << offset, tgpio->membase + TGPIO_ICR);
 	spin_unlock_irqrestore(&tgpio->lock, flags);



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

only message in thread, other threads:[~2010-01-20 13:23 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-01-20 13:08 timbgpio: Add support for interrupt triggering on both flanks Richard Röjfors

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.