From patchwork Fri Oct 26 23:32:52 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 1654471 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) by patchwork1.kernel.org (Postfix) with ESMTP id BA30840135 for ; Fri, 26 Oct 2012 23:35:21 +0000 (UTC) Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1TRtOr-0007XP-Kt; Fri, 26 Oct 2012 23:33:13 +0000 Received: from mail.df.lth.se ([194.47.250.12]) by merlin.infradead.org with esmtps (Exim 4.76 #1 (Red Hat Linux)) id 1TRtOn-0007Wy-Hz for linux-arm-kernel@lists.infradead.org; Fri, 26 Oct 2012 23:33:11 +0000 Received: from mer.df.lth.se (mer.df.lth.se [194.47.250.37]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mail.df.lth.se (Postfix) with ESMTPS id 64A7265DB8; Sat, 27 Oct 2012 01:32:59 +0200 (CEST) Received: from mer.df.lth.se (triad@localhost.localdomain [127.0.0.1]) by mer.df.lth.se (8.14.3/8.14.3/Debian-9.4) with ESMTP id q9QNWxTY027624; Sat, 27 Oct 2012 01:32:59 +0200 Received: (from triad@localhost) by mer.df.lth.se (8.14.3/8.14.3/Submit) id q9QNWuE4027623; Sat, 27 Oct 2012 01:32:56 +0200 From: Linus Walleij To: linux-arm-kernel@lists.infradead.org Subject: [PATCH 1/2] ARM: plat-versatile: use simple irqdomain for FPGA IRQ Date: Sat, 27 Oct 2012 01:32:52 +0200 Message-Id: <1351294372-27596-1-git-send-email-linus.walleij@linaro.org> X-Mailer: git-send-email 1.7.2.5 X-Spam-Note: CRM114 invocation failed X-Spam-Score: -3.3 (---) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-3.3 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.7 RCVD_IN_DNSWL_LOW RBL: Sender listed at http://www.dnswl.org/, low trust [194.47.250.12 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record -0.7 RP_MATCHES_RCVD Envelope sender domain matches handover relay domain -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] Cc: Linus Walleij , Rob Herring X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.14 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 This switches the FPGA IRQ driver over to using the simple IRQ domain. We can then use the same codepath for this in the DT and non-DT cases. To be able to use quicker irq_find_mapping() in the handlers we first call irq_create_mapping() on all the valid HW IRQ numbers so that descriptors will be created for them in the DT case where a linear domain will be the outcome of the call. Signed-off-by: Linus Walleij --- arch/arm/plat-versatile/fpga-irq.c | 50 +++++++++++++++++--------------------- 1 file changed, 22 insertions(+), 28 deletions(-) diff --git a/arch/arm/plat-versatile/fpga-irq.c b/arch/arm/plat-versatile/fpga-irq.c index 091ae10..dfe317c 100644 --- a/arch/arm/plat-versatile/fpga-irq.c +++ b/arch/arm/plat-versatile/fpga-irq.c @@ -1,6 +1,7 @@ /* * Support for Versatile FPGA-based IRQ controllers */ +#include #include #include #include @@ -117,13 +118,12 @@ static int fpga_irqdomain_map(struct irq_domain *d, unsigned int irq, struct fpga_irq_data *f = d->host_data; /* Skip invalid IRQs, only register handlers for the real ones */ - if (!(f->valid & (1 << hwirq))) + if (!(f->valid & BIT(hwirq))) return -ENOTSUPP; irq_set_chip_data(irq, f); irq_set_chip_and_handler(irq, &f->chip, handle_level_irq); set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); - f->used_irqs++; return 0; } @@ -132,13 +132,15 @@ static struct irq_domain_ops fpga_irqdomain_ops = { .xlate = irq_domain_xlate_onetwocell, }; -static __init struct fpga_irq_data * -fpga_irq_prep_struct(void __iomem *base, const char *name, u32 valid) { +void __init fpga_irq_init(void __iomem *base, const char *name, int irq_start, + int parent_irq, u32 valid, struct device_node *node) +{ struct fpga_irq_data *f; + int i; if (fpga_irq_id >= ARRAY_SIZE(fpga_irq_devices)) { - printk(KERN_ERR "%s: too few FPGA IRQ controllers, increase CONFIG_PLAT_VERSATILE_FPGA_IRQ_NR\n", __func__); - return NULL; + pr_err("%s: too few FPGA IRQ controllers, increase CONFIG_PLAT_VERSATILE_FPGA_IRQ_NR\n", __func__); + return; } f = &fpga_irq_devices[fpga_irq_id]; f->base = base; @@ -147,29 +149,28 @@ fpga_irq_prep_struct(void __iomem *base, const char *name, u32 valid) { f->chip.irq_mask = fpga_irq_mask; f->chip.irq_unmask = fpga_irq_unmask; f->valid = valid; - fpga_irq_id++; - - return f; -} - -void __init fpga_irq_init(void __iomem *base, const char *name, int irq_start, - int parent_irq, u32 valid, struct device_node *node) -{ - struct fpga_irq_data *f; - - f = fpga_irq_prep_struct(base, name, valid); - if (!f) - return; if (parent_irq != -1) { irq_set_handler_data(parent_irq, f); irq_set_chained_handler(parent_irq, fpga_irq_handle); } - f->domain = irq_domain_add_legacy(node, fls(valid), irq_start, 0, + /* This will also allocate irq descriptors */ + f->domain = irq_domain_add_simple(node, fls(valid), irq_start, &fpga_irqdomain_ops, f); + + /* This will allocate all valid descriptors in the linear case */ + for (i = 0; i < fls(valid); i++) + if (valid & BIT(i)) { + if (!irq_start) + irq_create_mapping(f->domain, i); + f->used_irqs++; + } + pr_info("FPGA IRQ chip %d \"%s\" @ %p, %u irqs\n", fpga_irq_id, name, base, f->used_irqs); + + fpga_irq_id++; } #ifdef CONFIG_OF @@ -193,18 +194,11 @@ int __init fpga_irq_of_init(struct device_node *node, if (of_property_read_u32(node, "valid-mask", &valid_mask)) valid_mask = 0; - f = fpga_irq_prep_struct(base, node->name, valid_mask); - if (!f) - return -ENOMEM; + fpga_irq_init(base, node->name, 0, -1, valid_mask, node); writel(clear_mask, base + IRQ_ENABLE_CLEAR); writel(clear_mask, base + FIQ_ENABLE_CLEAR); - f->domain = irq_domain_add_linear(node, fls(valid_mask), &fpga_irqdomain_ops, f); - f->used_irqs = hweight32(valid_mask); - - pr_info("FPGA IRQ chip %d \"%s\" @ %p, %u irqs\n", - fpga_irq_id, node->name, base, f->used_irqs); return 0; } #endif