From patchwork Tue Jan 19 13:11:14 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomasz Nowicki X-Patchwork-Id: 8061661 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 8A1749F818 for ; Tue, 19 Jan 2016 13:13:41 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 7EE5720411 for ; Tue, 19 Jan 2016 13:13:39 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 7EC70203A1 for ; Tue, 19 Jan 2016 13:13:38 +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 1aLW51-0003pR-15; Tue, 19 Jan 2016 13:12:15 +0000 Received: from mail-wm0-x22d.google.com ([2a00:1450:400c:c09::22d]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1aLW4a-00037x-VJ for linux-arm-kernel@lists.infradead.org; Tue, 19 Jan 2016 13:11:51 +0000 Received: by mail-wm0-x22d.google.com with SMTP id l65so137636656wmf.1 for ; Tue, 19 Jan 2016 05:11:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=semihalf-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=vIzkOTcb/Vk8qCPE14UL1Z20SHFaTkETZN9QZiEfofo=; b=G/JgOO3c39/4rFPu7X7o+O7Ds017/va2cnjSyw1bbaN8cb+qW+izlgzuV+JXTDx5AP DWuUn+M5CPlNrlS5B2ni5POFykwP551rxUt+dbzwoxjXuudI0/Sz/eVuAT0bS5+X2Iq2 sgzWbRowW+5b6X5VNIFMHYcDBXgV1wH7dK+i0f0B/0GTNQNjXXkcXFyVJXRvwDwKRTLI ytCMDgGDnR5Jb9gmv94iHX/id54C8Bg2ACSYqZRcPAtEsPUml0Yhyhw20VrrZTtiuSll bIu34H6OavCCVidrafZvl7AaaObo+712T/qQhQf76L6RhMSZiBxj63ac1qDLVFpdR9eh qhLQ== 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=vIzkOTcb/Vk8qCPE14UL1Z20SHFaTkETZN9QZiEfofo=; b=XnM4FCy0ToZj+UrJAhfj4noAknjiTM57qLYODnW3hxcVHE6YvcsRInlDbUi8Cu9J79 DUsISh/FZSD0koHss3r1vEXOIH3LSyakllU3hNNxja+B6N5H11itX99wvkTjAis01BMu wBYEv8e1/LjmSM5yQ4xJXC8tmmvMkIVeCgNKHmUTQJERpIKKo3AyQXAA1Nv31fMK5pe9 7lRnU5qLTQSYSfOzpDeZbAbTvifzfGIc74/N/QaTkIDLordHpCLBlEwRN/U1s05xBQex cPKtJbXpakV3uHwKyLZFLiGKCpwYJh+TdQIwVSP6DqbrYpWLKn5Mn64RJPEr4NPlDFPH xJOg== X-Gm-Message-State: ALoCoQmL1nzXcfemMOzqdUcgVoJ6/9wM8xFlEzePTVmOp5Xkl4ulHXdFM4VH77c/jIGjq+uCEEERiWs/yh3i7JAsixY2FLQTjw== X-Received: by 10.194.57.100 with SMTP id h4mr35051690wjq.21.1453209086966; Tue, 19 Jan 2016 05:11:26 -0800 (PST) Received: from tn-HP-4.semihalf.local ([80.82.22.190]) by smtp.gmail.com with ESMTPSA id w194sm17762623wmd.0.2016.01.19.05.11.25 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 19 Jan 2016 05:11:25 -0800 (PST) From: Tomasz Nowicki To: marc.zyngier@arm.com, tglx@linutronix.de, jason@lakedaemon.net, rjw@rjwysocki.net, lorenzo.pieralisi@arm.com, robert.richter@caviumnetworks.com, shijie.huang@arm.com, guohanjun@huawei.com, Suravee.Suthikulpanit@amd.com Subject: [PATCH V3 01/10] irqchip / GICv3: Refactor gic_of_init() for GICv3 driver Date: Tue, 19 Jan 2016 14:11:14 +0100 Message-Id: <1453209083-3358-2-git-send-email-tn@semihalf.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1453209083-3358-1-git-send-email-tn@semihalf.com> References: <1453209083-3358-1-git-send-email-tn@semihalf.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20160119_051149_396233_EE876F39 X-CRM114-Status: GOOD ( 16.98 ) X-Spam-Score: -2.6 (--) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: graeme.gregory@linaro.org, Catalin.Marinas@arm.com, will.deacon@arm.com, linux-kernel@vger.kernel.org, Tomasz Nowicki , linux-acpi@vger.kernel.org, hanjun.guo@linaro.org, ddaney.cavm@gmail.com, Tomasz Nowicki , mw@semihalf.com, linux-arm-kernel@lists.infradead.org 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=-4.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED,RP_MATCHES_RCVD,T_DKIM_INVALID,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 Isolate hardware abstraction (FDT) code to gic_of_init(). Rest of the logic goes to gic_init_bases() and expects well defined data to initialize GIC properly. The same solution is used for GICv2 driver. This is needed for ACPI initialization later. Signed-off-by: Tomasz Nowicki Signed-off-by: Hanjun Guo Acked-by: Marc Zyngier --- drivers/irqchip/irq-gic-v3.c | 130 ++++++++++++++++++++++++++----------------- 1 file changed, 78 insertions(+), 52 deletions(-) diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c index d7be6dd..31205c7 100644 --- a/drivers/irqchip/irq-gic-v3.c +++ b/drivers/irqchip/irq-gic-v3.c @@ -811,59 +811,16 @@ static void gicv3_enable_quirks(void) #endif } -static int __init gic_of_init(struct device_node *node, struct device_node *parent) +static int __init gic_init_bases(void __iomem *dist_base, + struct redist_region *rdist_regs, + u32 nr_redist_regions, + u64 redist_stride, + struct fwnode_handle *handle) { - void __iomem *dist_base; - struct redist_region *rdist_regs; - u64 redist_stride; - u32 nr_redist_regions; + struct device_node *node; u32 typer; - u32 reg; int gic_irqs; int err; - int i; - - dist_base = of_iomap(node, 0); - if (!dist_base) { - pr_err("%s: unable to map gic dist registers\n", - node->full_name); - return -ENXIO; - } - - reg = readl_relaxed(dist_base + GICD_PIDR2) & GIC_PIDR2_ARCH_MASK; - if (reg != GIC_PIDR2_ARCH_GICv3 && reg != GIC_PIDR2_ARCH_GICv4) { - pr_err("%s: no distributor detected, giving up\n", - node->full_name); - err = -ENODEV; - goto out_unmap_dist; - } - - if (of_property_read_u32(node, "#redistributor-regions", &nr_redist_regions)) - nr_redist_regions = 1; - - rdist_regs = kzalloc(sizeof(*rdist_regs) * nr_redist_regions, GFP_KERNEL); - if (!rdist_regs) { - err = -ENOMEM; - goto out_unmap_dist; - } - - for (i = 0; i < nr_redist_regions; i++) { - struct resource res; - int ret; - - ret = of_address_to_resource(node, 1 + i, &res); - rdist_regs[i].redist_base = of_iomap(node, 1 + i); - if (ret || !rdist_regs[i].redist_base) { - pr_err("%s: couldn't map region %d\n", - node->full_name, i); - err = -ENODEV; - goto out_unmap_rdist; - } - rdist_regs[i].phys_base = res.start; - } - - if (of_property_read_u64(node, "redistributor-stride", &redist_stride)) - redist_stride = 0; if (!is_hyp_mode_available()) static_key_slow_dec(&supports_deactivate); @@ -889,8 +846,8 @@ static int __init gic_of_init(struct device_node *node, struct device_node *pare gic_irqs = 1020; gic_data.irq_nr = gic_irqs; - gic_data.domain = irq_domain_add_tree(node, &gic_irq_domain_ops, - &gic_data); + gic_data.domain = irq_domain_create_tree(handle, &gic_irq_domain_ops, + &gic_data); gic_data.rdists.rdist = alloc_percpu(typeof(*gic_data.rdists.rdist)); if (WARN_ON(!gic_data.domain) || WARN_ON(!gic_data.rdists.rdist)) { @@ -900,7 +857,9 @@ static int __init gic_of_init(struct device_node *node, struct device_node *pare set_handle_irq(gic_handle_irq); - if (IS_ENABLED(CONFIG_ARM_GIC_V3_ITS) && gic_dist_supports_lpis()) + node = to_of_node(handle); + if (IS_ENABLED(CONFIG_ARM_GIC_V3_ITS) && gic_dist_supports_lpis() && + node) /* Temp hack to prevent ITS init for ACPI */ its_init(node, &gic_data.rdists, gic_data.domain); gic_smp_init(); @@ -914,6 +873,73 @@ out_free: if (gic_data.domain) irq_domain_remove(gic_data.domain); free_percpu(gic_data.rdists.rdist); + return err; +} + +static int __init gic_validate_dist_version(void __iomem *dist_base) +{ + u32 reg = readl_relaxed(dist_base + GICD_PIDR2) & GIC_PIDR2_ARCH_MASK; + + if (reg != GIC_PIDR2_ARCH_GICv3 && reg != GIC_PIDR2_ARCH_GICv4) + return -ENODEV; + + return 0; +} + +static int __init gic_of_init(struct device_node *node, struct device_node *parent) +{ + void __iomem *dist_base; + struct redist_region *rdist_regs; + u64 redist_stride; + u32 nr_redist_regions; + int err, i; + + dist_base = of_iomap(node, 0); + if (!dist_base) { + pr_err("%s: unable to map gic dist registers\n", + node->full_name); + return -ENXIO; + } + + err = gic_validate_dist_version(dist_base); + if (err) { + pr_err("%s: no distributor detected, giving up\n", + node->full_name); + goto out_unmap_dist; + } + + if (of_property_read_u32(node, "#redistributor-regions", &nr_redist_regions)) + nr_redist_regions = 1; + + rdist_regs = kzalloc(sizeof(*rdist_regs) * nr_redist_regions, GFP_KERNEL); + if (!rdist_regs) { + err = -ENOMEM; + goto out_unmap_dist; + } + + for (i = 0; i < nr_redist_regions; i++) { + struct resource res; + int ret; + + ret = of_address_to_resource(node, 1 + i, &res); + rdist_regs[i].redist_base = of_iomap(node, 1 + i); + if (ret || !rdist_regs[i].redist_base) { + pr_err("%s: couldn't map region %d\n", + node->full_name, i); + err = -ENODEV; + goto out_unmap_rdist; + } + rdist_regs[i].phys_base = res.start; + } + + if (of_property_read_u64(node, "redistributor-stride", &redist_stride)) + redist_stride = 0; + + err = gic_init_bases(dist_base, rdist_regs, nr_redist_regions, + redist_stride, &node->fwnode); + if (!err) + return 0; + out_unmap_rdist: for (i = 0; i < nr_redist_regions; i++) if (rdist_regs[i].redist_base)