Received: from mail.onstor.com (66.201.51.107) by exch1.onstor.net
 (10.0.0.225) with Microsoft SMTP Server id 8.1.311.2; Tue, 23 Dec 2008
 12:00:11 -0800
Received: from chiesmta2-2.messageone.com ([216.203.30.55]) by mail.onstor.com
 with Microsoft SMTPSVC(6.0.3790.3959);	 Tue, 23 Dec 2008 12:00:10 -0800
Received: from ftp.linux-mips.org (ftp.linux-mips.org [213.58.128.207])	by
 chiesmta2-2.messageone.com (8.13.8/8.13.8) with ESMTP id mBNK0AqT031186	for
 <andy.sharp@onstor.com>; Tue, 23 Dec 2008 14:00:11 -0600
Received: from localhost.localdomain ([127.0.0.1]:63464 "EHLO
	ftp.linux-mips.org") by ftp.linux-mips.org with ESMTP	id S24208003AbYLWT7t
 (ORCPT <rfc822;andy.sharp@onstor.com>);	Tue, 23 Dec 2008 19:59:49 +0000
Received: with ECARTIS (v1.0.0; list linux-mips); Tue, 23 Dec 2008 19:59:32
 +0000 (GMT)
Received: from fnoeppeil48.netpark.at ([217.175.205.176]:65471 "EHLO
	roarinelk.homelinux.net") by ftp.linux-mips.org with ESMTP	id
 S24207993AbYLWT7a (ORCPT <rfc822;linux-mips@linux-mips.org>);	Tue, 23 Dec
 2008 19:59:30 +0000
Received: (qmail 24690 invoked from network); 23 Dec 2008 20:59:29 +0100
Received: from scarran.roarinelk.net (HELO localhost.localdomain)
 (192.168.0.242)  by 192.168.0.1 with SMTP; 23 Dec 2008 20:59:29 +0100
From: Manuel Lauss <mano@roarinelk.homelinux.net>
To: Linux-MIPS <linux-mips@linux-mips.org>
CC: Manuel Lauss <mano@roarinelk.homelinux.net>
Sender: "linux-mips-bounce@linux-mips.org" <linux-mips-bounce@linux-mips.org>
Date: Tue, 23 Dec 2008 11:59:24 -0800
Subject: [PATCH v2] Alchemy: fix gpio_to_irq().
Thread-Topic: [PATCH v2] Alchemy: fix gpio_to_irq().
Thread-Index: AcllORAregRnObtsQCWwK3/g/JMG6w==
Message-ID: <1230062364-24788-1-git-send-email-mano@roarinelk.homelinux.net>
Accept-Language: en-US
Content-Language: en-US
X-MS-Exchange-Organization-AuthAs: Internal
X-MS-Exchange-Organization-AuthMechanism: 0b
X-MS-Exchange-Organization-AuthSource: exch1.onstor.net
X-MS-Has-Attach:
X-Auto-Response-Suppress: All
X-MS-TNEF-Correlator:
x-originalarrivaltime: 23 Dec 2008 20:00:10.0729 (UTC)
 FILETIME=[0FACBD90:01C96539]
errors-to: linux-mips-bounce@linux-mips.org
x-ems-proccessed: 2K3Xl1OQTInXD6xxuA8z3Q==
x-ems-stamp: 638HzX/Im71lNfld/YFD+A==
x-messageone-virus-version: vendor=fsecure
 engine=4.65.7400:2.4.4,1.2.40,4.0.164
 definitions=2008-12-23_08:2008-12-22,2008-12-23,2008-12-23 signatures=0
x-messageone-virus-scanned: Clean
x-messageone-envelope-sender: linux-mips-bounce@linux-mips.org
x-messageone-spam-details: rule=m773emszm_notspam policy=m773emszm score=0
 spamscore=0 ipscore=0 phishscore=0 bulkscore=0 adultscore=0 classifier=spam
 adjust=0 reason=mlx engine=3.1.0-0810130000 definitions=main-0812230114
x-messageone-spam-score: 0
x-messageone-spam-bar:
x-list: linux-mips
x-archive-position: 21662
x-ecartis-version: Ecartis v1.0.0
x-original-sender: mano@roarinelk.homelinux.net
Content-Type: text/plain; charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
MIME-Version: 1.0

It's not as easy as it is currently implemented:  Not all GPIOs are
irq-capable and every CPU model has them wired up differently.

Signed-off-by: Manuel Lauss <mano@roarinelk.homelinux.net>
---
This update removes all but one EINVAL.

 arch/mips/alchemy/common/gpio.c          |   88 ++++++++++++++++++++++++++=
+---
 arch/mips/include/asm/mach-au1x00/gpio.h |    7 ++-
 2 files changed, 84 insertions(+), 11 deletions(-)

diff --git a/arch/mips/alchemy/common/gpio.c b/arch/mips/alchemy/common/gpi=
o.c
index e660ddd..7bac8f7 100644
--- a/arch/mips/alchemy/common/gpio.c
+++ b/arch/mips/alchemy/common/gpio.c
@@ -40,27 +40,27 @@ static struct au1x00_gpio2 *const gpio2 =3D (struct au1=
x00_gpio2 *) GPIO2_BASE;
=20
 static int au1xxx_gpio2_read(unsigned gpio)
 {
-	gpio -=3D AU1XXX_GPIO_BASE;
+	gpio -=3D AU1XXX_GPIO2_BASE;
 	return ((gpio2->pinstate >> gpio) & 0x01);
 }
=20
 static void au1xxx_gpio2_write(unsigned gpio, int value)
 {
-	gpio -=3D AU1XXX_GPIO_BASE;
+	gpio -=3D AU1XXX_GPIO2_BASE;
=20
 	gpio2->output =3D (GPIO2_OUTPUT_ENABLE_MASK << gpio) | ((!!value) << gpio=
);
 }
=20
 static int au1xxx_gpio2_direction_input(unsigned gpio)
 {
-	gpio -=3D AU1XXX_GPIO_BASE;
+	gpio -=3D AU1XXX_GPIO2_BASE;
 	gpio2->dir &=3D ~(0x01 << gpio);
 	return 0;
 }
=20
 static int au1xxx_gpio2_direction_output(unsigned gpio, int value)
 {
-	gpio -=3D AU1XXX_GPIO_BASE;
+	gpio -=3D AU1XXX_GPIO2_BASE;
 	gpio2->dir |=3D 0x01 << gpio;
 	gpio2->output =3D (GPIO2_OUTPUT_ENABLE_MASK << gpio) | ((!!value) << gpio=
);
 	return 0;
@@ -97,7 +97,7 @@ static int au1xxx_gpio1_direction_output(unsigned gpio, i=
nt value)
=20
 int au1xxx_gpio_get_value(unsigned gpio)
 {
-	if (gpio >=3D AU1XXX_GPIO_BASE)
+	if (gpio >=3D AU1XXX_GPIO2_BASE)
 #if defined(CONFIG_SOC_AU1000)
 		return 0;
 #else
@@ -110,7 +110,7 @@ EXPORT_SYMBOL(au1xxx_gpio_get_value);
=20
 void au1xxx_gpio_set_value(unsigned gpio, int value)
 {
-	if (gpio >=3D AU1XXX_GPIO_BASE)
+	if (gpio >=3D AU1XXX_GPIO2_BASE)
 #if defined(CONFIG_SOC_AU1000)
 		;
 #else
@@ -123,7 +123,7 @@ EXPORT_SYMBOL(au1xxx_gpio_set_value);
=20
 int au1xxx_gpio_direction_input(unsigned gpio)
 {
-	if (gpio >=3D AU1XXX_GPIO_BASE)
+	if (gpio >=3D AU1XXX_GPIO2_BASE)
 #if defined(CONFIG_SOC_AU1000)
 		return -ENODEV;
 #else
@@ -136,7 +136,7 @@ EXPORT_SYMBOL(au1xxx_gpio_direction_input);
=20
 int au1xxx_gpio_direction_output(unsigned gpio, int value)
 {
-	if (gpio >=3D AU1XXX_GPIO_BASE)
+	if (gpio >=3D AU1XXX_GPIO2_BASE)
 #if defined(CONFIG_SOC_AU1000)
 		return -ENODEV;
 #else
@@ -146,3 +146,75 @@ int au1xxx_gpio_direction_output(unsigned gpio, int va=
lue)
 	return au1xxx_gpio1_direction_output(gpio, value);
 }
 EXPORT_SYMBOL(au1xxx_gpio_direction_output);
+
+#define GPIO2(x)		(AU1XXX_GPIO2_BASE + (x))
+#define MAKE_IRQ(intc, off)	(AU1000_INTC##intc##_INT_BASE + (off))
+#define MAKE_GPIO2_IRQ(intc, base, gpio)	\
+		MAKE_IRQ(intc, (base) + (gpio) - AU1XXX_GPIO2_BASE)
+
+int au1xxx_gpio_to_irq(unsigned int gpio)
+{
+#ifdef CONFIG_SOC_AU1000
+
+	if ((gpio >=3D 0) && (gpio <=3D 31))
+		return MAKE_IRQ(1, gpio);
+
+#elif defined(CONFIG_SOC_AU1100)
+
+	if (gpio >=3D AU1XXX_GPIO2_BASE) {
+		if ((gpio >=3D GPIO2(8)) && (gpio <=3D GPIO2(15)))
+			return MAKE_IRQ(0, 29);
+	} else
+		return MAKE_IRQ(1, gpio);
+
+#elif defined(CONFIG_SOC_AU1500)
+
+	if (gpio >=3D AU1XXX_GPIO2_BASE) {
+		if ((gpio >=3D GPIO2(0)) && (gpio <=3D GPIO2(3)))
+			return MAKE_GPIO2_IRQ(1, 16, gpio);
+		else if ((gpio >=3D GPIO2(4)) && (gpio <=3D GPIO2(5)))
+			return MAKE_GPIO2_IRQ(1, 21, gpio - 4);
+		else if ((gpio >=3D GPIO2(6)) && (gpio <=3D GPIO2(7)))
+			return MAKE_GPIO2_IRQ(1, 29, gpio - 6);
+	} else {
+		if (((gpio >=3D 0) && (gpio <=3D 15)) || (gpio =3D=3D 20) ||
+		    ((gpio >=3D 23) && (gpio <=3D 28)))
+			return MAKE_IRQ(1, gpio);
+	}
+
+#elif defined(CONFIG_SOC_AU1550)
+
+	if (gpio >=3D AU1XXX_GPIO2_BASE) {
+		if (gpio =3D=3D GPIO2(0))
+			return MAKE_IRQ(1, 16);
+		else if ((gpio >=3D GPIO2(1)) && (gpio <=3D GPIO2(5)))
+			return MAKE_IRQ(1, 17);
+		else if ((gpio >=3D GPIO2(6)) && (gpio <=3D GPIO2(7)))
+			return MAKE_GPIO2_IRQ(1, 29, gpio - 6);
+		else if ((gpio >=3D GPIO2(8)) && (gpio <=3D GPIO2(15)))
+			return MAKE_IRQ(1, 31)
+	} else {
+		if (((gpio >=3D 0) && (gpio <=3D 15)) ||
+		    ((gpio >=3D 20) && (gpio <=3D 28)))
+			return MAKE_IRQ(1, gpio);
+		else if ((gpio >=3D 16) && (gpio <=3D 17))
+			return MAKE_IRQ(1, gpio + 2);
+	}
+
+#elif defined(CONFIG_SOC_AU1200)
+
+	if (gpio >=3D AU1XXX_GPIO2_BASE) {
+		if ((gpio >=3D GPIO2(0)) && (gpio <=3D GPIO2(2)))
+			return MAKE_GPIO2_IRQ(0, 5, gpio);
+		else if (gpio =3D=3D GPIO2(3))
+			return MAKE_IRQ(0, 22);
+		else if ((gpio >=3D GPIO2(4)) && (gpio <=3D GPIO2(7)))
+			return MAKE_GPIO2_IRQ(0, 24, gpio - 4);
+		else if ((gpio >=3D GPIO2(8)) && (gpio <=3D GPIO2(15)))
+			return MAKE_IRQ(0, 28);
+	} else
+		return MAKE_IRQ(1, gpio);
+#endif
+	return -EINVAL;
+}
+EXPORT_SYMBOL(au1xxx_gpio_to_irq);
diff --git a/arch/mips/include/asm/mach-au1x00/gpio.h b/arch/mips/include/a=
sm/mach-au1x00/gpio.h
index 2dc61e0..08060ab 100644
--- a/arch/mips/include/asm/mach-au1x00/gpio.h
+++ b/arch/mips/include/asm/mach-au1x00/gpio.h
@@ -3,7 +3,7 @@
=20
 #include <linux/types.h>
=20
-#define AU1XXX_GPIO_BASE	200
+#define AU1XXX_GPIO2_BASE	200
=20
 struct au1x00_gpio2 {
 	u32	dir;
@@ -18,6 +18,7 @@ extern int au1xxx_gpio_get_value(unsigned gpio);
 extern void au1xxx_gpio_set_value(unsigned gpio, int value);
 extern int au1xxx_gpio_direction_input(unsigned gpio);
 extern int au1xxx_gpio_direction_output(unsigned gpio, int value);
+extern int au1xxx_gpio_to_irq(unsigned int gpio);
=20
=20
 /* Wrappers for the arch-neutral GPIO API */
@@ -55,12 +56,12 @@ static inline void gpio_set_value(unsigned gpio, int va=
lue)
=20
 static inline int gpio_to_irq(unsigned gpio)
 {
-	return gpio;
+	return au1xxx_gpio_to_irq(gpio);
 }
=20
 static inline int irq_to_gpio(unsigned irq)
 {
-	return irq;
+	return -EINVAL;
 }
=20
 /* For cansleep */
--=20
1.6.0.4


