From patchwork Thu Jun 5 09:53:09 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Thompson X-Patchwork-Id: 31405 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-oa0-f69.google.com (mail-oa0-f69.google.com [209.85.219.69]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id DBF94203AC for ; Thu, 5 Jun 2014 09:53:33 +0000 (UTC) Received: by mail-oa0-f69.google.com with SMTP id i7sf3824421oag.8 for ; Thu, 05 Jun 2014 02:53:33 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:from:to:cc:subject :date:message-id:in-reply-to:references:x-original-sender :x-original-authentication-results:precedence:mailing-list:list-id :list-post:list-help:list-archive:list-unsubscribe; bh=wjTL2cu95LrQctJxMa50L5z8mdjdbp5V+4V8ht7ITiU=; b=gU72Hv6QuU/QF7hkG41s+z8MdLAMzMjcCKAWwPbMBSTkMsxa4sAG3YEM2L5GgzDRHe YwTl+64gn0qRTBEugCixgQiHxivU7ddjO2q267rslvTrnJPILww9ZuBSrv/O5adBBscn PDcl1v1dXQZ6JKpR6GRjqrZa2R2CriDENKLhA4eXAjcjgHyvzrKiKfN+2P3EKdVyoUdD q2TH455uDq7wL5BN3d0y8jlz1ToK/3Y8S0pNyiYnY6CHpwTXJ8sknMdSWqrxPZFOM9hV Va9oCvNznQJjt2qbHfFVpsv7pZOs1r6gPkKTMjt8TjtdQtkiINfZNLrZBmeYMSxeKzVv I3iQ== X-Gm-Message-State: ALoCoQlzHVljYVks4Z4/6Iqm0jfIdn8F0nDK2zyUY3r4GwDqpNeDtT/NPg+yejIZk80Kfcy6cj5X X-Received: by 10.182.137.233 with SMTP id ql9mr13247295obb.46.1401962013423; Thu, 05 Jun 2014 02:53:33 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.83.50 with SMTP id i47ls73158qgd.38.gmail; Thu, 05 Jun 2014 02:53:33 -0700 (PDT) X-Received: by 10.52.141.74 with SMTP id rm10mr41495831vdb.6.1401962013315; Thu, 05 Jun 2014 02:53:33 -0700 (PDT) Received: from mail-ve0-f178.google.com (mail-ve0-f178.google.com [209.85.128.178]) by mx.google.com with ESMTPS id 3si2166911vcs.47.2014.06.05.02.53.33 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 05 Jun 2014 02:53:33 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.128.178 as permitted sender) client-ip=209.85.128.178; Received: by mail-ve0-f178.google.com with SMTP id sa20so857369veb.23 for ; Thu, 05 Jun 2014 02:53:33 -0700 (PDT) X-Received: by 10.53.8.162 with SMTP id dl2mr31238304vdd.24.1401962013214; Thu, 05 Jun 2014 02:53:33 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patches@linaro.org Received: by 10.221.54.6 with SMTP id vs6csp3725vcb; Thu, 5 Jun 2014 02:53:32 -0700 (PDT) X-Received: by 10.180.94.163 with SMTP id dd3mr14048325wib.26.1401962012259; Thu, 05 Jun 2014 02:53:32 -0700 (PDT) Received: from mail-wi0-f181.google.com (mail-wi0-f181.google.com [209.85.212.181]) by mx.google.com with ESMTPS id x8si40259136wiv.44.2014.06.05.02.53.31 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 05 Jun 2014 02:53:32 -0700 (PDT) Received-SPF: pass (google.com: domain of daniel.thompson@linaro.org designates 209.85.212.181 as permitted sender) client-ip=209.85.212.181; Received: by mail-wi0-f181.google.com with SMTP id n15so3092003wiw.2 for ; Thu, 05 Jun 2014 02:53:31 -0700 (PDT) X-Received: by 10.194.174.168 with SMTP id bt8mr14218814wjc.72.1401962011639; Thu, 05 Jun 2014 02:53:31 -0700 (PDT) Received: from sundance.lan (cpc4-aztw19-0-0-cust157.18-1.cable.virginm.net. [82.33.25.158]) by mx.google.com with ESMTPSA id s3sm7337863wje.36.2014.06.05.02.53.29 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 05 Jun 2014 02:53:30 -0700 (PDT) From: Daniel Thompson To: Jason Wessel Cc: Daniel Thompson , kgdb-bugreport@lists.sourceforge.net, patches@linaro.org, linux-arm-kernel@lists.infradead.org, linaro-kernel@lists.linaro.org, linux-kernel@vger.kernel.org, John Stultz , Anton Vorontsov , Colin Cross , Dirk Behme , kernel-team@android.com, Russell King , Rob Herring , Pawel Moll , Mark Rutland , Ian Campbell , Kumar Gala , Thomas Gleixner , Greg Kroah-Hartman , Jiri Slaby , "David A. Long" , Nicolas Pitre , Catalin Marinas , Frederic Weisbecker , Linus Walleij , Christoffer Dall , kernel@stlinux.com, devicetree@vger.kernel.org, linux-serial@vger.kernel.org, Jason Cooper , Nicolas Pitre , Sricharan R Subject: [RFC v3 4/9] irqchip: gic: Introduce shadow irqs for FIQ Date: Thu, 5 Jun 2014 10:53:09 +0100 Message-Id: <1401961994-18033-5-git-send-email-daniel.thompson@linaro.org> X-Mailer: git-send-email 1.9.0 In-Reply-To: <1401961994-18033-1-git-send-email-daniel.thompson@linaro.org> References: <1400853478-5824-1-git-send-email-daniel.thompson@linaro.org> <1401961994-18033-1-git-send-email-daniel.thompson@linaro.org> X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: daniel.thompson@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.128.178 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Precedence: list Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org List-ID: X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , This patch registers two virqs for each interrupt source it supports. Using multiple virqs allows the GIC driver to automatically modify the group register, allowing the new virqs to be used as argument to enable_fiq(). This also allows FIQ resources to be described in the device tree's interrupt list using a special flag (currently 0x80). Both these aspects combine and allow a driver to deploy a FIQ handler without any machine specific knowledge; it can be used effectively on multi-arch kernels. Signed-off-by: Daniel Thompson Cc: Thomas Gleixner Cc: Jason Cooper Cc: Nicolas Pitre Cc: Christoffer Dall Cc: Sricharan R --- drivers/irqchip/irq-gic.c | 62 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 56 insertions(+), 6 deletions(-) diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index aa8efe4..9a4712d 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c @@ -42,12 +42,17 @@ #include #include +#ifdef CONFIG_FIQ +#include +#endif #include #include #include #include "irqchip.h" +#define GIC_INTSPEC_IRQ_IS_FIQ (1 << 7) + union gic_base { void __iomem *common_base; void __percpu * __iomem *percpu_base; @@ -65,6 +70,7 @@ struct gic_chip_data { #endif struct irq_domain *domain; unsigned int gic_irqs; + unsigned int fiq_shadow_offset; #ifdef CONFIG_GIC_NON_BANKED void __iomem *(*get_base)(union gic_base *); #endif @@ -143,11 +149,34 @@ static inline void __iomem *gic_cpu_base(struct irq_data *d) return gic_data_cpu_base(gic_data); } +static inline bool gic_is_fiq(struct irq_data *d) +{ + struct gic_chip_data *gic_data = irq_data_get_irq_chip_data(d); + return d->hwirq > gic_data->gic_irqs; +} + static inline unsigned int gic_irq(struct irq_data *d) { + struct gic_chip_data *gic_data = irq_data_get_irq_chip_data(d); + if (gic_is_fiq(d)) + return d->hwirq - gic_data->fiq_shadow_offset; return d->hwirq; } +static void gic_set_group_irq(struct irq_data *d, int group) +{ + unsigned int reg = gic_irq(d) / 32 * 4; + u32 mask = 1 << (gic_irq(d) % 32); + u32 val; + + val = readl_relaxed(gic_dist_base(d) + GIC_DIST_IGROUP + reg); + if (group) + val |= mask; + else + val &= ~mask; + writel_relaxed(val, gic_dist_base(d) + GIC_DIST_IGROUP + reg); +} + /* * Routines to acknowledge, disable and enable interrupts */ @@ -159,6 +188,8 @@ static void gic_mask_irq(struct irq_data *d) writel_relaxed(mask, gic_dist_base(d) + GIC_DIST_ENABLE_CLEAR + (gic_irq(d) / 32) * 4); if (gic_arch_extn.irq_mask) gic_arch_extn.irq_mask(d); + if (gic_is_fiq(d)) + gic_set_group_irq(d, 1); raw_spin_unlock(&irq_controller_lock); } @@ -167,6 +198,8 @@ static void gic_unmask_irq(struct irq_data *d) u32 mask = 1 << (gic_irq(d) % 32); raw_spin_lock(&irq_controller_lock); + if (gic_is_fiq(d)) + gic_set_group_irq(d, 0); if (gic_arch_extn.irq_unmask) gic_arch_extn.irq_unmask(d); writel_relaxed(mask, gic_dist_base(d) + GIC_DIST_ENABLE_SET + (gic_irq(d) / 32) * 4); @@ -940,7 +973,12 @@ static int gic_routable_irq_domain_xlate(struct irq_domain *d, unsigned long *out_hwirq, unsigned int *out_type) { + struct gic_chip_data *gic_data = d->host_data; *out_hwirq += 16; + + if (intspec[2] & GIC_INTSPEC_IRQ_IS_FIQ) + *out_hwirq += gic_data->fiq_shadow_offset; + return 0; } @@ -1026,10 +1064,11 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start, gic->gic_irqs = gic_irqs; gic_irqs -= hwirq_base; /* calculate # of irqs to allocate */ + gic->fiq_shadow_offset = gic_irqs; if (of_property_read_u32(node, "arm,routable-irqs", &nr_routable_irqs)) { - irq_base = irq_alloc_descs(irq_start, 16, gic_irqs, + irq_base = irq_alloc_descs(irq_start, 16, 2 * gic_irqs, numa_node_id()); if (IS_ERR_VALUE(irq_base)) { WARN(1, "Cannot allocate irq_descs @ IRQ%d, assuming pre-allocated\n", @@ -1037,17 +1076,28 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start, irq_base = irq_start; } - gic->domain = irq_domain_add_legacy(node, gic_irqs, irq_base, - hwirq_base, &gic_irq_domain_ops, gic); + gic->domain = + irq_domain_add_legacy(node, 2 * gic_irqs, irq_base, + hwirq_base, &gic_irq_domain_ops, gic); } else { - gic->domain = irq_domain_add_linear(node, nr_routable_irqs, - &gic_irq_domain_ops, - gic); + gic->domain = irq_domain_add_linear(node, 2 * nr_routable_irqs, + &gic_irq_domain_ops, gic); } if (WARN_ON(!gic->domain)) return; +#ifdef CONFIG_FIQ + /* FIQ can only be supported on platforms without an extended irq_eoi + * method (otherwise we take a lock during irq_eoi handling). + */ + if (!gic_arch_extn.irq_eoi) + fiq_add_mapping( + irq_linear_revmap(gic->domain, hwirq_base), + irq_linear_revmap(gic->domain, hwirq_base + gic_irqs), + gic_irqs); +#endif + if (gic_nr == 0) { #ifdef CONFIG_SMP set_smp_cross_call(gic_raise_softirq);