From patchwork Fri May 23 13:57:54 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Thompson X-Patchwork-Id: 30788 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-yh0-f69.google.com (mail-yh0-f69.google.com [209.85.213.69]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 3590620369 for ; Fri, 23 May 2014 13:58:29 +0000 (UTC) Received: by mail-yh0-f69.google.com with SMTP id i57sf18938679yha.0 for ; Fri, 23 May 2014 06:58:29 -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=0twQCAsSk2SMBS9NjnLUMqhFFSBeujbKJD9jxtsjIeY=; b=nHHtP7tq+koEZBdp3eglJssu8JYJG8XjJ02YDO/pBkVDmGaE+kg0Ofv8H5ZhqTLcBd aid78X6qR7T/0D/bE3l+JhcNwWZUNej8dZQfokg+RR3kccj65AS1Kuq8CgYUMNuJq5cj 046fWrAOSvp/zT9of5rSMm8i0iIZFbNsZuLq7vNu8LQWUuyT6jyuLHckpBc+rAVjYO/q Yh5cWp7dRXq7EbCRwxVe7TpIuY6OZ9JEQ3FSIXyVGi0A7JWdv36M1W/ic67csYp0IH5I afZGdN7Dm+wLBHMgc/r7QXKSTtJ5DNas4ngV1qkrJ1iMu73wEz5/ti3W2MlJGlg6PwMe MB6w== X-Gm-Message-State: ALoCoQnuPOVb8MQOsd1JCs8WUQBBgFMEEGuiqiMCzWAtjaAuoIrE3xy5tF/9Ww98er3DyBon6E38 X-Received: by 10.236.1.198 with SMTP id 46mr1900257yhd.16.1400853509034; Fri, 23 May 2014 06:58:29 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.80.81 with SMTP id b75ls1805686qgd.34.gmail; Fri, 23 May 2014 06:58:28 -0700 (PDT) X-Received: by 10.52.143.6 with SMTP id sa6mr3632039vdb.22.1400853508845; Fri, 23 May 2014 06:58:28 -0700 (PDT) Received: from mail-ve0-f177.google.com (mail-ve0-f177.google.com [209.85.128.177]) by mx.google.com with ESMTPS id 8si1651680vdx.54.2014.05.23.06.58.28 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Fri, 23 May 2014 06:58:28 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.128.177 as permitted sender) client-ip=209.85.128.177; Received: by mail-ve0-f177.google.com with SMTP id db11so6173932veb.8 for ; Fri, 23 May 2014 06:58:28 -0700 (PDT) X-Received: by 10.58.85.65 with SMTP id f1mr4446706vez.20.1400853508619; Fri, 23 May 2014 06:58:28 -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 ib8csp33821vcb; Fri, 23 May 2014 06:58:28 -0700 (PDT) X-Received: by 10.194.87.200 with SMTP id ba8mr4560247wjb.28.1400853507603; Fri, 23 May 2014 06:58:27 -0700 (PDT) Received: from mail-wi0-f173.google.com (mail-wi0-f173.google.com [209.85.212.173]) by mx.google.com with ESMTPS id da6si1436745wib.68.2014.05.23.06.58.27 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Fri, 23 May 2014 06:58:27 -0700 (PDT) Received-SPF: pass (google.com: domain of daniel.thompson@linaro.org designates 209.85.212.173 as permitted sender) client-ip=209.85.212.173; Received: by mail-wi0-f173.google.com with SMTP id bs8so886365wib.12 for ; Fri, 23 May 2014 06:58:27 -0700 (PDT) X-Received: by 10.194.158.132 with SMTP id wu4mr675540wjb.96.1400853507121; Fri, 23 May 2014 06:58:27 -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.24 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 23 May 2014 06:58:26 -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, Hartley Sweeten , Ryan Mallon , Ben Dooks , Kukjin Kim , Jason Cooper , linux-samsung-soc@vger.kernel.org Subject: [RFC v2 06/10] irqchip: vic: Introduce shadow irqs for FIQ Date: Fri, 23 May 2014 14:57:54 +0100 Message-Id: <1400853478-5824-7-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.128.177 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: , Currently on the ARM Versatile machine both FIQ and IRQ signals share the same irq number. The effect of this is that enable_fiq() will enable an interrupt but will leave it routed to IRQ. This requires a driver utilizing FIQ to employ machine specific knowledge (i.e. that the machine has a VIC). By introducing shadow irqs to describe FIQs the VIC driver is able to update the routing automatically during enable_fiq()/disable_fiq(). Changes to the vic_init() API allow individual machines to choose where to fit the shadow irqs in the interrupt map and also to choose not to have shadows at all. This patch introduces shadows for mach-versatile whilst mach-ep93xx, mach-netx, mach-s3c64xx and plat-samsung retain unmodified interrupt maps. 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-ep93xx/core.c | 6 +- arch/arm/mach-netx/generic.c | 3 +- arch/arm/mach-s3c64xx/common.c | 6 +- arch/arm/mach-versatile/core.c | 9 +-- arch/arm/mach-versatile/include/mach/irqs.h | 76 ++++++++++++------------- arch/arm/plat-samsung/s5p-irq.c | 3 +- drivers/irqchip/irq-vic.c | 87 +++++++++++++++++++++++------ include/linux/irqchip/arm-vic.h | 8 ++- 8 files changed, 132 insertions(+), 66 deletions(-) diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c index 0e571f1..aa26411 100644 --- a/arch/arm/mach-ep93xx/core.c +++ b/arch/arm/mach-ep93xx/core.c @@ -185,8 +185,10 @@ void __init ep93xx_timer_init(void) *************************************************************************/ void __init ep93xx_init_irq(void) { - vic_init(EP93XX_VIC1_BASE, 0, EP93XX_VIC1_VALID_IRQ_MASK, 0); - vic_init(EP93XX_VIC2_BASE, 32, EP93XX_VIC2_VALID_IRQ_MASK, 0); + vic_init(EP93XX_VIC1_BASE, 0, VIC_FIQ_START_NONE, + EP93XX_VIC1_VALID_IRQ_MASK, 0); + vic_init(EP93XX_VIC2_BASE, 32, VIC_FIQ_START_NONE, + EP93XX_VIC2_VALID_IRQ_MASK, 0); } diff --git a/arch/arm/mach-netx/generic.c b/arch/arm/mach-netx/generic.c index db25b0c..5398dcd 100644 --- a/arch/arm/mach-netx/generic.c +++ b/arch/arm/mach-netx/generic.c @@ -169,7 +169,8 @@ void __init netx_init_irq(void) { int irq; - vic_init(io_p2v(NETX_PA_VIC), NETX_IRQ_VIC_START, ~0, 0); + vic_init(io_p2v(NETX_PA_VIC), NETX_IRQ_VIC_START, VIC_FIQ_START_NONE, + ~0, 0); for (irq = NETX_IRQ_HIF_CHAINED(0); irq <= NETX_IRQ_HIF_LAST; irq++) { irq_set_chip_and_handler(irq, &netx_hif_chip, diff --git a/arch/arm/mach-s3c64xx/common.c b/arch/arm/mach-s3c64xx/common.c index 5c45aae..b98dd48 100644 --- a/arch/arm/mach-s3c64xx/common.c +++ b/arch/arm/mach-s3c64xx/common.c @@ -242,8 +242,10 @@ void __init s3c64xx_init_irq(u32 vic0_valid, u32 vic1_valid) printk(KERN_DEBUG "%s: initialising interrupts\n", __func__); /* initialise the pair of VICs */ - vic_init(VA_VIC0, IRQ_VIC0_BASE, vic0_valid, IRQ_VIC0_RESUME); - vic_init(VA_VIC1, IRQ_VIC1_BASE, vic1_valid, IRQ_VIC1_RESUME); + vic_init(VA_VIC0, IRQ_VIC0_BASE, VIC_FIQ_START_NONE, vic0_valid, + IRQ_VIC0_RESUME); + vic_init(VA_VIC1, IRQ_VIC1_BASE, VIC_FIQ_START_NONE, vic1_valid, + IRQ_VIC1_RESUME); } #define eint_offset(irq) ((irq) - IRQ_EINT(0)) diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c index f2c89fb..3444ca8 100644 --- a/arch/arm/mach-versatile/core.c +++ b/arch/arm/mach-versatile/core.c @@ -108,7 +108,8 @@ 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, + np ? -1 : FIQ_VIC_START, ~0, 0, np); writel(~0, VA_SIC_BASE + SIC_IRQ_ENABLE_CLEAR); @@ -614,9 +615,9 @@ static struct pl022_ssp_controller ssp0_plat_data = { * These devices are connected via the DMA APB bridge */ #define SCI_IRQ { IRQ_SCIINT } -#define UART0_IRQ { IRQ_UARTINT0 } -#define UART1_IRQ { IRQ_UARTINT1 } -#define UART2_IRQ { IRQ_UARTINT2 } +#define UART0_IRQ { IRQ_UARTINT0, FIQ_UARTINT0 } +#define UART1_IRQ { IRQ_UARTINT1, FIQ_UARTINT1 } +#define UART2_IRQ { IRQ_UARTINT2, FIQ_UARTINT2 } #define SSP_IRQ { IRQ_SSPINT } /* FPGA Primecells */ diff --git a/arch/arm/mach-versatile/include/mach/irqs.h b/arch/arm/mach-versatile/include/mach/irqs.h index 0fd771c..da3f919 100644 --- a/arch/arm/mach-versatile/include/mach/irqs.h +++ b/arch/arm/mach-versatile/include/mach/irqs.h @@ -60,43 +60,6 @@ #define IRQ_VICSOURCE31 (IRQ_VIC_START + INT_VICSOURCE31) #define IRQ_VIC_END (IRQ_VIC_START + 31) -/* - * FIQ interrupts definitions are the same as the INT definitions. - */ -#define FIQ_WDOGINT INT_WDOGINT -#define FIQ_SOFTINT INT_SOFTINT -#define FIQ_COMMRx INT_COMMRx -#define FIQ_COMMTx INT_COMMTx -#define FIQ_TIMERINT0_1 INT_TIMERINT0_1 -#define FIQ_TIMERINT2_3 INT_TIMERINT2_3 -#define FIQ_GPIOINT0 INT_GPIOINT0 -#define FIQ_GPIOINT1 INT_GPIOINT1 -#define FIQ_GPIOINT2 INT_GPIOINT2 -#define FIQ_GPIOINT3 INT_GPIOINT3 -#define FIQ_RTCINT INT_RTCINT -#define FIQ_SSPINT INT_SSPINT -#define FIQ_UARTINT0 INT_UARTINT0 -#define FIQ_UARTINT1 INT_UARTINT1 -#define FIQ_UARTINT2 INT_UARTINT2 -#define FIQ_SCIINT INT_SCIINT -#define FIQ_CLCDINT INT_CLCDINT -#define FIQ_DMAINT INT_DMAINT -#define FIQ_PWRFAILINT INT_PWRFAILINT -#define FIQ_MBXINT INT_MBXINT -#define FIQ_GNDINT INT_GNDINT -#define FIQ_VICSOURCE21 INT_VICSOURCE21 -#define FIQ_VICSOURCE22 INT_VICSOURCE22 -#define FIQ_VICSOURCE23 INT_VICSOURCE23 -#define FIQ_VICSOURCE24 INT_VICSOURCE24 -#define FIQ_VICSOURCE25 INT_VICSOURCE25 -#define FIQ_VICSOURCE26 INT_VICSOURCE26 -#define FIQ_VICSOURCE27 INT_VICSOURCE27 -#define FIQ_VICSOURCE28 INT_VICSOURCE28 -#define FIQ_VICSOURCE29 INT_VICSOURCE29 -#define FIQ_VICSOURCE30 INT_VICSOURCE30 -#define FIQ_VICSOURCE31 INT_VICSOURCE31 - - /* * Secondary interrupt controller */ @@ -131,4 +94,41 @@ #define IRQ_GPIO3_START (IRQ_GPIO2_END + 1) #define IRQ_GPIO3_END (IRQ_GPIO3_START + 31) -#define NR_IRQS (IRQ_GPIO3_END + 1) +/* + * FIQ interrupts definitions shadow the VIC INT definitions. + */ +#define FIQ_VIC_START (IRQ_GPIO3_END + 1) +#define FIQ_WDOGINT (INT_WDOGINT + FIQ_VIC_START) +#define FIQ_SOFTINT (INT_SOFTINT + FIQ_VIC_START) +#define FIQ_COMMRx (INT_COMMRx + FIQ_VIC_START) +#define FIQ_COMMTx (INT_COMMTx + FIQ_VIC_START) +#define FIQ_TIMERINT0_1 (INT_TIMERINT0_1 + FIQ_VIC_START) +#define FIQ_TIMERINT2_3 (INT_TIMERINT2_3 + FIQ_VIC_START) +#define FIQ_GPIOINT0 (INT_GPIOINT0 + FIQ_VIC_START) +#define FIQ_GPIOINT1 (INT_GPIOINT1 + FIQ_VIC_START) +#define FIQ_GPIOINT2 (INT_GPIOINT2 + FIQ_VIC_START) +#define FIQ_GPIOINT3 (INT_GPIOINT3 + FIQ_VIC_START) +#define FIQ_RTCINT (INT_RTCINT + FIQ_VIC_START) +#define FIQ_SSPINT (INT_SSPINT + FIQ_VIC_START) +#define FIQ_UARTINT0 (INT_UARTINT0 + FIQ_VIC_START) +#define FIQ_UARTINT1 (INT_UARTINT1 + FIQ_VIC_START) +#define FIQ_UARTINT2 (INT_UARTINT2 + FIQ_VIC_START) +#define FIQ_SCIINT (INT_SCIINT + FIQ_VIC_START) +#define FIQ_CLCDINT (INT_CLCDINT + FIQ_VIC_START) +#define FIQ_DMAINT (INT_DMAINT + FIQ_VIC_START) +#define FIQ_PWRFAILINT (INT_PWRFAILINT + FIQ_VIC_START) +#define FIQ_MBXINT (INT_MBXINT + FIQ_VIC_START) +#define FIQ_GNDINT (INT_GNDINT + FIQ_VIC_START) +#define FIQ_VICSOURCE21 (INT_VICSOURCE21 + FIQ_VIC_START) +#define FIQ_VICSOURCE22 (INT_VICSOURCE22 + FIQ_VIC_START) +#define FIQ_VICSOURCE23 (INT_VICSOURCE23 + FIQ_VIC_START) +#define FIQ_VICSOURCE24 (INT_VICSOURCE24 + FIQ_VIC_START) +#define FIQ_VICSOURCE25 (INT_VICSOURCE25 + FIQ_VIC_START) +#define FIQ_VICSOURCE26 (INT_VICSOURCE26 + FIQ_VIC_START) +#define FIQ_VICSOURCE27 (INT_VICSOURCE27 + FIQ_VIC_START) +#define FIQ_VICSOURCE28 (INT_VICSOURCE28 + FIQ_VIC_START) +#define FIQ_VICSOURCE29 (INT_VICSOURCE29 + FIQ_VIC_START) +#define FIQ_VICSOURCE30 (INT_VICSOURCE30 + FIQ_VIC_START) +#define FIQ_VICSOURCE31 (INT_VICSOURCE31 + FIQ_VIC_START) + +#define NR_IRQS (FIQ_VICSOURCE31 + 1) diff --git a/arch/arm/plat-samsung/s5p-irq.c b/arch/arm/plat-samsung/s5p-irq.c index ddfaca9..ddb1138 100644 --- a/arch/arm/plat-samsung/s5p-irq.c +++ b/arch/arm/plat-samsung/s5p-irq.c @@ -26,6 +26,7 @@ void __init s5p_init_irq(u32 *vic, u32 num_vic) /* initialize the VICs */ for (irq = 0; irq < num_vic; irq++) - vic_init(VA_VIC(irq), VIC_BASE(irq), vic[irq], 0); + vic_init(VA_VIC(irq), VIC_BASE(irq), VIC_FIQ_START_NONE, + vic[irq], 0); #endif } diff --git a/drivers/irqchip/irq-vic.c b/drivers/irqchip/irq-vic.c index 7d35287..82bce53 100644 --- a/drivers/irqchip/irq-vic.c +++ b/drivers/irqchip/irq-vic.c @@ -56,6 +56,8 @@ #define VIC_PL192_VECT_ADDR 0xF00 +#define VIC_FIQ_SHADOW_OFFSET 32 + /** * struct vic_device - VIC PM device * @parent_irq: The parent IRQ number of the VIC if cascaded, or 0. @@ -81,8 +83,11 @@ struct vic_device { u32 soft_int; u32 protect; struct irq_domain *domain; + struct irq_domain *fiq_domain; }; +static DEFINE_RAW_SPINLOCK(irq_controller_lock); + /* we cannot allocate memory when VICs are initially registered */ static struct vic_device vic_devices[CONFIG_ARM_VIC_NR]; @@ -197,6 +202,9 @@ static int vic_irqdomain_map(struct irq_domain *d, unsigned int irq, { struct vic_device *v = d->host_data; + if (hwirq > VIC_FIQ_SHADOW_OFFSET) + hwirq -= VIC_FIQ_SHADOW_OFFSET; + /* Skip invalid IRQs, only register handlers for the real ones */ if (!(v->valid_sources & (1 << hwirq))) return -EPERM; @@ -277,7 +285,7 @@ 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, int fiq, u32 valid_sources, u32 resume_sources, struct device_node *node) { @@ -307,6 +315,19 @@ static void __init vic_register(void __iomem *base, unsigned int parent_irq, for (i = 0; i < fls(valid_sources); i++) if (valid_sources & (1 << i)) irq_create_mapping(v->domain, i); + + /* create FIQ shadow mapping for each IRQ */ + if (fiq >= 0) { + v->fiq_domain = irq_domain_add_legacy( + node, fls(valid_sources), fiq, + VIC_FIQ_SHADOW_OFFSET, &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->fiq_domain, + i + VIC_FIQ_SHADOW_OFFSET); + } + /* If no base IRQ was passed, figure out our allocated base */ if (irq) v->irq = irq; @@ -314,10 +335,36 @@ static void __init vic_register(void __iomem *base, unsigned int parent_irq, v->irq = irq_find_mapping(v->domain, 0); } +static inline bool vic_is_fiq(struct irq_data *d) +{ + return d->hwirq >= VIC_FIQ_SHADOW_OFFSET; +} + +static inline unsigned int vic_irq(struct irq_data *d) +{ + return d->hwirq & (VIC_FIQ_SHADOW_OFFSET-1); +} + +static void vic_set_fiq(struct irq_data *d, bool enable) +{ + void __iomem *base = irq_data_get_irq_chip_data(d); + unsigned int irq = vic_irq(d); + 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_ack_irq(struct irq_data *d) { void __iomem *base = irq_data_get_irq_chip_data(d); - unsigned int irq = d->hwirq; + unsigned int irq = vic_irq(d); writel(1 << irq, base + VIC_INT_ENABLE_CLEAR); /* moreover, clear the soft-triggered, in case it was the reason */ writel(1 << irq, base + VIC_INT_SOFT_CLEAR); @@ -326,17 +373,22 @@ static void vic_ack_irq(struct irq_data *d) static void vic_mask_irq(struct irq_data *d) { void __iomem *base = irq_data_get_irq_chip_data(d); - unsigned int irq = d->hwirq; + unsigned int irq = vic_irq(d); + if (vic_is_fiq(d)) + vic_set_fiq(d, false); writel(1 << irq, base + VIC_INT_ENABLE_CLEAR); } static void vic_unmask_irq(struct irq_data *d) { void __iomem *base = irq_data_get_irq_chip_data(d); - unsigned int irq = d->hwirq; + unsigned int irq = vic_irq(d); + if (vic_is_fiq(d)) + vic_set_fiq(d, true); writel(1 << irq, base + VIC_INT_ENABLE); } + #if defined(CONFIG_PM) static struct vic_device *vic_from_irq(unsigned int irq) { @@ -355,7 +407,7 @@ static struct vic_device *vic_from_irq(unsigned int irq) static int vic_set_wake(struct irq_data *d, unsigned int on) { struct vic_device *v = vic_from_irq(d->irq); - unsigned int off = d->hwirq; + unsigned int off = vic_irq(d); u32 bit = 1 << off; if (!v) @@ -413,7 +465,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) + int fiq_start, u32 vic_sources, + struct device_node *node) { unsigned int i; int vic_2nd_block = ((unsigned long)base & ~PAGE_MASK) != 0; @@ -439,12 +492,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, fiq_start, vic_sources, 0, node); } void __init __vic_init(void __iomem *base, int parent_irq, int irq_start, - u32 vic_sources, u32 resume_sources, - struct device_node *node) + int fiq_start, u32 vic_sources, u32 resume_sources, + struct device_node *node) { unsigned int i; u32 cellid = 0; @@ -462,7 +515,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, fiq_start, vic_sources, node); return; default: printk(KERN_WARNING "VIC: unknown vendor, continuing anyways\n"); @@ -479,7 +532,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, fiq_start, vic_sources, + resume_sources, node); } /** @@ -490,9 +544,9 @@ void __init __vic_init(void __iomem *base, int parent_irq, int irq_start, * @resume_sources: bitmask of interrupt sources to allow for resume */ void __init vic_init(void __iomem *base, unsigned int irq_start, - u32 vic_sources, u32 resume_sources) + int fiq_start, u32 vic_sources, u32 resume_sources) { - __vic_init(base, 0, irq_start, vic_sources, resume_sources, NULL); + __vic_init(base, 0, irq_start, -1, vic_sources, resume_sources, NULL); } /** @@ -511,7 +565,7 @@ 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, -1, vic_sources, resume_sources, NULL); /* Return out acquired base */ return v->irq; } @@ -535,9 +589,10 @@ 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 (and first FIQ) makes the domain allocate + * descriptors. */ - __vic_init(regs, 0, 0, interrupt_mask, wakeup_mask, node); + __vic_init(regs, 0, 0, -1, interrupt_mask, wakeup_mask, node); return 0; } diff --git a/include/linux/irqchip/arm-vic.h b/include/linux/irqchip/arm-vic.h index ba46c79..fae480d 100644 --- a/include/linux/irqchip/arm-vic.h +++ b/include/linux/irqchip/arm-vic.h @@ -26,12 +26,16 @@ #define VIC_INT_ENABLE 0x10 /* 1 = enable, 0 = disable */ #define VIC_INT_ENABLE_CLEAR 0x14 +#define VIC_FIQ_START_NONE -1 + 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); + int fiq_start, u32 vic_sources, u32 resume_sources, + struct device_node *node); +void vic_init(void __iomem *base, unsigned int irq_start, int fiq_start, + u32 vic_sources, u32 resume_sources); int vic_init_cascaded(void __iomem *base, unsigned int parent_irq, u32 vic_sources, u32 resume_sources);