LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Christophe Leroy <christophe.leroy@c-s.fr>
To: Benjamin Herrenschmidt <benh@kernel.crashing.org>,
	Paul Mackerras <paulus@samba.org>,
	Vitaly Bordug <vitb@kernel.crashing.org>,
	Marcelo Tosatti <marcelo@kvack.org>,
	Thomas Gleixner <tglx@linutronix.de>
Cc: linuxppc-dev@lists.ozlabs.org, linux-kernel@vger.kernel.org
Subject: [PATCH] Handling of IRQ in MPC8xx GPIO
Date: Thu, 21 Feb 2013 17:32:36 +0100	[thread overview]
Message-ID: <201302211632.r1LGWaRr025445@localhost.localdomain> (raw)

This patch allows the use IRQ to notify the change of GPIO status on the MPC8xx
CPM IO ports. This then allows to associate IRQs to GPIOs in the Device Tree. Ex:
	CPM1_PIO_C: gpio-controller@960 {
		#gpio-cells = <2>;
		compatible = "fsl,cpm1-pario-bank-c";
		reg = <0x960 0x10>;
		interrupts = <255 255 255 255 1 2 6 9 10 11 14 15 23 24 26 31>;
		interrupt-parent = <&CPM_PIC>;
		gpio-controller;
	};

Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>

diff -ur linux-3.7.9/arch/powerpc/include/asm/cpm1.h linux/arch/powerpc/include/asm/cpm1.h
--- linux-3.7.9/arch/powerpc/include/asm/cpm1.h	2013-02-17 19:53:32.000000000 +0100
+++ linux/arch/powerpc/include/asm/cpm1.h	2012-11-03 03:18:35.000000000 +0100
@@ -560,6 +560,8 @@
 #define CPM_PIN_SECONDARY 2
 #define CPM_PIN_GPIO      4
 #define CPM_PIN_OPENDRAIN 8
+#define CPM_PIN_FALLEDGE  16
+#define CPM_PIN_ANYEDGE   0
 
 enum cpm_port {
 	CPM_PORTA,
diff -ur linux-3.7.9/arch/powerpc/sysdev/cpm1.c linux/arch/powerpc/sysdev/cpm1.c
--- linux-3.7.9/arch/powerpc/sysdev/cpm1.c	2013-02-17 19:53:32.000000000 +0100
+++ linux/arch/powerpc/sysdev/cpm1.c	2013-02-21 15:52:51.000000000 +0100
@@ -375,6 +375,10 @@
 			setbits16(&iop->odr_sor, pin);
 		else
 			clrbits16(&iop->odr_sor, pin);
+		if (flags & CPM_PIN_FALLEDGE)
+			setbits16(&iop->intr, pin);
+		else
+			clrbits16(&iop->intr, pin);
 	}
 }
 
@@ -526,6 +530,9 @@
 
 	/* shadowed data register to clear/set bits safely */
 	u16 cpdata;
+
+	/* IRQ associated with Pins when relevant */
+	int irq[16];
 };
 
 static inline struct cpm1_gpio16_chip *
@@ -581,6 +588,30 @@
 	spin_unlock_irqrestore(&cpm1_gc->lock, flags);
 }
 
+static int __cpm1_gpio16_to_irq(struct of_mm_gpio_chip *mm_gc,
+		unsigned int gpio)
+{
+	struct cpm1_gpio16_chip *cpm1_gc = to_cpm1_gpio16_chip(mm_gc);
+
+	return cpm1_gc->irq[gpio] ? cpm1_gc->irq[gpio] : -ENXIO;
+}
+
+static int cpm1_gpio16_to_irq(struct gpio_chip *gc, unsigned int gpio)
+{
+	struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
+	struct cpm1_gpio16_chip *cpm1_gc = to_cpm1_gpio16_chip(mm_gc);
+	unsigned long flags;
+	int ret;
+
+	spin_lock_irqsave(&cpm1_gc->lock, flags);
+
+	ret = __cpm1_gpio16_to_irq(mm_gc, gpio);
+
+	spin_unlock_irqrestore(&cpm1_gc->lock, flags);
+
+	return ret;
+}
+
 static int cpm1_gpio16_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
 {
 	struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
@@ -621,6 +652,7 @@
 	struct cpm1_gpio16_chip *cpm1_gc;
 	struct of_mm_gpio_chip *mm_gc;
 	struct gpio_chip *gc;
+	int i;
 
 	cpm1_gc = kzalloc(sizeof(*cpm1_gc), GFP_KERNEL);
 	if (!cpm1_gc)
@@ -628,6 +660,9 @@
 
 	spin_lock_init(&cpm1_gc->lock);
 
+	for (i = 0; i < 16; i++)
+		cpm1_gc->irq[i] = irq_of_parse_and_map(np, i);
+
 	mm_gc = &cpm1_gc->mm_gc;
 	gc = &mm_gc->gc;
 
@@ -637,6 +672,7 @@
 	gc->direction_output = cpm1_gpio16_dir_out;
 	gc->get = cpm1_gpio16_get;
 	gc->set = cpm1_gpio16_set;
+	gc->to_irq = cpm1_gpio16_to_irq;
 
 	return of_mm_gpiochip_add(np, mm_gc);
 }
diff -ur linux-3.7.9/kernel/irq/irqdomain.c linux/kernel/irq/irqdomain.c
--- linux-3.7.9/kernel/irq/irqdomain.c	2013-02-17 19:53:32.000000000 +0100
+++ linux/kernel/irq/irqdomain.c	2012-12-13 19:52:38.000000000 +0100
@@ -763,7 +763,8 @@
 	BUG_ON(domain->revmap_type != IRQ_DOMAIN_MAP_LINEAR);
 
 	/* Check revmap bounds; complain if exceeded */
-	if (WARN_ON(hwirq >= domain->revmap_data.linear.size))
+	/* 255 is a trick to allow UNDEF value in DTS */
+	if (hwirq == 255 || WARN_ON(hwirq >= domain->revmap_data.linear.size))
 		return 0;
 
 	return domain->revmap_data.linear.revmap[hwirq];

             reply	other threads:[~2013-02-21 17:30 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-02-21 16:32 Christophe Leroy [this message]
2013-06-04 21:59 ` Handling of IRQ in MPC8xx GPIO Scott Wood

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=201302211632.r1LGWaRr025445@localhost.localdomain \
    --to=christophe.leroy@c-s.fr \
    --cc=benh@kernel.crashing.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linuxppc-dev@lists.ozlabs.org \
    --cc=marcelo@kvack.org \
    --cc=paulus@samba.org \
    --cc=tglx@linutronix.de \
    --cc=vitb@kernel.crashing.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox