From patchwork Wed Jan 22 13:31:08 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 23519 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-vc0-f197.google.com (mail-vc0-f197.google.com [209.85.220.197]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 16CCA218CB for ; Wed, 22 Jan 2014 13:31:29 +0000 (UTC) Received: by mail-vc0-f197.google.com with SMTP id hq11sf586567vcb.0 for ; Wed, 22 Jan 2014 05:31:28 -0800 (PST) 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=Y2dFlmABoBUzu7SP2gUXhkdEe0AxwbtzzAc+CXtLC84=; b=YIZPmNHQf8R9bxICWi2cs85pYysWdtwFaamlHAkOzA9RQV8sEpMT6ITMgCVeunW1L8 fksEbaIzKUZWE0izCAkwSHTjrwvoHB/znvJw+5gQCjjuPMMSFiDwukYmMiPPzfk5E8vk 8jJIFkihlD9hulHSM+A1X2u/kQFEnKL7p5XrMylU9VfhJ0b9E76qJR1dGFJxOjVWxzlv q6isjgLhk6iOc8LwaPPlFnBAVLKn0IV5Wng9/zyUNwJ7m6ZT23g0nHrL/143YEPx/yzZ dQFN9UmIWBEdRIbRu/ZSdHNOLinR33XFI//OgNCcDRDYifmje0Piy+71RIJGxhD3C7C6 ZbsQ== X-Gm-Message-State: ALoCoQlm67FNfau2jTExHP4iMAWZaiWMMt02DQRDGONa7LxRVuI0fu8zMwZHE3nrsu1yMeqMUMmf X-Received: by 10.58.43.161 with SMTP id x1mr525717vel.18.1390397488321; Wed, 22 Jan 2014 05:31:28 -0800 (PST) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.49.83.2 with SMTP id m2ls47921qey.37.gmail; Wed, 22 Jan 2014 05:31:28 -0800 (PST) X-Received: by 10.220.58.202 with SMTP id i10mr906062vch.23.1390397488177; Wed, 22 Jan 2014 05:31:28 -0800 (PST) Received: from mail-ve0-f174.google.com (mail-ve0-f174.google.com [209.85.128.174]) by mx.google.com with ESMTPS id kv9si4544055vec.24.2014.01.22.05.31.28 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Wed, 22 Jan 2014 05:31:28 -0800 (PST) Received-SPF: neutral (google.com: 209.85.128.174 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) client-ip=209.85.128.174; Received: by mail-ve0-f174.google.com with SMTP id pa12so215078veb.19 for ; Wed, 22 Jan 2014 05:31:28 -0800 (PST) X-Received: by 10.220.147.16 with SMTP id j16mr939764vcv.28.1390397488086; Wed, 22 Jan 2014 05:31:28 -0800 (PST) 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.174.196 with SMTP id u4csp184735vcz; Wed, 22 Jan 2014 05:31:27 -0800 (PST) X-Received: by 10.194.222.38 with SMTP id qj6mr1835810wjc.66.1390397487184; Wed, 22 Jan 2014 05:31:27 -0800 (PST) Received: from mail-wi0-f176.google.com (mail-wi0-f176.google.com [209.85.212.176]) by mx.google.com with ESMTPS id q3si6816578wia.79.2014.01.22.05.31.26 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Wed, 22 Jan 2014 05:31:27 -0800 (PST) Received-SPF: neutral (google.com: 209.85.212.176 is neither permitted nor denied by best guess record for domain of linus.walleij@linaro.org) client-ip=209.85.212.176; Received: by mail-wi0-f176.google.com with SMTP id hi8so5608233wib.15 for ; Wed, 22 Jan 2014 05:31:26 -0800 (PST) X-Received: by 10.180.21.166 with SMTP id w6mr19691297wie.31.1390397486652; Wed, 22 Jan 2014 05:31:26 -0800 (PST) Received: from localhost.localdomain ([85.235.11.236]) by mx.google.com with ESMTPSA id po3sm14898693wjc.3.2014.01.22.05.31.25 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 22 Jan 2014 05:31:26 -0800 (PST) From: Linus Walleij To: linux-arm-kernel@lists.infradead.org Cc: Linus Walleij , Thomas Gleixner Subject: [PATCH 2/5] irqchip: support cascaded VICs Date: Wed, 22 Jan 2014 14:31:08 +0100 Message-Id: <1390397471-6802-3-git-send-email-linus.walleij@linaro.org> X-Mailer: git-send-email 1.8.4.2 In-Reply-To: <1390397471-6802-1-git-send-email-linus.walleij@linaro.org> References: <1390397471-6802-1-git-send-email-linus.walleij@linaro.org> X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: linus.walleij@linaro.org X-Original-Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.128.174 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) 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 adds support for a VIC to be cascaded off another IRQ. On the Integrator/AP logical module IM-PD1 there is a VIC cascaded off the central FPGA IRQ controller so this is needed for that to work out. In order for the plug-in board to be able to register all the devices with their IRQs relative to the offset of the base obtained for the cascaded VIC, the base IRQ number is passed back to the caller. Cc: Thomas Gleixner Signed-off-by: Linus Walleij --- tglx: if you're happy with this pls ACK it so I can take this through the ARM SoC tree. --- arch/arm/mach-versatile/core.c | 2 +- drivers/irqchip/irq-vic.c | 53 ++++++++++++++++++++++++++++++++++++----- include/linux/irqchip/arm-vic.h | 6 +++-- 3 files changed, 52 insertions(+), 9 deletions(-) diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c index 3b0572f30d56..36b97212d554 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, IRQ_VIC_START, ~0, 0, np); + __vic_init(VA_VIC_BASE, 0, IRQ_VIC_START, ~0, 0, 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 70108c1491bc..6002942a231c 100644 --- a/drivers/irqchip/irq-vic.c +++ b/drivers/irqchip/irq-vic.c @@ -57,6 +57,7 @@ /** * struct vic_device - VIC PM device + * @parent_irq: The parent IRQ number of the VIC if cascaded, or 0. * @irq: The IRQ number for the base of the VIC. * @base: The register base for the VIC. * @valid_sources: A bitmask of valid interrupts @@ -224,6 +225,17 @@ static int handle_one_vic(struct vic_device *vic, struct pt_regs *regs) return handled; } +static void vic_handle_irq_cascaded(unsigned int irq, struct irq_desc *desc) +{ + u32 stat, hwirq; + struct vic_device *vic = irq_desc_get_handler_data(desc); + + while ((stat = readl_relaxed(vic->base + VIC_IRQ_STATUS))) { + hwirq = ffs(stat) - 1; + generic_handle_irq(irq_find_mapping(vic->domain, hwirq)); + } +} + /* * Keep iterating over all registered VIC's until there are no pending * interrupts. @@ -246,6 +258,7 @@ static struct irq_domain_ops vic_irqdomain_ops = { /** * 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. * @valid_sources: bitmask of valid interrupts * @resume_sources: bitmask of interrupts allowed for resume sources. @@ -257,7 +270,8 @@ 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 irq, +static void __init vic_register(void __iomem *base, unsigned int parent_irq, + unsigned int irq, u32 valid_sources, u32 resume_sources, struct device_node *node) { @@ -275,6 +289,12 @@ static void __init vic_register(void __iomem *base, unsigned int irq, v->resume_sources = resume_sources; set_handle_irq(vic_handle_irq); vic_id++; + + if (parent_irq) { + irq_set_handler_data(parent_irq, v); + irq_set_chained_handler(parent_irq, vic_handle_irq_cascaded); + } + v->domain = irq_domain_add_simple(node, fls(valid_sources), irq, &vic_irqdomain_ops, v); /* create an IRQ mapping for each valid IRQ */ @@ -413,10 +433,10 @@ static void __init vic_init_st(void __iomem *base, unsigned int irq_start, writel(32, base + VIC_PL190_DEF_VECT_ADDR); } - vic_register(base, irq_start, vic_sources, 0, node); + vic_register(base, 0, irq_start, vic_sources, 0, node); } -void __init __vic_init(void __iomem *base, int irq_start, +void __init __vic_init(void __iomem *base, int parent_irq, int irq_start, u32 vic_sources, u32 resume_sources, struct device_node *node) { @@ -453,7 +473,7 @@ void __init __vic_init(void __iomem *base, int irq_start, vic_init2(base); - vic_register(base, irq_start, vic_sources, resume_sources, node); + vic_register(base, parent_irq, irq_start, vic_sources, resume_sources, node); } /** @@ -466,7 +486,28 @@ void __init __vic_init(void __iomem *base, int irq_start, void __init vic_init(void __iomem *base, unsigned int irq_start, u32 vic_sources, u32 resume_sources) { - __vic_init(base, irq_start, vic_sources, resume_sources, NULL); + __vic_init(base, 0, irq_start, vic_sources, resume_sources, NULL); +} + +/** + * vic_init_cascaded() - initialise a cascaded vectored interrupt controller + * @base: iomem base address + * @parent_irq: the parent IRQ we're cascaded off + * @irq_start: starting interrupt number, must be muliple of 32 + * @vic_sources: bitmask of interrupt sources to allow + * @resume_sources: bitmask of interrupt sources to allow for resume + * + * This returns the base for the new interrupts or negative on error. + */ +int __init vic_init_cascaded(void __iomem *base, unsigned int parent_irq, + u32 vic_sources, u32 resume_sources) +{ + struct vic_device *v; + + v = &vic_devices[vic_id]; + __vic_init(base, parent_irq, 0, vic_sources, resume_sources, NULL); + /* Return out acquired base */ + return v->irq; } #ifdef CONFIG_OF @@ -489,7 +530,7 @@ int __init vic_of_init(struct device_node *node, struct device_node *parent) /* * Passing 0 as first IRQ makes the simple domain allocate descriptors */ - __vic_init(regs, 0, interrupt_mask, wakeup_mask, node); + __vic_init(regs, 0, 0, interrupt_mask, wakeup_mask, node); return 0; } diff --git a/include/linux/irqchip/arm-vic.h b/include/linux/irqchip/arm-vic.h index e3c82dc95756..ba46c794b4e5 100644 --- a/include/linux/irqchip/arm-vic.h +++ b/include/linux/irqchip/arm-vic.h @@ -29,8 +29,10 @@ struct device_node; struct pt_regs; -void __vic_init(void __iomem *base, int irq_start, u32 vic_sources, - u32 resume_sources, struct device_node *node); +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); +int vic_init_cascaded(void __iomem *base, unsigned int parent_irq, + u32 vic_sources, u32 resume_sources); #endif