From patchwork Wed Dec 7 13:59:50 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: thomas.abraham@linaro.org X-Patchwork-Id: 5529 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id 1B63123E18 for ; Wed, 7 Dec 2011 13:58:37 +0000 (UTC) Received: from mail-ee0-f52.google.com (mail-ee0-f52.google.com [74.125.83.52]) by fiordland.canonical.com (Postfix) with ESMTP id 12855A18522 for ; Wed, 7 Dec 2011 13:58:37 +0000 (UTC) Received: by mail-ee0-f52.google.com with SMTP id c14so573066eek.11 for ; Wed, 07 Dec 2011 05:58:37 -0800 (PST) Received: by 10.14.17.211 with SMTP id j59mr3741035eej.138.1323266316906; Wed, 07 Dec 2011 05:58:36 -0800 (PST) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.205.129.2 with SMTP id hg2cs71249bkc; Wed, 7 Dec 2011 05:58:36 -0800 (PST) Received: by 10.68.2.35 with SMTP id 3mr5950774pbr.28.1323266313039; Wed, 07 Dec 2011 05:58:33 -0800 (PST) Received: from mailout2.samsung.com (mailout2.samsung.com. [203.254.224.25]) by mx.google.com with ESMTP id t1si3356974pbi.145.2011.12.07.05.58.32; Wed, 07 Dec 2011 05:58:33 -0800 (PST) Received-SPF: neutral (google.com: 203.254.224.25 is neither permitted nor denied by best guess record for domain of thomas.abraham@linaro.org) client-ip=203.254.224.25; Authentication-Results: mx.google.com; spf=neutral (google.com: 203.254.224.25 is neither permitted nor denied by best guess record for domain of thomas.abraham@linaro.org) smtp.mail=thomas.abraham@linaro.org Received: from epcpsbgm1.samsung.com (mailout2.samsung.com [203.254.224.25]) by mailout2.samsung.com (Oracle Communications Messaging Exchange Server 7u4-19.01 64bit (built Sep 7 2010)) with ESMTP id <0LVU007956T8LU40@mailout2.samsung.com> for patches@linaro.org; Wed, 07 Dec 2011 22:58:32 +0900 (KST) X-AuditID: cbfee61a-b7b89ae000001a15-fc-4edf71073a0b Received: from epmmp2 ( [203.254.227.17]) by epcpsbgm1.samsung.com (MMPCPMTA) with SMTP id 47.F2.06677.7017FDE4; Wed, 07 Dec 2011 22:58:32 +0900 (KST) Received: from localhost.localdomain ([107.108.73.37]) by mmp2.samsung.com (Oracle Communications Messaging Exchange Server 7u4-19.01 64bit (built Sep 7 2010)) with ESMTPA id <0LVU00BJT6TAY680@mmp2.samsung.com> for patches@linaro.org; Wed, 07 Dec 2011 22:58:31 +0900 (KST) From: Thomas Abraham To: linux-samsung-soc@vger.kernel.org Cc: linux-arm-kernel@lists.infradead.org, kgene.kim@samsung.com, patches@linaro.org, Grant Likely Subject: [PATCH 2/4] arm: exynos4: add irq_domain support for wakeup interrupts Date: Wed, 07 Dec 2011 19:29:50 +0530 Message-id: <1323266392-28330-3-git-send-email-thomas.abraham@linaro.org> X-Mailer: git-send-email 1.6.6.rc2 In-reply-to: <1323266392-28330-2-git-send-email-thomas.abraham@linaro.org> References: <1323266392-28330-1-git-send-email-thomas.abraham@linaro.org> <1323266392-28330-2-git-send-email-thomas.abraham@linaro.org> X-Brightmail-Tracker: AAAAAA== Add irq_domain support for the 32 wakeup interrupt sources. Cc: Grant Likely Signed-off-by: Thomas Abraham --- arch/arm/mach-exynos/include/mach/regs-gpio.h | 4 +- arch/arm/mach-exynos/irq-eint.c | 69 ++++++++++++++++--------- 2 files changed, 46 insertions(+), 27 deletions(-) diff --git a/arch/arm/mach-exynos/include/mach/regs-gpio.h b/arch/arm/mach-exynos/include/mach/regs-gpio.h index 1401b21..2e6ec6b 100644 --- a/arch/arm/mach-exynos/include/mach/regs-gpio.h +++ b/arch/arm/mach-exynos/include/mach/regs-gpio.h @@ -28,9 +28,9 @@ #define EXYNOS4_EINT40PEND (S5P_VA_GPIO2 + 0xF40) #define S5P_EINT_PEND(x) (EXYNOS4_EINT40PEND + ((x) * 0x4)) -#define EINT_REG_NR(x) (EINT_OFFSET(x) >> 3) +#define EINT_REG_NR(x) ((x) >> 3) -#define eint_irq_to_bit(irq) (1 << (EINT_OFFSET(irq) & 0x7)) +#define eint_irq_to_bit(irq) (1 << ((irq) & 0x7)) #define EINT_MODE S3C_GPIO_SFN(0xf) diff --git a/arch/arm/mach-exynos/irq-eint.c b/arch/arm/mach-exynos/irq-eint.c index 5e89412..a65da64 100644 --- a/arch/arm/mach-exynos/irq-eint.c +++ b/arch/arm/mach-exynos/irq-eint.c @@ -16,6 +16,8 @@ #include #include #include +#include +#include #include #include @@ -28,17 +30,19 @@ static DEFINE_SPINLOCK(eint_lock); static unsigned int eint0_15_data[16]; +static struct irq_domain exynos4_eint_irq_domain; #define exynos4_irq_eint_to_gic_irq(number) (IRQ_EINT0 + number) +#define EXYNOS4_EINT_NR 32 static inline void exynos4_irq_eint_mask(struct irq_data *data) { u32 mask; spin_lock(&eint_lock); - mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(data->irq))); - mask |= eint_irq_to_bit(data->irq); - __raw_writel(mask, S5P_EINT_MASK(EINT_REG_NR(data->irq))); + mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(data->hwirq))); + mask |= eint_irq_to_bit(data->hwirq); + __raw_writel(mask, S5P_EINT_MASK(EINT_REG_NR(data->hwirq))); spin_unlock(&eint_lock); } @@ -47,16 +51,16 @@ static void exynos4_irq_eint_unmask(struct irq_data *data) u32 mask; spin_lock(&eint_lock); - mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(data->irq))); - mask &= ~(eint_irq_to_bit(data->irq)); - __raw_writel(mask, S5P_EINT_MASK(EINT_REG_NR(data->irq))); + mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(data->hwirq))); + mask &= ~(eint_irq_to_bit(data->hwirq)); + __raw_writel(mask, S5P_EINT_MASK(EINT_REG_NR(data->hwirq))); spin_unlock(&eint_lock); } static inline void exynos4_irq_eint_ack(struct irq_data *data) { - __raw_writel(eint_irq_to_bit(data->irq), - S5P_EINT_PEND(EINT_REG_NR(data->irq))); + __raw_writel(eint_irq_to_bit(data->hwirq), + S5P_EINT_PEND(EINT_REG_NR(data->hwirq))); } static void exynos4_irq_eint_maskack(struct irq_data *data) @@ -67,7 +71,7 @@ static void exynos4_irq_eint_maskack(struct irq_data *data) static int exynos4_irq_eint_set_type(struct irq_data *data, unsigned int type) { - int offs = EINT_OFFSET(data->irq); + int offs = data->hwirq; int shift; u32 ctrl, mask; u32 newvalue = 0; @@ -102,10 +106,10 @@ static int exynos4_irq_eint_set_type(struct irq_data *data, unsigned int type) mask = 0x7 << shift; spin_lock(&eint_lock); - ctrl = __raw_readl(S5P_EINT_CON(EINT_REG_NR(data->irq))); + ctrl = __raw_readl(S5P_EINT_CON(EINT_REG_NR(data->hwirq))); ctrl &= ~mask; ctrl |= newvalue << shift; - __raw_writel(ctrl, S5P_EINT_CON(EINT_REG_NR(data->irq))); + __raw_writel(ctrl, S5P_EINT_CON(EINT_REG_NR(data->hwirq))); spin_unlock(&eint_lock); switch (offs) { @@ -148,19 +152,19 @@ static struct irq_chip exynos4_irq_eint = { * * Each EINT pend/mask registers handle eight of them. */ -static inline void exynos4_irq_demux_eint(unsigned int start) +static inline void exynos4_irq_demux_eint(unsigned int base, unsigned int offs) { unsigned int irq; - u32 status = __raw_readl(S5P_EINT_PEND(EINT_REG_NR(start))); - u32 mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(start))); + u32 status = __raw_readl(S5P_EINT_PEND(EINT_REG_NR(offs))); + u32 mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(offs))); status &= ~mask; status &= 0xff; while (status) { irq = fls(status) - 1; - generic_handle_irq(irq + start); + generic_handle_irq(irq + offs + base); status &= ~(1 << irq); } } @@ -168,9 +172,11 @@ static inline void exynos4_irq_demux_eint(unsigned int start) static void exynos4_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc) { struct irq_chip *chip = irq_get_chip(irq); + u32 *irq_data = irq_get_handler_data(irq); + chained_irq_enter(chip, desc); - exynos4_irq_demux_eint(IRQ_EINT(16)); - exynos4_irq_demux_eint(IRQ_EINT(24)); + exynos4_irq_demux_eint(*irq_data, 16); + exynos4_irq_demux_eint(*irq_data, 24); chained_irq_exit(chip, desc); } @@ -193,22 +199,35 @@ static void exynos4_irq_eint0_15(unsigned int irq, struct irq_desc *desc) int __init exynos4_init_irq_eint(void) { - int irq; + int irq, hwirq; + struct irq_domain *domain = &exynos4_eint_irq_domain; + + domain->irq_base = irq_alloc_descs(IRQ_EINT(0), IRQ_EINT(0), + EXYNOS4_EINT_NR, 0); + if (domain->irq_base < 0) { + pr_err("exynos4_init_irq_eint: Failed to alloc irq descs\n"); + return -EBUSY; + } + domain->nr_irq = EXYNOS4_EINT_NR; + domain->ops = &irq_domain_simple_ops; + irq_domain_add(domain); - for (irq = 0 ; irq <= 31 ; irq++) { - irq_set_chip_and_handler(IRQ_EINT(irq), &exynos4_irq_eint, + irq_domain_for_each_irq(domain, hwirq, irq) { + irq_set_chip_and_handler(irq, &exynos4_irq_eint, handle_level_irq); - set_irq_flags(IRQ_EINT(irq), IRQF_VALID); + set_irq_flags(irq, IRQF_VALID); } irq_set_chained_handler(IRQ_EINT16_31, exynos4_irq_demux_eint16_31); + irq_set_handler_data(IRQ_EINT16_31, &domain->irq_base); - for (irq = 0 ; irq <= 15 ; irq++) { - eint0_15_data[irq] = IRQ_EINT(irq); + for (hwirq = 0 ; hwirq <= 15 ; hwirq++) { + irq = irq_domain_to_irq(domain, hwirq); + eint0_15_data[irq] = irq; - irq_set_handler_data(exynos4_irq_eint_to_gic_irq(irq), + irq_set_handler_data(exynos4_irq_eint_to_gic_irq(hwirq), &eint0_15_data[irq]); - irq_set_chained_handler(exynos4_irq_eint_to_gic_irq(irq), + irq_set_chained_handler(exynos4_irq_eint_to_gic_irq(hwirq), exynos4_irq_eint0_15); }