From patchwork Tue Aug 19 16:46:01 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Thompson X-Patchwork-Id: 35636 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-pa0-f70.google.com (mail-pa0-f70.google.com [209.85.220.70]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 09488202DD for ; Tue, 19 Aug 2014 16:51:01 +0000 (UTC) Received: by mail-pa0-f70.google.com with SMTP id lf10sf59211501pab.5 for ; Tue, 19 Aug 2014 09:51:01 -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=i2Q2AN+tHwpMat0v/qWydSk2AfBq/57IYzeQ2xsxJro=; b=ESBSmMM1A5uxiKrx2jZa91nAyudrhkmcYEyCgMPv4eFADqVDmFvTWIJe8bM6wMlieJ abU2dap4leks9cNLM6s/yySaRJL7TXYP06jg90QZog+gqZYTGHqX/7D45wuda7S5R8BB 0AQ8JZecmQCo4L773VGN/pUV6QuJ0viVjkhrNhTcjXs4B0AJLwL+eIw5TfJ614H2zxCP GKuBKfLHfBsGTazX0tterszahNAij83NDD4PmxW2L9p0Zx8Mg6OytjOaslCGscjO5c/w qcA1K1ShQcQDPVZAlbkegYYdHqh0L6Dh0JNJSX/EIv/SK8Ase3lkL1eAmshSfnKo7G16 kRIQ== X-Gm-Message-State: ALoCoQneVKlREcV71t76OsDukg5w6KPUApM0kAjfoUw4bm0ycHg0MidJ9Fy3AJ9Fb1ylabFzCE0F X-Received: by 10.70.34.195 with SMTP id b3mr22426652pdj.7.1408467058949; Tue, 19 Aug 2014 09:50:58 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.34.99 with SMTP id k90ls3060255qgk.78.gmail; Tue, 19 Aug 2014 09:50:58 -0700 (PDT) X-Received: by 10.52.245.101 with SMTP id xn5mr12967317vdc.32.1408467058670; Tue, 19 Aug 2014 09:50:58 -0700 (PDT) Received: from mail-vc0-f175.google.com (mail-vc0-f175.google.com [209.85.220.175]) by mx.google.com with ESMTPS id fu10si9120369vdb.95.2014.08.19.09.50.58 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Tue, 19 Aug 2014 09:50:58 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.220.175 as permitted sender) client-ip=209.85.220.175; Received: by mail-vc0-f175.google.com with SMTP id ik5so7593897vcb.6 for ; Tue, 19 Aug 2014 09:50:58 -0700 (PDT) X-Received: by 10.52.73.202 with SMTP id n10mr557703vdv.86.1408467058552; Tue, 19 Aug 2014 09:50:58 -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.37.5 with SMTP id tc5csp254657vcb; Tue, 19 Aug 2014 09:50:57 -0700 (PDT) X-Received: by 10.194.118.232 with SMTP id kp8mr52107150wjb.42.1408467057138; Tue, 19 Aug 2014 09:50:57 -0700 (PDT) Received: from mail-we0-f172.google.com (mail-we0-f172.google.com [74.125.82.172]) by mx.google.com with ESMTPS id vr4si15570499wjc.138.2014.08.19.09.50.56 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Tue, 19 Aug 2014 09:50:57 -0700 (PDT) Received-SPF: pass (google.com: domain of daniel.thompson@linaro.org designates 74.125.82.172 as permitted sender) client-ip=74.125.82.172; Received: by mail-we0-f172.google.com with SMTP id x48so6778706wes.3 for ; Tue, 19 Aug 2014 09:50:56 -0700 (PDT) X-Received: by 10.194.63.205 with SMTP id i13mr52318988wjs.74.1408467056645; Tue, 19 Aug 2014 09:50:56 -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 gc8sm36225wic.3.2014.08.19.09.50.54 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 19 Aug 2014 09:50:55 -0700 (PDT) From: Daniel Thompson To: Russell King Cc: Daniel Thompson , linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, kgdb-bugreport@lists.sourceforge.net, patches@linaro.org, linaro-kernel@lists.linaro.org, John Stultz , Anton Vorontsov , Colin Cross , kernel-team@android.com, Rob Herring , Linus Walleij , Ben Dooks , Catalin Marinas , Dave Martin , Fabio Estevam , Frederic Weisbecker , Nicolas Pitre , Hartley Sweeten , Ryan Mallon , Ben Dooks , Kukjin Kim , Thomas Gleixner , Jason Cooper , linux-samsung-soc@vger.kernel.org Subject: [PATCH v10 11/19] irqchip: vic: Add support for FIQ management Date: Tue, 19 Aug 2014 17:46:01 +0100 Message-Id: <1408466769-20004-12-git-send-email-daniel.thompson@linaro.org> X-Mailer: git-send-email 1.9.3 In-Reply-To: <1408466769-20004-1-git-send-email-daniel.thompson@linaro.org> References: <1408369264-14242-1-git-send-email-daniel.thompson@linaro.org> <1408466769-20004-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.175 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 introduces callbacks to route interrupts to or away from the FIQ signal. It also causes these callbacks to be registered with the FIQ infrastructure. This patch enable FIQ support for mach-versatile whilst mach-ep93xx, mach-netx, mach-s3c64xx and plat-samsung are unmodified (and can therefore continue to use init_FIQ() as before). Signed-off-by: Daniel Thompson Cc: Hartley Sweeten Cc: Ryan Mallon Cc: Russell King Cc: Ben Dooks Cc: Kukjin Kim Cc: Thomas Gleixner Cc: Jason Cooper Cc: linux-samsung-soc@vger.kernel.org --- arch/arm/mach-versatile/core.c | 2 +- drivers/irqchip/irq-vic.c | 92 ++++++++++++++++++++++++++++++++--------- include/linux/irqchip/arm-vic.h | 6 ++- 3 files changed, 78 insertions(+), 22 deletions(-) diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c index 08fb8c8..bad1d30 100644 --- a/arch/arm/mach-versatile/core.c +++ b/arch/arm/mach-versatile/core.c @@ -108,7 +108,7 @@ void __init versatile_init_irq(void) np = of_find_matching_node_by_address(NULL, vic_of_match, VERSATILE_VIC_BASE); - __vic_init(VA_VIC_BASE, 0, IRQ_VIC_START, ~0, 0, np); + __vic_init(VA_VIC_BASE, 0, IRQ_VIC_START, ~0, 0, np ? false : true, np); writel(~0, VA_SIC_BASE + SIC_IRQ_ENABLE_CLEAR); diff --git a/drivers/irqchip/irq-vic.c b/drivers/irqchip/irq-vic.c index 7d35287..22aa126 100644 --- a/drivers/irqchip/irq-vic.c +++ b/drivers/irqchip/irq-vic.c @@ -36,6 +36,9 @@ #include #include +#ifdef CONFIG_FIQ +#include +#endif #include "irqchip.h" @@ -261,11 +264,53 @@ static struct irq_domain_ops vic_irqdomain_ops = { .xlate = irq_domain_xlate_onetwocell, }; +#ifdef CONFIG_FIQ +static DEFINE_RAW_SPINLOCK(irq_controller_lock); + +static void vic_set_fiq(struct irq_data *d, bool enable) +{ + void __iomem *base = irq_data_get_irq_chip_data(d); + unsigned int irq = d->hwirq; + u32 val; + + raw_spin_lock(&irq_controller_lock); + val = readl(base + VIC_INT_SELECT); + if (enable) + val |= 1 << irq; + else + val &= ~(1 << irq); + writel(val, base + VIC_INT_SELECT); + raw_spin_unlock(&irq_controller_lock); +} + +static void vic_enable_fiq(struct irq_data *d) +{ + vic_set_fiq(d, true); +} + +static void vic_disable_fiq(struct irq_data *d) +{ + vic_set_fiq(d, false); +} + +struct fiq_chip vic_fiq = { + .fiq_enable = vic_enable_fiq, + .fiq_disable = vic_disable_fiq, +}; + +static void vic_register_fiq(int irq) +{ + fiq_register_mapping(irq, &vic_fiq); +} +#else /* CONFIG_FIQ */ +static inline void vic_register_fiq(int irq) {} +#endif /* CONFIG_FIQ */ + /** * vic_register() - Register a VIC. * @base: The base address of the VIC. * @parent_irq: The parent IRQ if cascaded, else 0. - * @irq: The base IRQ for the VIC. + * @irq_start: The base IRQ for the VIC. * @valid_sources: bitmask of valid interrupts * @resume_sources: bitmask of interrupts allowed for resume sources. * @node: The device tree node associated with the VIC. @@ -277,12 +322,13 @@ static struct irq_domain_ops vic_irqdomain_ops = { * This also configures the IRQ domain for the VIC. */ static void __init vic_register(void __iomem *base, unsigned int parent_irq, - unsigned int irq, + unsigned int irq_start, u32 valid_sources, u32 resume_sources, - struct device_node *node) + bool map_fiqs, struct device_node *node) { struct vic_device *v; int i; + unsigned int irq; if (vic_id >= ARRAY_SIZE(vic_devices)) { printk(KERN_ERR "%s: too few VICs, increase CONFIG_ARM_VIC_NR\n", __func__); @@ -301,15 +347,19 @@ static void __init vic_register(void __iomem *base, unsigned int parent_irq, irq_set_chained_handler(parent_irq, vic_handle_irq_cascaded); } - v->domain = irq_domain_add_simple(node, fls(valid_sources), irq, + v->domain = irq_domain_add_simple(node, fls(valid_sources), irq_start, &vic_irqdomain_ops, v); /* create an IRQ mapping for each valid IRQ */ - for (i = 0; i < fls(valid_sources); i++) - if (valid_sources & (1 << i)) - irq_create_mapping(v->domain, i); + for (i = 0; i < fls(valid_sources); i++) { + if (valid_sources & (1 << i)) { + irq = irq_create_mapping(v->domain, i); + vic_register_fiq(irq); + } + } + /* If no base IRQ was passed, figure out our allocated base */ - if (irq) - v->irq = irq; + if (irq_start) + v->irq = irq_start; else v->irq = irq_find_mapping(v->domain, 0); } @@ -413,7 +463,8 @@ static void __init vic_clear_interrupts(void __iomem *base) * and 020 within the page. We call this "second block". */ static void __init vic_init_st(void __iomem *base, unsigned int irq_start, - u32 vic_sources, struct device_node *node) + u32 vic_sources, bool map_fiqs, + struct device_node *node) { unsigned int i; int vic_2nd_block = ((unsigned long)base & ~PAGE_MASK) != 0; @@ -439,12 +490,12 @@ static void __init vic_init_st(void __iomem *base, unsigned int irq_start, writel(32, base + VIC_PL190_DEF_VECT_ADDR); } - vic_register(base, 0, irq_start, vic_sources, 0, node); + vic_register(base, 0, irq_start, vic_sources, 0, map_fiqs, node); } void __init __vic_init(void __iomem *base, int parent_irq, int irq_start, - u32 vic_sources, u32 resume_sources, - struct device_node *node) + u32 vic_sources, u32 resume_sources, + bool map_fiqs, struct device_node *node) { unsigned int i; u32 cellid = 0; @@ -462,7 +513,7 @@ void __init __vic_init(void __iomem *base, int parent_irq, int irq_start, switch(vendor) { case AMBA_VENDOR_ST: - vic_init_st(base, irq_start, vic_sources, node); + vic_init_st(base, irq_start, vic_sources, map_fiqs, node); return; default: printk(KERN_WARNING "VIC: unknown vendor, continuing anyways\n"); @@ -479,7 +530,8 @@ void __init __vic_init(void __iomem *base, int parent_irq, int irq_start, vic_init2(base); - vic_register(base, parent_irq, irq_start, vic_sources, resume_sources, node); + vic_register(base, parent_irq, irq_start, vic_sources, resume_sources, + map_fiqs, node); } /** @@ -492,7 +544,8 @@ void __init __vic_init(void __iomem *base, int parent_irq, int irq_start, void __init vic_init(void __iomem *base, unsigned int irq_start, u32 vic_sources, u32 resume_sources) { - __vic_init(base, 0, irq_start, vic_sources, resume_sources, NULL); + __vic_init(base, 0, irq_start, vic_sources, resume_sources, + false, NULL); } /** @@ -511,7 +564,8 @@ int __init vic_init_cascaded(void __iomem *base, unsigned int parent_irq, struct vic_device *v; v = &vic_devices[vic_id]; - __vic_init(base, parent_irq, 0, vic_sources, resume_sources, NULL); + __vic_init(base, parent_irq, 0, vic_sources, resume_sources, false, + NULL); /* Return out acquired base */ return v->irq; } @@ -535,9 +589,9 @@ int __init vic_of_init(struct device_node *node, struct device_node *parent) of_property_read_u32(node, "valid-wakeup-mask", &wakeup_mask); /* - * Passing 0 as first IRQ makes the simple domain allocate descriptors + * Passing 0 as first IRQ makes the domain allocate descriptors. */ - __vic_init(regs, 0, 0, interrupt_mask, wakeup_mask, node); + __vic_init(regs, 0, 0, interrupt_mask, wakeup_mask, true, node); return 0; } diff --git a/include/linux/irqchip/arm-vic.h b/include/linux/irqchip/arm-vic.h index ba46c79..30ab39f 100644 --- a/include/linux/irqchip/arm-vic.h +++ b/include/linux/irqchip/arm-vic.h @@ -30,8 +30,10 @@ struct device_node; struct pt_regs; void __vic_init(void __iomem *base, int parent_irq, int irq_start, - u32 vic_sources, u32 resume_sources, struct device_node *node); -void vic_init(void __iomem *base, unsigned int irq_start, u32 vic_sources, u32 resume_sources); + u32 vic_sources, u32 resume_sources, + bool map_fiqs, struct device_node *node); +void vic_init(void __iomem *base, unsigned int irq_start, u32 vic_sources, + u32 resume_sources); int vic_init_cascaded(void __iomem *base, unsigned int parent_irq, u32 vic_sources, u32 resume_sources);