Received: by 10.223.176.46 with SMTP id f43csp25885wra; Thu, 25 Jan 2018 16:48:05 -0800 (PST) X-Google-Smtp-Source: AH8x2249qPqysr9Da+wNuttJOzkSVs3yQD+lgTX9KOHCPrKWAMmPiPVToS0lIdT75T3369c0whej X-Received: by 10.99.126.75 with SMTP id o11mr14344095pgn.97.1516927684918; Thu, 25 Jan 2018 16:48:04 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1516927684; cv=none; d=google.com; s=arc-20160816; b=TS2HYYPZ9LrgBFyXAXpwQRxnvxR988hoj7yCMs21Ae5VLbBugw51LWkskuasRT+8WB Gk+2rdSM+D13xx3cn3swdeiOhYq4aqkjcBSRwaZZvo3ZjFgJP/C5g0CSeeFoCiyuZ8qx bKJ4w0xLO2z0EYxgk+GsZtRDo5qMBwXV0zt+3nR0oCNzYuSeCgsy3VkHLceaXQojTFBj gCfPbma2bnCvJsaa3uleo2HENiIqfUYcTDYmw+fwv2wBC3XkbWRq5Q6m1inSwEXUB28K rCJyxFOz+W0VyBkyB/sWCcuycCRdDfxbWAoYkXmZuVA5XEcQaFbzXaX2nsSVKle5+dzZ Yd2A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:message-id:date:subject:cc:to:from :dmarc-filter:dkim-signature:dkim-signature :arc-authentication-results; bh=YxeaQAEi8cybTfKGS0U6qBzbNWNSKqkpfPXtugmmtro=; b=WqzYA4+168CQx8Itgoh2kDUoBff93hr9F5/X6p5uJVi/o/aCQyDVaHhG2Z0KMAs8uw +Efd77YocCaoYwxoiJQxymzEs/oXUsE1x5+FvCys4daCcm8DX8vxQ3vHsC57Ugfsm2KO /Kv/pu+PLTwy/ofoSan1BCoZUFZtvc/hEt+rI+pNGB+4XB3wZsvaeARPk+ZNMTcJP436 NoPDtz0ZDw5J+vd7IOLUUcb1Uo7gv70ZUZb6OTcO49RHJqhSnlMGzqqgfgkmonvoYZYR LIfET8yuYvoBcgO/D91OYKMTidTxNav/bnsTh3dGwhdV1s57zxBiih9r7vuNxOgbG1Fk 3NnA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@codeaurora.org header.s=default header.b=BTJRv7Qa; dkim=pass header.i=@codeaurora.org header.s=default header.b=QUmSui3+; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id g5-v6si1877532pll.591.2018.01.25.16.47.50; Thu, 25 Jan 2018 16:48:04 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@codeaurora.org header.s=default header.b=BTJRv7Qa; dkim=pass header.i=@codeaurora.org header.s=default header.b=QUmSui3+; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751839AbeAZAq4 (ORCPT + 99 others); Thu, 25 Jan 2018 19:46:56 -0500 Received: from smtp.codeaurora.org ([198.145.29.96]:59740 "EHLO smtp.codeaurora.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751408AbeAZAqy (ORCPT ); Thu, 25 Jan 2018 19:46:54 -0500 Received: by smtp.codeaurora.org (Postfix, from userid 1000) id 1ED916050D; Fri, 26 Jan 2018 00:46:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1516927614; bh=/dZZuxgd4UUbWN614mu2eBnlx+fyV/6zQuuc1U+QuA0=; h=From:To:Cc:Subject:Date:From; b=BTJRv7Qafb2bmNmwe5kj5PbwUFrAeIMP475KPOrThJjtQbSezFd+00eqfmQ0lJlMW rtbbDi2BjH7JqJk8rrioM9wkYqca83rFHQ5QO9zYm5DQMfjXRi9Ldgs603BLH4BO+E PpAnjY5LSXF7zm8lmAeEKcsBbEUDV606ABT1FMY4= X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on pdx-caf-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.8 required=2.0 tests=ALL_TRUSTED,BAYES_00, DKIM_SIGNED,T_DKIM_INVALID autolearn=no autolearn_force=no version=3.4.0 Received: from sboyd-linux.qualcomm.com (i-global254.qualcomm.com [199.106.103.254]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: sboyd@smtp.codeaurora.org) by smtp.codeaurora.org (Postfix) with ESMTPSA id 72C8B60AD5; Fri, 26 Jan 2018 00:46:52 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1516927612; bh=/dZZuxgd4UUbWN614mu2eBnlx+fyV/6zQuuc1U+QuA0=; h=From:To:Cc:Subject:Date:From; b=QUmSui3+SPHvEFuYECDG75+G+m9opWg+Y6YmMUUimJPyJfxjTWRBLT+eNgyAIL1pr U1LUCn9gn75lkoklwGS593DrcpIDnj7Pmm8OFCJWXyxfUS0ZowjNzjq+VcjEDrtta4 u+gJ3OvKfxuL8zVklsDwNixb450pFDv5phte1jYE= DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org 72C8B60AD5 Authentication-Results: pdx-caf-mail.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: pdx-caf-mail.web.codeaurora.org; spf=none smtp.mailfrom=sboyd@codeaurora.org From: Stephen Boyd To: Thomas Gleixner , Jason Cooper , Marc Zyngier Cc: linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org Subject: [PATCH/RESEND] irqchip/gic-v3: Support MSIs via aliases and distributor Date: Thu, 25 Jan 2018 16:46:51 -0800 Message-Id: <20180126004651.19400-1-sboyd@codeaurora.org> X-Mailer: git-send-email 2.15.0.374.g5f9953d2c365 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Some GIC configurations don't have an accessible ITS, but they want to support MSIs through the distributor's SETSPI registers or through the IMPLEMENTATION DEFINED message-based interrupt request register region. This mode of operation is similar to the v2m support on gic-400, but we don't necessarily know what particular SPIs are supported as MSIs so we need some help from firmware to know what to do. Introduce an "arm,spi-ranges" property for this, similar to the "marvell,spi-ranges" property, that indicates the base and size of each MSI range. This property applies equally to the distributor and alias registers. In either case, we detect this mode of operation by looking for a node with the "msi-controller" property and then probe the v2m frame code on top of it. Assume these nodes will have the "arm,spi-ranges" property in them so that the v2m code works mostly unmodified. Cc: Acked-by: Rob Herring Tested-by: Srinivas Kandagatla Cc: Marc Zyngier Signed-off-by: Stephen Boyd --- Picked up acks/tested-by. .../bindings/interrupt-controller/arm,gic-v3.txt | 48 +++++++++- drivers/irqchip/irq-gic-v2m.c | 102 ++++++++++++++++----- drivers/irqchip/irq-gic-v3.c | 4 + include/linux/irqchip/arm-gic-common.h | 3 + 4 files changed, 129 insertions(+), 28 deletions(-) diff --git a/Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.txt b/Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.txt index 0a57f2f4167d..ef319ac41be3 100644 --- a/Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.txt +++ b/Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.txt @@ -57,6 +57,11 @@ Optional occupied by the redistributors. Required if more than one such region is present. +- msi-controller : Boolean property. Identifies the node as an MSI controller + +- arm,spi-ranges : Tuples of GIC SPI interrupt ranges (base, size) indicating + SPIs available for use as MSIs. + Sub-nodes: PPI affinity can be expressed as a single "ppi-partitions" node, @@ -75,14 +80,28 @@ These nodes must have the following properties: - reg: Specifies the base physical address and size of the ITS registers. +GICv3 has an IMPLEMENTATION DEFINED set of aliases for message-based interrupt +requests. + +These nodes must have the following properties: +- compatible : Should at least contain one of + "qcom,gic-msi-aliases". +- msi-controller : Boolean property. Identifies the node as an MSI controller +- #msi-cells: Must be <1>. The single msi-cell is the DeviceID of the device + which will generate the MSI. +- reg: Specifies the base physical address and size of the message-based + interrupt request registers. +- arm,spi-ranges: Tuples of GIC SPI interrupt ranges (base, size) indicating + SPIs available for use as MSIs. + +Note: The main GIC node must contain the appropriate #address-cells, +#size-cells and ranges properties for the reg property of all ITS and +alias message-based interrupt nodes. + Optional: - socionext,synquacer-pre-its: (u32, u32) tuple describing the untranslated address and size of the pre-ITS window. -The main GIC node must contain the appropriate #address-cells, -#size-cells and ranges properties for the reg property of all ITS -nodes. - Examples: gic: interrupt-controller@2cf00000 { @@ -149,6 +168,27 @@ Examples: }; }; + intc: interrupt-controller@9bc0000 { + compatible = "arm,gic-v3"; + #interrupt-cells = <3>; + #address-cells = <1>; + #size-cells = <1>; + ranges; + interrupt-controller; + #redistributor-regions = <1>; + redistributor-stride = <0x0 0x40000>; + reg = <0x09bc0000 0x10000>, + <0x09c00000 0x100000>; + interrupts = <1 9 4>; + + msi_alias0: interrupt-controller@9bd0000 { + compatible = "qcom,gic-msi-aliases"; + reg = <0x9bd0000 0x1000>; + msi-controller; + #msi-cells = <1>; + arm,spi-ranges = <544 96>; + }; + }; device@0 { reg = <0 0 0 4>; diff --git a/drivers/irqchip/irq-gic-v2m.c b/drivers/irqchip/irq-gic-v2m.c index 993a8426a453..a254c29dbe69 100644 --- a/drivers/irqchip/irq-gic-v2m.c +++ b/drivers/irqchip/irq-gic-v2m.c @@ -26,6 +26,7 @@ #include #include #include +#include /* * MSI_TYPER: @@ -383,13 +384,57 @@ static int __init gicv2m_init_one(struct fwnode_handle *fwnode, return ret; } -static struct of_device_id gicv2m_device_id[] = { - { .compatible = "arm,gic-v2m-frame", }, - {}, +static const struct of_device_id gicv2m_device_id[] = { + { .compatible = "arm,gic-v2m-frame", }, + { .compatible = "qcom,gic-msi-aliases", }, + {} }; -static int __init gicv2m_of_init(struct fwnode_handle *parent_handle, - struct irq_domain *parent) +static int __init gicv2m_of_init_one(struct device_node *child) +{ + u32 spi_start = 0, nr_spis = 0; + struct resource res; + int ret, i, cnt; + struct fwnode_handle *fwnode = &child->fwnode; + + if (!of_find_property(child, "msi-controller", NULL)) + return 0; + + ret = of_address_to_resource(child, 0, &res); + if (ret) { + pr_err("Failed to allocate v2m resource\n"); + return ret; + } + + if (!of_property_read_u32(child, "arm,msi-base-spi", + &spi_start) && + !of_property_read_u32(child, "arm,msi-num-spis", &nr_spis)) + pr_info("DT overriding V2M MSI_TYPER (base:%u, num:%u)\n", + spi_start, nr_spis); + + cnt = of_property_count_u32_elems(child, "arm,spi-ranges"); + if (cnt < 0) + cnt = 0; + cnt /= 2; + + if (!cnt) + return gicv2m_init_one(fwnode, spi_start, nr_spis, &res); + + /* Populate v2m for each SPI range */ + for (i = 0; i < cnt; i++) { + of_property_read_u32_index(child, "arm,spi-ranges", + i * 2, &spi_start); + of_property_read_u32_index(child, "arm,spi-ranges", + i * 2 + 1, &nr_spis); + ret = gicv2m_init_one(fwnode, spi_start, nr_spis, &res); + if (ret) + return ret; + } + + return 0; +} + +static int __init gicv2m_of_init_children(struct fwnode_handle *parent_handle) { int ret = 0; struct device_node *node = to_of_node(parent_handle); @@ -397,35 +442,27 @@ static int __init gicv2m_of_init(struct fwnode_handle *parent_handle, for (child = of_find_matching_node(node, gicv2m_device_id); child; child = of_find_matching_node(child, gicv2m_device_id)) { - u32 spi_start = 0, nr_spis = 0; - struct resource res; - - if (!of_find_property(child, "msi-controller", NULL)) - continue; - - ret = of_address_to_resource(child, 0, &res); - if (ret) { - pr_err("Failed to allocate v2m resource.\n"); - break; - } - - if (!of_property_read_u32(child, "arm,msi-base-spi", - &spi_start) && - !of_property_read_u32(child, "arm,msi-num-spis", &nr_spis)) - pr_info("DT overriding V2M MSI_TYPER (base:%u, num:%u)\n", - spi_start, nr_spis); - - ret = gicv2m_init_one(&child->fwnode, spi_start, nr_spis, &res); + ret = gicv2m_of_init_one(child); if (ret) { of_node_put(child); break; } } + return ret; +} + +static int __init gicv2m_of_init(struct fwnode_handle *parent_handle, + struct irq_domain *parent) +{ + int ret; + + ret = gicv2m_of_init_children(parent_handle); if (!ret) ret = gicv2m_allocate_domains(parent); if (ret) gicv2m_teardown(); + return ret; } @@ -518,6 +555,23 @@ static int __init gicv2m_acpi_init(struct irq_domain *parent) } #endif /* CONFIG_ACPI */ +int __init gicv2m_init_gicv3(struct fwnode_handle *handle, + struct irq_domain *parent) +{ + int ret; + struct device_node *node = to_of_node(handle); + + ret = gicv2m_of_init_children(handle); + if (!ret) + ret = gicv2m_of_init_one(node); + if (!ret) + ret = gicv2m_allocate_domains(parent); + if (ret) + gicv2m_teardown(); + + return ret; +} + int __init gicv2m_init(struct fwnode_handle *parent_handle, struct irq_domain *parent) { diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c index 641b5109f5de..fda2755c4247 100644 --- a/drivers/irqchip/irq-gic-v3.c +++ b/drivers/irqchip/irq-gic-v3.c @@ -1242,6 +1242,10 @@ static int __init gic_of_init(struct device_node *node, struct device_node *pare if (static_key_true(&supports_deactivate)) gic_of_setup_kvm_info(node); + + if (IS_ENABLED(CONFIG_ARM_GIC_V2M)) + gicv2m_init_gicv3(&node->fwnode, gic_data.domain); + return 0; out_unmap_rdist: diff --git a/include/linux/irqchip/arm-gic-common.h b/include/linux/irqchip/arm-gic-common.h index 0a83b4379f34..d2eea9539d37 100644 --- a/include/linux/irqchip/arm-gic-common.h +++ b/include/linux/irqchip/arm-gic-common.h @@ -33,4 +33,7 @@ struct gic_kvm_info { const struct gic_kvm_info *gic_get_kvm_info(void); +int gicv2m_init_gicv3(struct fwnode_handle *parent_handle, + struct irq_domain *parent); + #endif /* __LINUX_IRQCHIP_ARM_GIC_COMMON_H */ -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project