From patchwork Fri May 23 13:57:51 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Thompson X-Patchwork-Id: 30785 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-ie0-f198.google.com (mail-ie0-f198.google.com [209.85.223.198]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 1B32420369 for ; Fri, 23 May 2014 13:58:22 +0000 (UTC) Received: by mail-ie0-f198.google.com with SMTP id tp5sf23583187ieb.1 for ; Fri, 23 May 2014 06:58:21 -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=gsyEaOxEzuaSfLkAGX6WCS1oGwLiUtHmUjsdrZ/PVrA=; b=DqfzvqoJhpUkKEoQUMOW40CVubcAM2IvQOfmllaxQR4eYUYDYFmrO1+1JUC+med6j3 lGleUN1hDoMxB/3FbVGMABVCG1tUpqxIHt8lADQl+APLZpIz4sXSKsRnGRq95tAkA7WF vwNYICR3A6DvqXXGA76ACPVvzQkscmm6xTqak+j23XXioY5wwNz/bp1LfPu21Cfsqhv8 x8q8JXEJTMaZj6IuowQKa9KvxXrEJaZnL8TAiICjzDXT+T97dtDHJ0dQW7WrosK5qQBu LB1c3Vk65p/QHLmEpWH4ZODsSb687LlJvVa8RXpLy3KIKIMfVtaeaol4a0G1M8vhWP1f iOxA== X-Gm-Message-State: ALoCoQnXOO6uG6RMa9En7THVv1DIh+3Zr0Wd7KsWFGBKAKEK1mxzdzPFsbc54egFhuQIkV5e4BYT X-Received: by 10.43.124.136 with SMTP id go8mr1966541icc.26.1400853501577; Fri, 23 May 2014 06:58:21 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.97.200 with SMTP id m66ls1721345qge.83.gmail; Fri, 23 May 2014 06:58:21 -0700 (PDT) X-Received: by 10.52.61.139 with SMTP id p11mr654183vdr.49.1400853501462; Fri, 23 May 2014 06:58:21 -0700 (PDT) Received: from mail-vc0-f169.google.com (mail-vc0-f169.google.com [209.85.220.169]) by mx.google.com with ESMTPS id hd1si1659784veb.48.2014.05.23.06.58.21 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Fri, 23 May 2014 06:58:21 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.220.169 as permitted sender) client-ip=209.85.220.169; Received: by mail-vc0-f169.google.com with SMTP id ij19so6327275vcb.0 for ; Fri, 23 May 2014 06:58:21 -0700 (PDT) X-Received: by 10.52.181.132 with SMTP id dw4mr448780vdc.86.1400853501382; Fri, 23 May 2014 06:58:21 -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.220.221.72 with SMTP id ib8csp33811vcb; Fri, 23 May 2014 06:58:21 -0700 (PDT) X-Received: by 10.180.13.139 with SMTP id h11mr3473969wic.34.1400853500788; Fri, 23 May 2014 06:58:20 -0700 (PDT) Received: from mail-wi0-f177.google.com (mail-wi0-f177.google.com [209.85.212.177]) by mx.google.com with ESMTPS id g4si2576597wje.83.2014.05.23.06.58.20 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Fri, 23 May 2014 06:58:20 -0700 (PDT) Received-SPF: pass (google.com: domain of daniel.thompson@linaro.org designates 209.85.212.177 as permitted sender) client-ip=209.85.212.177; Received: by mail-wi0-f177.google.com with SMTP id f8so917485wiw.4 for ; Fri, 23 May 2014 06:58:20 -0700 (PDT) X-Received: by 10.194.246.234 with SMTP id xz10mr2350124wjc.77.1400853500271; Fri, 23 May 2014 06:58:20 -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 l4sm4016261wjf.14.2014.05.23.06.58.17 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 23 May 2014 06:58:19 -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 v2 03/10] irqchip: gic: Introduce shadow irqs for FIQ Date: Fri, 23 May 2014 14:57:51 +0100 Message-Id: <1400853478-5824-4-git-send-email-daniel.thompson@linaro.org> X-Mailer: git-send-email 1.9.0 In-Reply-To: <1400853478-5824-1-git-send-email-daniel.thompson@linaro.org> References: <1400083125-1464-1-git-send-email-daniel.thompson@linaro.org> <1400853478-5824-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.220.169 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 | 46 +++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 41 insertions(+), 5 deletions(-) diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index aa8efe4..0c259ac 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c @@ -48,6 +48,8 @@ #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 +67,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 +146,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 +185,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 +195,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 +970,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 +1061,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,12 +1073,12 @@ 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_irq_domain_ops, gic); } if (WARN_ON(!gic->domain))