From patchwork Mon Nov 27 18:38:56 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Russell King (Oracle)" X-Patchwork-Id: 10077755 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 162A2602BD for ; Mon, 27 Nov 2017 18:40:24 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0C83728F5C for ; Mon, 27 Nov 2017 18:40:24 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 0172528F5E; Mon, 27 Nov 2017 18:40:23 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [65.50.211.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 794B528F5C for ; Mon, 27 Nov 2017 18:40:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:Date:Message-Id:MIME-Version:Subject:To :From:References:In-Reply-To:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=U5xvL9PHXPg/yNR44zPP6MiE/W4OJucf5Lb63R/I+/I=; b=CMS9LvTf66+T2H zy3mmwfZJf/jVvifDJ4xtYTTQOhc/Tc+HES3zK4cc85xq8v69ROHEVJIxipMUQd4W+HkK+BAuvFxL +ibzHOE6oPwuD2lRm2iMwndkWrpxNZLPsozIEdZofMiMwlbX1If5h+UaFszywwlZA9D7a04wbfbf4 lFX+OEXQ8oksWCp6MlrIaiu1ONLu4k1Ta33kGULAmo4ew5oWjU1Y7MRSViRKUAeckh7rESEzNWt67 nt6iW8tq4pMJjazNmb+De8JvwN4mohma/7sz9/xBOcpqKfuIwbmWTPn9EbhOiY3ccSkSSatHXGQr1 qg4mLGCU3ip56EZJ3moA==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1eJOKN-00009w-0G; Mon, 27 Nov 2017 18:40:23 +0000 Received: from pandora.armlinux.org.uk ([2001:4d48:ad52:3201:214:fdff:fe10:1be6]) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1eJOJO-0006ZE-GP for linux-arm-kernel@lists.infradead.org; Mon, 27 Nov 2017 18:39:29 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=armlinux.org.uk; s=pandora-2014; h=Date:Sender:Message-Id:Content-Type:Content-Transfer-Encoding:MIME-Version:Subject:Cc:To:From:References:In-Reply-To; bh=FFPmZqCYD91YSaeDQrjBlP5sblXOYq3Ck54Y6xDgncM=; b=QW78Y7kkY1F2BtAPqYDEbDaVebXsTz+QjuAqUHZbbBKrTHHXr5c1wbpSspEp/lKdTFkXKdXRslSkDKqB0Fcv5lqdZ59hPCgl54rsPftY5v3ccogtOVH3lodC55RJbMci6UTtjf63BOYQO6CpL7wcJoC0Lp3n9fczUncsTzH8ybE=; Received: from e0022681537dd.dyn.armlinux.org.uk ([2001:4d48:ad52:3201:222:68ff:fe15:37dd]:37618 helo=rmk-PC.armlinux.org.uk) by pandora.armlinux.org.uk with esmtpsa (TLSv1:AES128-SHA:128) (Exim 4.82_1-5b7a7c0-XX) (envelope-from ) id 1eJOJ0-0000rc-Va; Mon, 27 Nov 2017 18:38:59 +0000 Received: from rmk by rmk-PC.armlinux.org.uk with local (Exim 4.82_1-5b7a7c0-XX) (envelope-from ) id 1eJOIy-0006on-LY; Mon, 27 Nov 2017 18:38:56 +0000 In-Reply-To: <20171127183811.GM31757@n2100.armlinux.org.uk> References: <20171127183811.GM31757@n2100.armlinux.org.uk> From: Russell King To: linux-arm-kernel@lists.infradead.org Subject: [PATCH 5/6] ARM: sa1111: use an irqdomain for SA1111 interrupts MIME-Version: 1.0 Content-Disposition: inline Message-Id: Date: Mon, 27 Nov 2017 18:38:56 +0000 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20171127_103922_978796_CEF08385 X-CRM114-Status: GOOD ( 17.53 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Thomas Gleixner , "Rafael J. Wysocki" Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP Use an IRQ domain for SA1111 interrupts, which allows us to separate the hardware interrupt number from the Linux interrupt number. We can then use the hardware interrupt number stored in the irq_data to calculate the register offsets and mask. Signed-off-by: Russell King --- arch/arm/common/sa1111.c | 79 +++++++++++++++++++++++++++++++----------------- 1 file changed, 51 insertions(+), 28 deletions(-) diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c index 36c2162c95af..d6a0ce7b51cf 100644 --- a/arch/arm/common/sa1111.c +++ b/arch/arm/common/sa1111.c @@ -108,6 +108,7 @@ struct sa1111 { spinlock_t lock; void __iomem *base; struct sa1111_platform_data *pdata; + struct irq_domain *irqdomain; struct gpio_chip gc; #ifdef CONFIG_PM void *saved_state; @@ -193,6 +194,14 @@ static struct sa1111_dev_info sa1111_devices[] = { }, }; +static void sa1111_handle_irqdomain(struct irq_domain *irqdomain, int irq) +{ + struct irq_desc *d = irq_to_desc(irq_linear_revmap(irqdomain, irq)); + + if (d) + generic_handle_irq_desc(d); +} + /* * SA1111 interrupt support. Since clearing an IRQ while there are * active IRQs causes the interrupt output to pulse, the upper levels @@ -202,6 +211,7 @@ static void sa1111_irq_handler(struct irq_desc *desc) { unsigned int stat0, stat1, i; struct sa1111 *sachip = irq_desc_get_handler_data(desc); + struct irq_domain *irqdomain; void __iomem *mapbase = sachip->base + SA1111_INTC; stat0 = readl_relaxed(mapbase + SA1111_INTSTATCLR0); @@ -218,33 +228,28 @@ static void sa1111_irq_handler(struct irq_desc *desc) return; } + irqdomain = sachip->irqdomain; + for (i = 0; stat0; i++, stat0 >>= 1) if (stat0 & 1) - generic_handle_irq(i + sachip->irq_base); + sa1111_handle_irqdomain(irqdomain, i); for (i = 32; stat1; i++, stat1 >>= 1) if (stat1 & 1) - generic_handle_irq(i + sachip->irq_base); + sa1111_handle_irqdomain(irqdomain, i); /* For level-based interrupts */ desc->irq_data.chip->irq_unmask(&desc->irq_data); } -#define SA1111_IRQMASK_LO(x) (1 << (x - sachip->irq_base)) -#define SA1111_IRQMASK_HI(x) (1 << (x - sachip->irq_base - 32)) - static u32 sa1111_irqmask(struct irq_data *d) { - struct sa1111 *sachip = irq_data_get_irq_chip_data(d); - - return BIT((d->irq - sachip->irq_base) & 31); + return BIT(irqd_to_hwirq(d) & 31); } static int sa1111_irqbank(struct irq_data *d) { - struct sa1111 *sachip = irq_data_get_irq_chip_data(d); - - return ((d->irq - sachip->irq_base) / 32) * 4; + return (irqd_to_hwirq(d) / 32) * 4; } static void sa1111_ack_irq(struct irq_data *d) @@ -350,10 +355,26 @@ static struct irq_chip sa1111_irq_chip = { .irq_set_wake = sa1111_wake_irq, }; +static int sa1111_irqdomain_map(struct irq_domain *d, unsigned int irq, + irq_hw_number_t hwirq) +{ + struct sa1111 *sachip = d->host_data; + + irq_set_chip_data(irq, sachip); + irq_set_chip_and_handler(irq, &sa1111_irq_chip, handle_edge_irq); + irq_clear_status_flags(irq, IRQ_NOREQUEST | IRQ_NOPROBE); + + return 0; +} + +static const struct irq_domain_ops sa1111_irqdomain_ops = { + .map = sa1111_irqdomain_map, + .xlate = irq_domain_xlate_twocell, +}; + static int sa1111_setup_irq(struct sa1111 *sachip, unsigned irq_base) { void __iomem *irqbase = sachip->base + SA1111_INTC; - unsigned i, irq; int ret; /* @@ -391,19 +412,21 @@ static int sa1111_setup_irq(struct sa1111 *sachip, unsigned irq_base) writel_relaxed(~0, irqbase + SA1111_INTSTATCLR0); writel_relaxed(~0, irqbase + SA1111_INTSTATCLR1); - for (i = IRQ_GPAIN0; i <= SSPROR; i++) { - irq = sachip->irq_base + i; - irq_set_chip_and_handler(irq, &sa1111_irq_chip, handle_edge_irq); - irq_set_chip_data(irq, sachip); - irq_clear_status_flags(irq, IRQ_NOREQUEST | IRQ_NOPROBE); + sachip->irqdomain = irq_domain_add_linear(NULL, SA1111_IRQ_NR, + &sa1111_irqdomain_ops, + sachip); + if (!sachip->irqdomain) { + irq_free_descs(sachip->irq_base, SA1111_IRQ_NR); + return -ENOMEM; } - for (i = AUDXMTDMADONEA; i <= IRQ_S1_BVD1_STSCHG; i++) { - irq = sachip->irq_base + i; - irq_set_chip_and_handler(irq, &sa1111_irq_chip, handle_edge_irq); - irq_set_chip_data(irq, sachip); - irq_clear_status_flags(irq, IRQ_NOREQUEST | IRQ_NOPROBE); - } + irq_domain_associate_many(sachip->irqdomain, + sachip->irq_base + IRQ_GPAIN0, + IRQ_GPAIN0, SSPROR + 1 - IRQ_GPAIN0); + irq_domain_associate_many(sachip->irqdomain, + sachip->irq_base + AUDXMTDMADONEA, + AUDXMTDMADONEA, + IRQ_S1_BVD1_STSCHG + 1 - AUDXMTDMADONEA); /* * Register SA1111 interrupt @@ -428,12 +451,12 @@ static void sa1111_remove_irq(struct sa1111 *sachip) writel_relaxed(0, irqbase + SA1111_WAKEEN0); writel_relaxed(0, irqbase + SA1111_WAKEEN1); - if (sachip->irq != NO_IRQ) { - irq_set_chained_handler_and_data(sachip->irq, NULL, NULL); - irq_free_descs(sachip->irq_base, SA1111_IRQ_NR); + irq_domain_remove(sachip->irqdomain); - release_mem_region(sachip->phys + SA1111_INTC, 512); - } + irq_set_chained_handler_and_data(sachip->irq, NULL, NULL); + irq_free_descs(sachip->irq_base, SA1111_IRQ_NR); + + release_mem_region(sachip->phys + SA1111_INTC, 512); } enum {