From patchwork Thu Jun 5 09:53:06 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Thompson X-Patchwork-Id: 4304261 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 64ABBBEEAA for ; Thu, 5 Jun 2014 09:56:36 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 871D920353 for ; Thu, 5 Jun 2014 09:56:35 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 89BBB202F8 for ; Thu, 5 Jun 2014 09:56:34 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1WsUMq-0001F4-76; Thu, 05 Jun 2014 09:53:52 +0000 Received: from mail-wi0-f177.google.com ([209.85.212.177]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1WsUMk-0001DS-JC for linux-arm-kernel@lists.infradead.org; Thu, 05 Jun 2014 09:53:47 +0000 Received: by mail-wi0-f177.google.com with SMTP id f8so3093707wiw.4 for ; Thu, 05 Jun 2014 02:53:24 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=OxudCixeS1Ku5ZMJbwqICEPzDY/FiWu2xPZOSz0Bfz8=; b=GZoZbEUrAiP9YHVdLIzLgjDdzcnNthJpsDByWLrBkSl3Kb7OCkrx4op2jZqnRQfHrd NfPLQd9zK1pQI686OxqEVbWr4kQ01Vm6Rrp6JRxR7aJu1iIA2jjGqRdWuHax+mq21cvB 2jPIhZIFV2uPVV0/AzpLwyVo75bUgMhgVWAucyPs/Qf/HtVHnRdHZTyWh7Ww1vUKtHl5 16VpSVYB+5BPJLrvZVUhgdR86Fss5sqy0TpoLabmRWHvOAlNbmlj6Bvzj5hJCrPvl8s5 QTI14QPadefp9qPNWiRU4WR8dp0h66FXvTUuiBuG2ZKtqy27qE2CFEKnuoG00x4alAQ4 9w+A== X-Gm-Message-State: ALoCoQnRiwP6l6vky5LBcSyeldVhZepUOXcWBDYOjeQAztvKk4mHW5qhxCiifMD3WKESA1HULI1I X-Received: by 10.194.238.65 with SMTP id vi1mr13700176wjc.84.1401962004545; Thu, 05 Jun 2014 02:53:24 -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.22 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 05 Jun 2014 02:53:23 -0700 (PDT) From: Daniel Thompson To: Jason Wessel Subject: [RFC v3 1/9] arm: fiq: arbitrary mappings from IRQ to FIQ virqs Date: Thu, 5 Jun 2014 10:53:06 +0100 Message-Id: <1401961994-18033-2-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-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20140605_025346_784435_BE60F345 X-CRM114-Status: GOOD ( 20.32 ) X-Spam-Score: -0.7 (/) Cc: Mark Rutland , kernel@stlinux.com, kgdb-bugreport@lists.sourceforge.net, Linus Walleij , Jiri Slaby , Daniel Thompson , Dirk Behme , Russell King , Nicolas Pitre , Fabio Estevam , Ian Campbell , Anton Vorontsov , "David A. Long" , linux-serial@vger.kernel.org, Catalin Marinas , kernel-team@android.com, devicetree@vger.kernel.org, linaro-kernel@lists.linaro.org, Pawel Moll , patches@linaro.org, Kumar Gala , Rob Herring , John Stultz , Thomas Gleixner , linux-arm-kernel@lists.infradead.org, Greg Kroah-Hartman , linux-kernel@vger.kernel.org, Colin Cross , Frederic Weisbecker , Christoffer Dall X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-2.5 required=5.0 tests=BAYES_00,RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Currently enable_fiq/disable_fiq use a simple offset to convert an IRQ virq into a FIQ virq. This is too inflexible for multi-platform kernels and makes runtime error checking impossible. We solve this by introducing a flexible mapping that allows interrupt controllers that support FIQ to register those mappings. This, in turn, makes it much possible for drivers in DT kernels to gain access to FIQ virqs. Signed-off-by: Daniel Thompson Cc: Russell King Cc: Fabio Estevam Cc: Nicolas Pitre --- arch/arm/include/asm/fiq.h | 2 ++ arch/arm/kernel/fiq.c | 57 +++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 53 insertions(+), 6 deletions(-) diff --git a/arch/arm/include/asm/fiq.h b/arch/arm/include/asm/fiq.h index d493d0b..75d98c6 100644 --- a/arch/arm/include/asm/fiq.h +++ b/arch/arm/include/asm/fiq.h @@ -36,8 +36,10 @@ struct fiq_handler { extern int claim_fiq(struct fiq_handler *f); extern void release_fiq(struct fiq_handler *f); extern void set_fiq_handler(void *start, unsigned int length); +extern struct irq_data *lookup_fiq_irq_data(int fiq); extern void enable_fiq(int fiq); extern void disable_fiq(int fiq); +extern void fiq_add_mapping(int irq, int fiq_virq, unsigned int length); /* helpers defined in fiqasm.S: */ extern void __set_fiq_regs(unsigned long const *regs); diff --git a/arch/arm/kernel/fiq.c b/arch/arm/kernel/fiq.c index 918875d..177939c 100644 --- a/arch/arm/kernel/fiq.c +++ b/arch/arm/kernel/fiq.c @@ -40,6 +40,8 @@ #include #include #include +#include +#include #include #include @@ -53,6 +55,9 @@ }) static unsigned long no_fiq_insn; +static int fiq_start = -1; +static RADIX_TREE(fiq_virq_tree, GFP_KERNEL); +static DEFINE_MUTEX(fiq_virq_mutex); /* Default reacquire function * - we always relinquish FIQ control @@ -60,8 +65,11 @@ static unsigned long no_fiq_insn; */ static int fiq_def_op(void *ref, int relinquish) { - if (!relinquish) + if (!relinquish) { + unsigned offset = FIQ_OFFSET; + no_fiq_insn = *(unsigned long *)(0xffff0000 + offset); set_fiq_handler(&no_fiq_insn, sizeof(no_fiq_insn)); + } return 0; } @@ -127,16 +135,33 @@ void release_fiq(struct fiq_handler *f) while (current_fiq->fiq_op(current_fiq->dev_id, 0)); } -static int fiq_start; +struct irq_data *lookup_fiq_irq_data(int fiq) +{ + struct irq_data *d; + + if (fiq_start != -1) + return irq_get_irq_data(fiq + fiq_start); + + rcu_read_lock(); + d = radix_tree_lookup(&fiq_virq_tree, fiq); + rcu_read_unlock(); + return d; +} void enable_fiq(int fiq) { - enable_irq(fiq + fiq_start); + struct irq_data *d = lookup_fiq_irq_data(fiq); + if (WARN_ON(!d)) + return; + enable_irq(d->irq); } void disable_fiq(int fiq) { - disable_irq(fiq + fiq_start); + struct irq_data *d = lookup_fiq_irq_data(fiq); + if (WARN_ON(!d)) + return; + disable_irq(d->irq); } EXPORT_SYMBOL(set_fiq_handler); @@ -144,12 +169,32 @@ EXPORT_SYMBOL(__set_fiq_regs); /* defined in fiqasm.S */ EXPORT_SYMBOL(__get_fiq_regs); /* defined in fiqasm.S */ EXPORT_SYMBOL(claim_fiq); EXPORT_SYMBOL(release_fiq); +EXPORT_SYMBOL(lookup_fiq_irq_data); EXPORT_SYMBOL(enable_fiq); EXPORT_SYMBOL(disable_fiq); +/* + * Add a mapping between a normal IRQ and a FIQ shadow. + */ +void fiq_add_mapping(int irq, int fiq_virq, unsigned int length) +{ + int i; + + /* fiq_add_mapping can't be mixed with init_FIQ */ + BUG_ON(fiq_start != -1); + + mutex_lock(&fiq_virq_mutex); + for (i = 0; i < length; i++) { + int err = radix_tree_insert(&fiq_virq_tree, irq + i, + irq_get_irq_data(fiq_virq + i)); + if (err) + pr_err("fiq: Cannot map %d to %d\n", irq + i, + fiq_virq + i); + } + mutex_unlock(&fiq_virq_mutex); +} + void __init init_FIQ(int start) { - unsigned offset = FIQ_OFFSET; - no_fiq_insn = *(unsigned long *)(0xffff0000 + offset); fiq_start = start; }