Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755418Ab0FCOam (ORCPT ); Thu, 3 Jun 2010 10:30:42 -0400 Received: from mail-wy0-f174.google.com ([74.125.82.174]:40187 "EHLO mail-wy0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754061Ab0FCOak (ORCPT ); Thu, 3 Jun 2010 10:30:40 -0400 DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=sender:from:organization:to:subject:date:user-agent:cc:references :in-reply-to:mime-version:content-type:content-transfer-encoding :message-id; b=HBZdnHZ7xv8VMdA6exCELrEcFN3ZqXfrDdHDgV1J4qabj89sEwKBC1taMyADHBw8Kp d7eGww4zPbQGp5D6kMPtzr9DiXB8oY6Z38ObJwHhXezYClJi2OZlz0k6x2FHXsfr4//O O9c/j7tchrgsDGr24DFlPPVn/Haf97oOSA2V8= From: Florian Fainelli Organization: OpenWrt To: "Lars-Peter Clausen" Subject: Re: [RFC][PATCH 02/26] MIPS: jz4740: Add IRQ handler code Date: Thu, 3 Jun 2010 16:29:26 +0200 User-Agent: KMail/1.13.2 (Linux/2.6.32-22-server; KDE/4.4.2; x86_64; ; ) Cc: Ralf Baechle , linux-mips@linux-mips.org, linux-kernel@vger.kernel.org, Thomas Gleixner References: <1275505397-16758-1-git-send-email-lars@metafoo.de> <1275505397-16758-3-git-send-email-lars@metafoo.de> In-Reply-To: <1275505397-16758-3-git-send-email-lars@metafoo.de> MIME-Version: 1.0 Content-Type: Text/Plain; charset="utf-8" Content-Transfer-Encoding: 7bit Message-Id: <201006031629.26424.florian@openwrt.org> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 8868 Lines: 293 On Wednesday 02 June 2010 21:02:53 Lars-Peter Clausen wrote: > This patch adds support for IRQ handling on a JZ4740 SoC. > > Signed-off-by: Lars-Peter Clausen > Cc: Thomas Gleixner > --- > arch/mips/include/asm/mach-jz4740/irq.h | 55 ++++++++++ > arch/mips/jz4740/irq.c | 170 > +++++++++++++++++++++++++++++++ arch/mips/jz4740/irq.h | > 21 ++++ > 3 files changed, 246 insertions(+), 0 deletions(-) > create mode 100644 arch/mips/include/asm/mach-jz4740/irq.h > create mode 100644 arch/mips/jz4740/irq.c > create mode 100644 arch/mips/jz4740/irq.h > > diff --git a/arch/mips/include/asm/mach-jz4740/irq.h > b/arch/mips/include/asm/mach-jz4740/irq.h new file mode 100644 > index 0000000..5e27b78 > --- /dev/null > +++ b/arch/mips/include/asm/mach-jz4740/irq.h > @@ -0,0 +1,55 @@ > +/* > + * Copyright (C) 2009-2010, Lars-Peter Clausen > + * JZ7420/JZ4740 IRQ definitions > + * > + * This program is free software; you can redistribute it and/or modify > it + * under the terms of the GNU General Public License as published > by the + * Free Software Foundation; either version 2 of the License, or > (at your + * option) any later version. > + * > + * You should have received a copy of the GNU General Public License > along + * with this program; if not, write to the Free Software > Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. > + * > + */ > + > +#ifndef __ASM_MACH_JZ4740_IRQ_H__ > +#define __ASM_MACH_JZ4740_IRQ_H__ > + > +#define MIPS_CPU_IRQ_BASE 0 > +#define JZ4740_IRQ_BASE 8 > + > +/* 1st-level interrupts */ > +#define JZ4740_IRQ(x) (JZ4740_IRQ_BASE + (x)) > +#define JZ4740_IRQ_I2C JZ4740_IRQ(1) > +#define JZ4740_IRQ_UHC JZ4740_IRQ(3) > +#define JZ4740_IRQ_UART1 JZ4740_IRQ(8) > +#define JZ4740_IRQ_UART0 JZ4740_IRQ(9) > +#define JZ4740_IRQ_SADC JZ4740_IRQ(12) > +#define JZ4740_IRQ_MSC JZ4740_IRQ(14) > +#define JZ4740_IRQ_RTC JZ4740_IRQ(15) > +#define JZ4740_IRQ_SSI JZ4740_IRQ(16) > +#define JZ4740_IRQ_CIM JZ4740_IRQ(17) > +#define JZ4740_IRQ_AIC JZ4740_IRQ(18) > +#define JZ4740_IRQ_ETH JZ4740_IRQ(19) > +#define JZ4740_IRQ_DMAC JZ4740_IRQ(20) > +#define JZ4740_IRQ_TCU2 JZ4740_IRQ(21) > +#define JZ4740_IRQ_TCU1 JZ4740_IRQ(22) > +#define JZ4740_IRQ_TCU0 JZ4740_IRQ(23) > +#define JZ4740_IRQ_UDC JZ4740_IRQ(24) > +#define JZ4740_IRQ_GPIO3 JZ4740_IRQ(25) > +#define JZ4740_IRQ_GPIO2 JZ4740_IRQ(26) > +#define JZ4740_IRQ_GPIO1 JZ4740_IRQ(27) > +#define JZ4740_IRQ_GPIO0 JZ4740_IRQ(28) > +#define JZ4740_IRQ_IPU JZ4740_IRQ(29) > +#define JZ4740_IRQ_LCD JZ4740_IRQ(30) > + > +/* 2nd-level interrupts */ > +#define JZ4740_IRQ_DMA(x) ((x) + JZ4740_IRQ(32)) > + > +#define JZ4740_IRQ_INTC_GPIO(x) (JZ4740_IRQ_GPIO0 - (x)) > +#define JZ4740_IRQ_GPIO(x) (JZ4740_IRQ(48) + (x)) > + > +#define NR_IRQS (JZ4740_IRQ_GPIO(127) + 1) > + > +#endif > diff --git a/arch/mips/jz4740/irq.c b/arch/mips/jz4740/irq.c > new file mode 100644 > index 0000000..46a03ee > --- /dev/null > +++ b/arch/mips/jz4740/irq.c > @@ -0,0 +1,170 @@ > +/* > + * Copyright (C) 2009-2010, Lars-Peter Clausen > + * JZ4740 platform IRQ support > + * > + * This program is free software; you can redistribute it and/or modify > it + * under the terms of the GNU General Public License as published > by the + * Free Software Foundation; either version 2 of the License, or > (at your + * option) any later version. > + * > + * You should have received a copy of the GNU General Public License > along + * with this program; if not, write to the Free Software > Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. > + * > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include > +#include > + > +#include > +#include > +#include > + > +#include > + > +static void __iomem *jz_intc_base; > +static uint32_t jz_intc_wakeup; > +static uint32_t jz_intc_saved; > + > +#define JZ_REG_INTC_STATUS 0x00 > +#define JZ_REG_INTC_MASK 0x04 > +#define JZ_REG_INTC_SET_MASK 0x08 > +#define JZ_REG_INTC_CLEAR_MASK 0x0c > +#define JZ_REG_INTC_PENDING 0x10 > + > +#define IRQ_BIT(x) BIT((x) - JZ4740_IRQ_BASE) > + > +static void intc_irq_unmask(unsigned int irq) > +{ > + writel(IRQ_BIT(irq), jz_intc_base + JZ_REG_INTC_CLEAR_MASK); > +} > + > +static void intc_irq_mask(unsigned int irq) > +{ > + writel(IRQ_BIT(irq), jz_intc_base + JZ_REG_INTC_SET_MASK); > +} > + > +static int intc_irq_set_wake(unsigned int irq, unsigned int on) > +{ > + if (on) > + jz_intc_wakeup |= IRQ_BIT(irq); > + else > + jz_intc_wakeup &= ~IRQ_BIT(irq); > + > + return 0; > +} > + > +static struct irq_chip intc_irq_type = { > + .name = "INTC", > + .mask = intc_irq_mask, > + .mask_ack = intc_irq_mask, > + .unmask = intc_irq_unmask, > + .set_wake = intc_irq_set_wake, > +}; > + > +static irqreturn_t jz4740_cascade(int irq, void *data) > +{ > + uint32_t irq_reg; > + int intc_irq; > + > + irq_reg = readl(jz_intc_base + JZ_REG_INTC_PENDING); > + > + intc_irq = ffs(irq_reg); > + if (intc_irq) > + generic_handle_irq(intc_irq - 1 + JZ4740_IRQ_BASE); > + > + return IRQ_HANDLED; > +} > + > +static struct irqaction jz4740_cascade_action = { > + .handler = jz4740_cascade, > + .name = "JZ4740 cascade interrupt", > + .flags = IRQF_DISABLED, > +}; > + > +void __init arch_init_irq(void) > +{ > + int i; > + mips_cpu_irq_init(); > + > + jz_intc_base = ioremap(CPHYSADDR(JZ4740_INTC_BASE_ADDR), 0x14); Better define the physical address and use ioremap directly on it. > + > + for (i = JZ4740_IRQ_BASE; i < JZ4740_IRQ_BASE + 32; i++) { > + intc_irq_mask(i); > + set_irq_chip_and_handler(i, &intc_irq_type, handle_level_irq); > + } > + > + setup_irq(2, &jz4740_cascade_action); > +} > + > +asmlinkage void plat_irq_dispatch(void) > +{ > + unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM; > + if (pending & STATUSF_IP2) > + do_IRQ(2); > + else if (pending & STATUSF_IP3) > + do_IRQ(3); > + else > + spurious_interrupt(); > +} > + > +void jz4740_intc_suspend(void) > +{ > + jz_intc_saved = readl(jz_intc_base + JZ_REG_INTC_MASK); > + writel(~jz_intc_wakeup, jz_intc_base + JZ_REG_INTC_SET_MASK); > + writel(jz_intc_wakeup, jz_intc_base + JZ_REG_INTC_CLEAR_MASK); > +} > + > +void jz4740_intc_resume(void) > +{ > + writel(~jz_intc_saved, jz_intc_base + JZ_REG_INTC_CLEAR_MASK); > + writel(jz_intc_saved, jz_intc_base + JZ_REG_INTC_SET_MASK); > +} > + > +#ifdef CONFIG_DEBUG_FS > + > +static inline void intc_seq_reg(struct seq_file *s, const char *name, > + unsigned int reg) > +{ > + seq_printf(s, "%s:\t\t%08x\n", name, readl(jz_intc_base + reg)); > +} > + > +static int intc_regs_show(struct seq_file *s, void *unused) > +{ > + intc_seq_reg(s, "Status", JZ_REG_INTC_STATUS); > + intc_seq_reg(s, "Mask", JZ_REG_INTC_MASK); > + intc_seq_reg(s, "Pending", JZ_REG_INTC_PENDING); > + > + return 0; > +} > + > +static int intc_regs_open(struct inode *inode, struct file *file) > +{ > + return single_open(file, intc_regs_show, NULL); > +} > + > +static const struct file_operations intc_regs_operations = { > + .open = intc_regs_open, > + .read = seq_read, > + .llseek = seq_lseek, > + .release = single_release, > +}; > + > +static int __init intc_debugfs_init(void) > +{ > + (void) debugfs_create_file("jz_regs_intc", S_IFREG | S_IRUGO, > + NULL, NULL, &intc_regs_operations); > + return 0; > +} > +subsys_initcall(intc_debugfs_init); > + > +#endif > diff --git a/arch/mips/jz4740/irq.h b/arch/mips/jz4740/irq.h > new file mode 100644 > index 0000000..dadbd5f > --- /dev/null > +++ b/arch/mips/jz4740/irq.h > @@ -0,0 +1,21 @@ > +/* > + * Copyright (C) 2010, Lars-Peter Clausen > + * > + * This program is free software; you can redistribute it and/or modify > it + * under the terms of the GNU General Public License as published > by the + * Free Software Foundation; either version 2 of the License, or > (at your + * option) any later version. > + * > + * You should have received a copy of the GNU General Public License > along + * with this program; if not, write to the Free Software > Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. > + * > + */ > + > +#ifndef __MIPS_JZ4740_IRQ_H__ > +#define __MIPS_JZ4740_IRQ_H__ > + > +extern void jz4740_intc_suspend(void); > +extern void jz4740_intc_resume(void); > + > +#endif -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/