From patchwork Tue Sep 19 00:59:58 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Doug Berger X-Patchwork-Id: 9957977 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 3667A601E9 for ; Tue, 19 Sep 2017 01:09:34 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2324D2892E for ; Tue, 19 Sep 2017 01:09:34 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 15ECA289E4; Tue, 19 Sep 2017 01:09:34 +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_ADSP_CUSTOM_MED, DKIM_SIGNED, DKIM_VALID, FREEMAIL_FROM, RCVD_IN_DNSWL_MED autolearn=unavailable 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 8F57A287E8 for ; Tue, 19 Sep 2017 01:09:33 +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:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:References: In-Reply-To:Message-Id:Date:Subject:To:From:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=AJHqb/qqfPy9RMlc5SbnYFbZYjNgJSgoCB5hVvdRhP8=; b=iHicQcIbfQJhpfCTwleSfbpZx7 WIzwEI+hWNGJaKtgcTQTXDacyD4qSMNRY3mQygsGWtMPSoVSIvFGKfKlRgam4+bI8hhIux6L7s292 iKzYIJZ5az9z4qayyM3xdc2LKgzvALExHgRkk8wwcma29FhGDzQyQ6N3CCGRBmjFfityLzpxjgDXu X8uWWumntclKIzNsFDb+JCM+TW68k/rfa9TPTgKwrVdDkDRH3RBDF+MX2lWfu2L3F8WNBLIAupsbW 6M9SAIei/h+6vbgysPzvEGl5sDx7g+BGzpqv//fGw36yfWFubqMK2afOsR2XPWaIfX3mDLaRtu3ux mxJZ3WJw==; 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 1du72a-0003Nu-U2; Tue, 19 Sep 2017 01:09:32 +0000 Received: from mail-qt0-x244.google.com ([2607:f8b0:400d:c0d::244]) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1du6u1-00073w-AG for linux-arm-kernel@lists.infradead.org; Tue, 19 Sep 2017 01:00:45 +0000 Received: by mail-qt0-x244.google.com with SMTP id f24so1426629qte.5 for ; Mon, 18 Sep 2017 18:00:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=jCBliR1Y+ATmklN7eSpv/XggHvhmhHArCeCzpHmAxSk=; b=tNXvzSWW98Lv+4LZQTQuwiZ7LG/R9iCsDLgbgXRnmLqOWFzZcN69ZAVcMByiic5444 dXFMziIzAZMinfgPR6wVsqmMzwbD8jhA7n8Qosu/iH6ftrVEPer790wG4t4ayyRUTl8z sr+KlwJ2M/OCiAkydUt0gxiBqEAVFXeUPxsaUv1AfX9KUxTmy17To8V47ixYJa0bmlM8 Z7nD0NlGFKlB3s42QY7xja0zvCTG1BrxdyQNPXwiHJw/kw3bLkVjNPTmZwJr1V8Z0sPr yr4MiTZWNK7abps3etijz267jMdoCtwaeD7mwGHC9kYGao6yBI8n7WoD1HYepo8eOt5I yT1A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=jCBliR1Y+ATmklN7eSpv/XggHvhmhHArCeCzpHmAxSk=; b=MSka+9CX1tnv7uamADxBXZWynlqsOMwZevgi4qIg7ANaka21Ag1PAaAgIgufBbNLhX LDxYLR8jtZilomOTt6Nr9m7rUOy/yCd3/b2606ZaVsHvR2pfK+9O1qyOjI7VmaHC6aB4 F7STxW4dQykmEzCGfYwzYDqliovyM1bHGKZ1tnUxIXDJ6ElLmTh1lHURk6TthwGEBCSy dhHwZngbodRDF1WeZ3GmV7Eu+zNI+p7LVrTGYnhsT8gwR6wUx2zKvfWuHrNDuY5mcei3 u1g+0KytR8gvryqDeCiknm2fHsxjWR/KlgAz8hcBahyIIfrwJIF7W2fvimqD64g8Sykq h7gQ== X-Gm-Message-State: AHPjjUgr/3/jsR6+VZT6KzNJZ1pcJg86i5nsXGltEZmZcVWHqskUsOJU HmMZ5r2bTt/3GA== X-Google-Smtp-Source: AOwi7QDIBnArCHKL62HndrGTND0ALDqn6MsqbDp3b1sLEObQ17ZTNFo94yqzHfiy8tXxh71iMeasyQ== X-Received: by 10.200.44.123 with SMTP id e56mr654576qta.308.1505782819663; Mon, 18 Sep 2017 18:00:19 -0700 (PDT) Received: from stb-bld-02.irv.broadcom.com ([192.19.255.250]) by smtp.gmail.com with ESMTPSA id x39sm6113273qtc.93.2017.09.18.18.00.17 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 18 Sep 2017 18:00:19 -0700 (PDT) From: Doug Berger To: Thomas Gleixner Subject: [PATCH v4 1/3] irqchip: brcmstb-l2: Remove some processing from the handler Date: Mon, 18 Sep 2017 17:59:58 -0700 Message-Id: <20170919010000.32072-2-opendmb@gmail.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20170919010000.32072-1-opendmb@gmail.com> References: <20170919010000.32072-1-opendmb@gmail.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20170918_180041_652824_2999FF95 X-CRM114-Status: GOOD ( 20.13 ) 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: Mark Rutland , Sebastian Frias , Doug Berger , Jason Cooper , linux-mips@linux-mips.org, Mason , Marc Zyngier , Boris Brezillon , Bartosz Golaszewski , Kevin Cernekee , linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, Rob Herring , bcm-kernel-feedback-list@broadcom.com, Gregory Fong , Florian Fainelli , Brian Norris , Mans Rullgard , linux-arm-kernel@lists.infradead.org, Marc Gonzalez MIME-Version: 1.0 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 Saving the generic chip pointer in the brcmstb_l2_intc_data prevents the need to call irq_get_domain_generic_chip(). Also don't need to save parent_irq and base there since local variables in the brcmstb_l2_intc_of_init() function are just as good. The handle_edge_irq flow or chained_irq_enter takes care of the acknowledgment of the interrupt so it is redundant to clear it in brcmstb_l2_intc_irq_handle(). irq_linear_revmap() is a fast path equivalent of irq_find_mapping() that is appropriate to use for domain controllers of this type. Defining irq_mask_ack is slightly more efficient than just implementing irq_mask and irq_ack separately. Signed-off-by: Doug Berger --- drivers/irqchip/irq-brcmstb-l2.c | 72 ++++++++++++++++++++++++++-------------- 1 file changed, 48 insertions(+), 24 deletions(-) diff --git a/drivers/irqchip/irq-brcmstb-l2.c b/drivers/irqchip/irq-brcmstb-l2.c index b009b916a292..48bd1a36c7d4 100644 --- a/drivers/irqchip/irq-brcmstb-l2.c +++ b/drivers/irqchip/irq-brcmstb-l2.c @@ -1,7 +1,7 @@ /* * Generic Broadcom Set Top Box Level 2 Interrupt controller driver * - * Copyright (C) 2014 Broadcom Corporation + * Copyright (C) 2014-2017 Broadcom * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -41,25 +41,49 @@ /* L2 intc private data structure */ struct brcmstb_l2_intc_data { - int parent_irq; - void __iomem *base; struct irq_domain *domain; + struct irq_chip_generic *gc; bool can_wake; u32 saved_mask; /* for suspend/resume */ }; +/** + * brcmstb_l2_mask_and_ack - Mask and ack pending interrupt + * @d: irq_data + * + * Chip has separate enable/disable registers instead of a single mask + * register and pending interrupt is acknowledged by setting a bit. + * + * Note: This function is generic and could easily be added to the + * generic irqchip implementation if there ever becomes a will to do so. + * Perhaps with a name like irq_gc_mask_disable_and_ack_set(). + * + * e.g.: https://patchwork.kernel.org/patch/9831047/ + */ +static void brcmstb_l2_mask_and_ack(struct irq_data *d) +{ + struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); + struct irq_chip_type *ct = irq_data_get_chip_type(d); + u32 mask = d->mask; + + irq_gc_lock(gc); + irq_reg_writel(gc, mask, ct->regs.disable); + *ct->mask_cache &= ~mask; + irq_reg_writel(gc, mask, ct->regs.ack); + irq_gc_unlock(gc); +} + static void brcmstb_l2_intc_irq_handle(struct irq_desc *desc) { struct brcmstb_l2_intc_data *b = irq_desc_get_handler_data(desc); - struct irq_chip_generic *gc = irq_get_domain_generic_chip(b->domain, 0); struct irq_chip *chip = irq_desc_get_chip(desc); unsigned int irq; u32 status; chained_irq_enter(chip, desc); - status = irq_reg_readl(gc, CPU_STATUS) & - ~(irq_reg_readl(gc, CPU_MASK_STATUS)); + status = irq_reg_readl(b->gc, CPU_STATUS) & + ~(irq_reg_readl(b->gc, CPU_MASK_STATUS)); if (status == 0) { raw_spin_lock(&desc->lock); @@ -70,10 +94,8 @@ static void brcmstb_l2_intc_irq_handle(struct irq_desc *desc) do { irq = ffs(status) - 1; - /* ack at our level */ - irq_reg_writel(gc, 1 << irq, CPU_CLEAR); status &= ~(1 << irq); - generic_handle_irq(irq_find_mapping(b->domain, irq)); + generic_handle_irq(irq_linear_revmap(b->domain, irq)); } while (status); out: chained_irq_exit(chip, desc); @@ -116,32 +138,33 @@ static int __init brcmstb_l2_intc_of_init(struct device_node *np, { unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN; struct brcmstb_l2_intc_data *data; - struct irq_chip_generic *gc; struct irq_chip_type *ct; int ret; unsigned int flags; + int parent_irq; + void __iomem *base; data = kzalloc(sizeof(*data), GFP_KERNEL); if (!data) return -ENOMEM; - data->base = of_iomap(np, 0); - if (!data->base) { + base = of_iomap(np, 0); + if (!base) { pr_err("failed to remap intc L2 registers\n"); ret = -ENOMEM; goto out_free; } /* Disable all interrupts by default */ - writel(0xffffffff, data->base + CPU_MASK_SET); + writel(0xffffffff, base + CPU_MASK_SET); /* Wakeup interrupts may be retained from S5 (cold boot) */ data->can_wake = of_property_read_bool(np, "brcm,irq-can-wake"); if (!data->can_wake) - writel(0xffffffff, data->base + CPU_CLEAR); + writel(0xffffffff, base + CPU_CLEAR); - data->parent_irq = irq_of_parse_and_map(np, 0); - if (!data->parent_irq) { + parent_irq = irq_of_parse_and_map(np, 0); + if (!parent_irq) { pr_err("failed to find parent interrupt\n"); ret = -EINVAL; goto out_unmap; @@ -170,18 +193,19 @@ static int __init brcmstb_l2_intc_of_init(struct device_node *np, } /* Set the IRQ chaining logic */ - irq_set_chained_handler_and_data(data->parent_irq, + irq_set_chained_handler_and_data(parent_irq, brcmstb_l2_intc_irq_handle, data); - gc = irq_get_domain_generic_chip(data->domain, 0); - gc->reg_base = data->base; - gc->private = data; - ct = gc->chip_types; + data->gc = irq_get_domain_generic_chip(data->domain, 0); + data->gc->reg_base = base; + data->gc->private = data; + ct = data->gc->chip_types; ct->chip.irq_ack = irq_gc_ack_set_bit; ct->regs.ack = CPU_CLEAR; ct->chip.irq_mask = irq_gc_mask_disable_reg; + ct->chip.irq_mask_ack = brcmstb_l2_mask_and_ack; ct->regs.disable = CPU_MASK_SET; ct->chip.irq_unmask = irq_gc_unmask_enable_reg; @@ -195,19 +219,19 @@ static int __init brcmstb_l2_intc_of_init(struct device_node *np, /* This IRQ chip can wake the system, set all child interrupts * in wake_enabled mask */ - gc->wake_enabled = 0xffffffff; + data->gc->wake_enabled = 0xffffffff; ct->chip.irq_set_wake = irq_gc_set_wake; } pr_info("registered L2 intc (mem: 0x%p, parent irq: %d)\n", - data->base, data->parent_irq); + base, parent_irq); return 0; out_free_domain: irq_domain_remove(data->domain); out_unmap: - iounmap(data->base); + iounmap(base); out_free: kfree(data); return ret;