From patchwork Thu Jul 28 17:17:55 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tommy Lin X-Patchwork-Id: 1015212 Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) by demeter2.kernel.org (8.14.4/8.14.4) with ESMTP id p6S9pdYS016957 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Thu, 28 Jul 2011 09:52:01 GMT Received: from canuck.infradead.org ([2001:4978:20e::1]) by merlin.infradead.org with esmtps (Exim 4.76 #1 (Red Hat Linux)) id 1QmNFS-0004jU-8e; Thu, 28 Jul 2011 09:51:22 +0000 Received: from localhost ([127.0.0.1] helo=canuck.infradead.org) by canuck.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1QmNFR-0000XF-NY; Thu, 28 Jul 2011 09:51:21 +0000 Received: from mail-gy0-f177.google.com ([209.85.160.177]) by canuck.infradead.org with esmtps (Exim 4.76 #1 (Red Hat Linux)) id 1QmNFM-0000Wv-K0 for linux-arm-kernel@lists.infradead.org; Thu, 28 Jul 2011 09:51:18 +0000 Received: by gya1 with SMTP id 1so1921117gya.36 for ; Thu, 28 Jul 2011 02:51:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=from:to:cc:subject:date:message-id:x-mailer; bh=1rbBEPs6ba9X3RkTDqkRiMvC3erDvKuJEdBMx1xGqvA=; b=sM+v9o/HcZ77E9cfVickztCIVWNZS3vNYyKgEKSWbY5PP5pElPJN0vLQGIfFH3EgiS b3PZGcnSUv08Dm0eVUHhXxLN7vOG+sKTKni/+e95ZPeBuxdhCbbP2NwYYIDkjw2L1k4J +Nuvt563bksMP6q99Pd/F0aSf/avh23bjGcBI= Received: by 10.151.116.5 with SMTP id t5mr597947ybm.179.1311846675282; Thu, 28 Jul 2011 02:51:15 -0700 (PDT) Received: from localhost.localdomain (60-250-205-192.HINET-IP.hinet.net [60.250.205.192]) by mx.google.com with ESMTPS id u12sm2364552ybj.6.2011.07.28.02.51.13 (version=TLSv1/SSLv3 cipher=OTHER); Thu, 28 Jul 2011 02:51:14 -0700 (PDT) From: Tommy Lin To: Russell King , Anton Vorontsov Subject: [PATCH 3/3] arch: arm: mach-cns3xxx: Add external interrupt pin demo program Date: Fri, 29 Jul 2011 01:17:55 +0800 Message-Id: <1311873475-26111-1-git-send-email-tommy.lin.1101@gmail.com> X-Mailer: git-send-email 1.7.6 X-CRM114-Version: 20090807-BlameThorstenAndJenny ( TRE 0.7.6 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20110728_055116_938475_89492311 X-CRM114-Status: GOOD ( 20.14 ) X-Spam-Score: -0.7 (/) X-Spam-Report: SpamAssassin version 3.3.1 on canuck.infradead.org summary: Content analysis details: (-0.7 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.7 RCVD_IN_DNSWL_LOW RBL: Sender listed at http://www.dnswl.org/, low trust [209.85.160.177 listed in list.dnswl.org] 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider (tommy.lin.1101[at]gmail.com) 0.0 DATE_IN_FUTURE_06_12 Date: is 6 to 12 hours after Received: date 0.1 FREEMAIL_ENVFROM_END_DIGIT Envelope-from freemail username ends in digit (tommy.lin.1101[at]gmail.com) -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature Cc: Tommy Lin , linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: linux-arm-kernel-bounces@lists.infradead.org Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter2.kernel.org [140.211.167.43]); Thu, 28 Jul 2011 09:52:01 +0000 (UTC) Add external interrupt pin configuration demo program to CNS3XXX platform. The external interrupt pins are dedicate input pins that direct connect to ARM MPCore GIC module. Signed-off-by: Tommy Lin --- arch/arm/configs/cns3420vb_defconfig | 1 + arch/arm/mach-cns3xxx/Kconfig | 11 ++ arch/arm/mach-cns3xxx/Makefile | 1 + arch/arm/mach-cns3xxx/ext_intr.c | 194 ++++++++++++++++++++++++++++++++++ 4 files changed, 207 insertions(+), 0 deletions(-) create mode 100644 arch/arm/mach-cns3xxx/ext_intr.c diff --git a/arch/arm/configs/cns3420vb_defconfig b/arch/arm/configs/cns3420vb_defconfig index c83d14c..6eefa7e 100644 --- a/arch/arm/configs/cns3420vb_defconfig +++ b/arch/arm/configs/cns3420vb_defconfig @@ -21,6 +21,7 @@ CONFIG_MODVERSIONS=y CONFIG_IOSCHED_CFQ=m CONFIG_ARCH_CNS3XXX=y CONFIG_MACH_CNS3420VB=y +CONFIG_CNS3XXX_EXT_INTR_DEMO=m CONFIG_AEABI=y CONFIG_ZBOOT_ROM_TEXT=0x0 CONFIG_ZBOOT_ROM_BSS=0x0 diff --git a/arch/arm/mach-cns3xxx/Kconfig b/arch/arm/mach-cns3xxx/Kconfig index 29b13f2..b4736e6 100644 --- a/arch/arm/mach-cns3xxx/Kconfig +++ b/arch/arm/mach-cns3xxx/Kconfig @@ -10,4 +10,15 @@ config MACH_CNS3420VB This is a platform with an on-board ARM11 MPCore and has support for USB, USB-OTG, MMC/SD/SDIO, SATA, PCI-E, etc. +config CNS3XXX_EXT_INTR_DEMO + tristate "External interrupt demo program" + depends on MACH_CNS3420VB + help + This program hook interrupt service routine to external interrupts + 0 ~ 3. + Name EVB Trigger ISR + Ext_Int0 Rising edge + Ext_Int1 Push button S3 Rising edge Toggle LED D6 + Ext_Int2 Push button S4 High level Toggle LED D7 + endmenu diff --git a/arch/arm/mach-cns3xxx/Makefile b/arch/arm/mach-cns3xxx/Makefile index 7bb9c88..a610c59 100644 --- a/arch/arm/mach-cns3xxx/Makefile +++ b/arch/arm/mach-cns3xxx/Makefile @@ -2,3 +2,4 @@ obj-y += gpio.o obj-$(CONFIG_ARCH_CNS3XXX) += core.o pm.o devices.o obj-$(CONFIG_PCI) += pcie.o obj-$(CONFIG_MACH_CNS3420VB) += cns3420vb.o +obj-$(CONFIG_CNS3XXX_EXT_INTR_DEMO) += ext_intr.o diff --git a/arch/arm/mach-cns3xxx/ext_intr.c b/arch/arm/mach-cns3xxx/ext_intr.c new file mode 100644 index 0000000..5127860 --- /dev/null +++ b/arch/arm/mach-cns3xxx/ext_intr.c @@ -0,0 +1,194 @@ +/******************************************************************************* + * + * arch/arm/mach-cns3xxx/ext_intr.c + * + * External interrupt driver for the CNS3XXX SOCs + * + * Copyright (c) 2011 Cavium + * Tommy Lin + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, Version 2, as + * published by the Free Software Foundation. + * + * This file is distributed in the hope that it will be useful, + * but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or + * NONINFRINGEMENT. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this file; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA or + * visit http://www.gnu.org/licenses/. + * + * This file may also be available under a different license from Cavium. + * Contact Cavium for more information + * + ******************************************************************************/ + +#include +#include + +#include +#include + + +/* CNS3XXX has three external interrupt pins, Ext_Intr0, Ext_Intr1 and + * Ext_Intr3. Each pin has its own interrupt ID which is not shared with other + * function. It is not like 32 gpio pins in group A or B shared one irq. The + * external interrupt pins are special functions that shared with GPIOB[27:29]. + * Users could turn on shared pin function to enable external interrupt pin with + * cns3xxx_sharepin_request API. + * + * The external interrupt trigger method is controlled by ARM MPCore GIC. GIC + * only suppot high active level trigger and rising edge trigger. Configure GIC + * with other trigger type will have no effect. + * + * Name irq Shared gpio pin + * Ext_Intr0 93 GPIOB[29] + * Ext_Intr1 94 GPIOB[28] + * Ext_Intr2 95 GPIOB[27] + */ + +#define hw_debug(fmt, args...) printk(KERN_ERR ">>>>>> %s\t"\ + fmt, __func__, ##args) + +struct ext_intr_data { + int irq; + unsigned gpio; + char *name; + char *alias; +}; + +static unsigned led_D6 = GPIOA(6); +static unsigned led_D7 = GPIOA(5); + +static struct ext_intr_data eintr_data[] = { + {IRQ_CNS3XXX_EXTERNAL_PIN0, GPIOB(29), "Ext_Intr0", "HIB_REQ"}, + {IRQ_CNS3XXX_EXTERNAL_PIN1, GPIOB(28), "Ext_Intr1", "Push Button S3"}, + {IRQ_CNS3XXX_EXTERNAL_PIN2, GPIOB(27), "Ext_Intr2", "Push Button S4"}, +}; + +static irqreturn_t cns3xxx_ext_intr0_handler(int irq, void *dev_id) +{ + struct ext_intr_data *data = dev_id; + + printk(KERN_WARNING "%s detected!\n", data->alias); + + return IRQ_HANDLED; +} + +static irqreturn_t cns3xxx_ext_intr1_handler(int irq, void *dev_id) +{ + int value; + + value = gpio_get_value(led_D6); + + disable_irq_nosync(irq); + + gpio_set_value(led_D6, !value); + + enable_irq(irq); + + return IRQ_HANDLED; +} + +static irqreturn_t cns3xxx_ext_intr2_handler(int irq, void *dev_id) +{ + int value; + + value = gpio_get_value(led_D7); + + disable_irq_nosync(irq); + + gpio_set_value(led_D7, !value); + + enable_irq(irq); + + return IRQ_HANDLED; +} + +int __init cns3xxx_eintr_init(void) +{ + int ret; + + ret = gpio_request(led_D6, "INTR Test LED(D6)"); + if (ret) + goto err1; + gpio_direction_output(led_D6, 0); + + ret = gpio_request(led_D7, "INTR Test LED(D7)"); + if (ret) + goto err2; + gpio_direction_output(led_D7, 0); + + /************ Ext_Intr0 ************/ + ret = cns3xxx_sharepin_request(eintr_data[0].gpio, eintr_data[0].alias); + if (ret) + goto err3; + + ret = request_irq(eintr_data[0].irq, cns3xxx_ext_intr0_handler, + IRQF_SHARED | IRQF_TRIGGER_RISING, + eintr_data[0].name, &eintr_data[0]); + if (ret) + goto err4; + + /************ Ext_Intr1 ************/ + ret = cns3xxx_sharepin_request(eintr_data[1].gpio, eintr_data[1].alias); + if (ret) + goto err5; + + ret = request_irq(eintr_data[1].irq, cns3xxx_ext_intr1_handler, + IRQF_SHARED | IRQF_TRIGGER_RISING, + eintr_data[1].name, &eintr_data[1]); + if (ret) + goto err6; + + /************ Ext_Intr2 ************/ + ret = cns3xxx_sharepin_request(eintr_data[2].gpio, eintr_data[2].alias); + if (ret) + goto err7; + + ret = request_irq(eintr_data[2].irq, cns3xxx_ext_intr2_handler, + IRQF_SHARED | IRQF_TRIGGER_HIGH, + eintr_data[2].name, &eintr_data[2]); + if (ret) + goto err8; + + return 0; + +err8: + cns3xxx_sharepin_free(eintr_data[2].gpio); +err7: + free_irq(eintr_data[1].irq, &eintr_data[1]); +err6: + cns3xxx_sharepin_free(eintr_data[1].gpio); +err5: + free_irq(eintr_data[0].irq, &eintr_data[0]); +err4: + cns3xxx_sharepin_free(eintr_data[0].gpio); +err3: + gpio_free(led_D7); +err2: + gpio_free(led_D6); +err1: + return ret; +} + +void __exit cns3xxx_eintr_exit(void) +{ + free_irq(eintr_data[2].irq, &eintr_data[2]); + free_irq(eintr_data[1].irq, &eintr_data[1]); + free_irq(eintr_data[0].irq, &eintr_data[0]); + cns3xxx_sharepin_free(eintr_data[2].gpio); + cns3xxx_sharepin_free(eintr_data[1].gpio); + cns3xxx_sharepin_free(eintr_data[0].gpio); + gpio_free(led_D7); + gpio_free(led_D6); +} + +module_init(cns3xxx_eintr_init); +module_exit(cns3xxx_eintr_exit); + +MODULE_LICENSE("GPL"); +