From patchwork Tue Aug 15 17:15:25 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lorenzo Pieralisi X-Patchwork-Id: 9902283 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 47AFF60244 for ; Tue, 15 Aug 2017 17:19:55 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 28007286A0 for ; Tue, 15 Aug 2017 17:19:55 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 1A8F42887B; Tue, 15 Aug 2017 17:19:55 +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=-2.6 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_LOW 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 70528286A0 for ; Tue, 15 Aug 2017 17:19:54 +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:In-Reply-To:MIME-Version:References: Message-ID:Subject:To:From:Date:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=PHsYObl7smimmm+X84NjIGKSnvp6RMQ8tG90ZvnKVjQ=; b=bgi4oOdZx3XnTl pGnaDrY0Eqwv7rpl/FC37Ql55Vr+YlnzjOpy59wV3FosdfrKOFxxo3PvwUVNjCcki3Snxqk0G58K4 TE9GF+U5NGYmlvyuRcZrl4TFY56pys1vpfo6qHRFC/n3f1gdY+KhWv/f2LIVP6l47AswyfsM4fGiw K9uBidaoPfAxUAbX1YEATpQgPdgXeRlIOd8+2aFUQS8WJJhE3s3An6rHWFPXHF7QRc5G9lAw1pCA5 hkkQ/BOlkb3zT9Bynz8q3J44nXnso3YTckkI/kQaidQ9epTjhwLi6hEXZwhek4uM776EtZM2QkOce 9UbR8ErJqyml3T06BGdQ==; 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 1dhfVK-0005Xv-QQ; Tue, 15 Aug 2017 17:19:46 +0000 Received: from casper.infradead.org ([2001:8b0:10b:1236::1]) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1dhfUm-0004k3-A0 for linux-arm-kernel@bombadil.infradead.org; Tue, 15 Aug 2017 17:19:12 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=In-Reply-To:Content-Type:MIME-Version: References:Message-ID:Subject:Cc:To:From:Date:Sender:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id: List-Help:List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=v8WDcbDYVxmCLtef+8C1FbzJBPVcJ70NzXlMQHTfwH8=; b=HTuui9pEwumnI37Hw2Sk3hwVd /a4lHwIrpwFwvcn1mvh7Lzx5VzmprDyPbap/7tGUwHSk9kCZbCYBGsg5Lhyfkpz/tnN8z+voQWhjO xz3ssGBgoZmGFjQ2SklZN1et+ITcNE4AwZ79W3OwBM8w4LgaUbjWESFOvv6A7LOAdbZ69sh3VcR+A 4xKp8nqSJ5sLrsUsWIk4M0qFIh4cMnq3QUZ9O+Iiy5mmaXORisX4dd1SGtmHf0r0FHBpr/rbuHjCY eEJU1HAGklNt2n86zv/3gaFaYtXIV7il25vHrc8Z6CTTBiIIqH0z66xw4T7BNdkPZMpSiCSe7wpHR b2Xiq+aIQ==; Received: from usa-sjc-mx-foss1.foss.arm.com ([217.140.101.70] helo=foss.arm.com) by casper.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1dhfRX-0007x7-8c for linux-arm-kernel@lists.infradead.org; Tue, 15 Aug 2017 17:15:53 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id EA8172B; Tue, 15 Aug 2017 10:15:29 -0700 (PDT) Received: from e107981-lin.cambridge.arm.com (e107981-lin.cambridge.arm.com [10.1.206.250]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 4C2933F483; Tue, 15 Aug 2017 10:15:28 -0700 (PDT) Date: Tue, 15 Aug 2017 18:15:25 +0100 From: Lorenzo Pieralisi To: Hanjun Guo Subject: Re: [RFC PATCH 4/4] ACPI: IORT: Add SMMUv3 MSI support Message-ID: <20170815171525.GB13707@e107981-lin.cambridge.arm.com> References: <1502276017-63108-1-git-send-email-guohanjun@huawei.com> <1502276017-63108-5-git-send-email-guohanjun@huawei.com> <20170811093348.GC26039@red-moon> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.21 (2010-09-15) X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20170815_181551_599925_B5E9AFEE X-CRM114-Status: GOOD ( 46.64 ) 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: "Rafael J. Wysocki" , Marc Zyngier , Linuxarm , Sinan Kaya , "linux-acpi@vger.kernel.org" , Hanjun Guo , "linux-arm-kernel@lists.infradead.org" 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 On Fri, Aug 11, 2017 at 09:56:31PM +0800, Hanjun Guo wrote: > Hi Lorenzo, > > On 11 August 2017 at 17:33, Lorenzo Pieralisi wrote: > > On Wed, Aug 09, 2017 at 06:53:37PM +0800, Hanjun Guo wrote: > >> From: Hanjun Guo > >> > >> Since we have a mapping index for SMMUv3 MSI, we can > >> directly use that index to get the map entry, then > >> retrieve dev ID and ITS parent to add SMMUv3 MSI > >> support. > >> > >> Signed-off-by: Hanjun Guo > >> --- > >> drivers/acpi/arm64/iort.c | 46 ++++++++++++++++++++++++++++++++++++---------- > >> 1 file changed, 36 insertions(+), 10 deletions(-) > >> > >> diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c > >> index 9439f02..ce03298 100644 > >> --- a/drivers/acpi/arm64/iort.c > >> +++ b/drivers/acpi/arm64/iort.c > >> @@ -313,7 +313,8 @@ static int iort_id_map(struct acpi_iort_id_mapping *map, u8 type, u32 rid_in, > >> /* Single mapping does not care for input id */ > >> if (map->flags & ACPI_IORT_ID_SINGLE_MAPPING) { > >> if (type == ACPI_IORT_NODE_NAMED_COMPONENT || > >> - type == ACPI_IORT_NODE_PCI_ROOT_COMPLEX) { > >> + type == ACPI_IORT_NODE_PCI_ROOT_COMPLEX || > >> + type == ACPI_IORT_NODE_SMMU_V3) { > >> *rid_out = map->output_base; > >> return 0; > >> } > >> @@ -357,7 +358,8 @@ struct acpi_iort_node *iort_node_get_id(struct acpi_iort_node *node, > >> > >> if (map->flags & ACPI_IORT_ID_SINGLE_MAPPING) { > >> if (node->type == ACPI_IORT_NODE_NAMED_COMPONENT || > >> - node->type == ACPI_IORT_NODE_PCI_ROOT_COMPLEX) { > >> + node->type == ACPI_IORT_NODE_PCI_ROOT_COMPLEX || > >> + node->type == ACPI_IORT_NODE_SMMU_V3) { > >> *id_out = map->output_base; > >> return parent; > >> } > >> @@ -549,9 +551,21 @@ int iort_pmsi_get_dev_id(struct device *dev, u32 *dev_id) > >> if (!node) > >> return -ENODEV; > >> > >> - for (i = 0; i < node->mapping_count; i++) { > >> - if (iort_node_map_platform_id(node, dev_id, IORT_MSI_TYPE, i)) > >> + if (node->type == ACPI_IORT_NODE_SMMU_V3) { > >> + u32 index; > >> + > >> + if (iort_get_smmu_v3_id_mapping_index(node, &index)) > >> + return -ENODEV; > >> + > >> + if (iort_node_map_platform_id(node, dev_id, IORT_MSI_TYPE, > >> + index)) > >> return 0; > >> + } else { > >> + for (i = 0; i < node->mapping_count; i++) { > >> + if (iort_node_map_platform_id(node, dev_id, > >> + IORT_MSI_TYPE, i)) > >> + return 0; > >> + } > >> } > >> > >> return -ENODEV; > >> @@ -626,20 +640,30 @@ static struct irq_domain *iort_get_platform_device_domain(struct device *dev) > >> struct acpi_iort_node *node, *msi_parent; > >> struct fwnode_handle *iort_fwnode; > >> struct acpi_iort_its_group *its; > >> - int i; > >> > >> /* find its associated iort node */ > >> - node = iort_scan_node(ACPI_IORT_NODE_NAMED_COMPONENT, > >> - iort_match_node_callback, dev); > >> + node = iort_find_dev_node(dev); > >> if (!node) > >> return NULL; > >> > >> /* then find its msi parent node */ > >> - for (i = 0; i < node->mapping_count; i++) { > >> + if (node->type == ACPI_IORT_NODE_SMMU_V3) { > >> + u32 index; > >> + > >> + if (iort_get_smmu_v3_id_mapping_index(node, &index)) > >> + return NULL; > >> + > >> msi_parent = iort_node_map_platform_id(node, NULL, > >> + IORT_MSI_TYPE, index); > >> + } else { > >> + int i; > >> + > >> + for (i = 0; i < node->mapping_count; i++) { > >> + msi_parent = iort_node_map_platform_id(node, NULL, > >> IORT_MSI_TYPE, i); > >> - if (msi_parent) > >> - break; > >> + if (msi_parent) > >> + break; > >> + } > >> } > >> > >> if (!msi_parent) > >> @@ -1233,6 +1257,8 @@ static int __init iort_add_smmu_platform_device(struct acpi_iort_node *node) > >> /* Configure DMA for the page table walker */ > >> acpi_dma_configure(&pdev->dev, attr); > >> > >> + acpi_configure_pmsi_domain(&pdev->dev); > > > > I think this is just overkill. There are two separate things to solve > > here: > > > > 1) Make single mappings valid for SMMUv3 (and PMCG); that's fair enough > > and goes with the logic to skip the ITS DeviceID index for "normal" > > mappings, I can live with that > > 2) Find the MSI domain for an SMMUv3 (or any other IORT table node); I > > do not think you need all this complexity to do it via > > acpi_configure_pmsi_domain(), it can be done in a easier way with > > an ad-hoc stub (it does not even have to be SMMUv3 specific) > > > > My worry is that we are peppering the generic IORT mapping code with > > node types specific kludges and it is becoming a mess. > > Agreed. > > > > > I can rework the patch to show you what I have in mind, please let > > me know. > > Please, thank you very much for doing so. Here, untested just to get your opinion, please let me know. Thanks, Lorenzo -- >8 -- Subject: [PATCH 4/4] ACPI/IORT: IORT nodes MSI handling Signed-off-by: Lorenzo Pieralisi --- drivers/acpi/arm64/iort.c | 76 +++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 63 insertions(+), 13 deletions(-) diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c index 24678c3..21a0aab 100644 --- a/drivers/acpi/arm64/iort.c +++ b/drivers/acpi/arm64/iort.c @@ -366,7 +366,7 @@ struct acpi_iort_node *iort_node_get_id(struct acpi_iort_node *node, return NULL; } -static int iort_get_smmu_v3_id_mapping_index(struct acpi_iort_node *node, +static int iort_get_id_mapping_index(struct acpi_iort_node *node, u32 *index) { struct acpi_iort_smmu_v3 *smmu; @@ -378,20 +378,25 @@ static int iort_get_smmu_v3_id_mapping_index(struct acpi_iort_node *node, if (node->revision < 1) return -EINVAL; - smmu = (struct acpi_iort_smmu_v3 *)node->node_data; - /* if any of the gsi for control interrupts is not 0, ignore the MSI */ - if (smmu->event_gsiv || smmu->pri_gsiv || smmu->gerr_gsiv - || smmu->sync_gsiv) - return -EINVAL; + switch (node->type) { + case ACPI_IORT_NODE_SMMU_V3: + smmu = (struct acpi_iort_smmu_v3 *)node->node_data; + /* if any of the gsi for control interrupts is not 0, ignore the MSI */ + if (smmu->event_gsiv || smmu->pri_gsiv || smmu->gerr_gsiv + || smmu->sync_gsiv) + return -EINVAL; + + if (smmu->id_mapping_index >= node->mapping_count) { + pr_err(FW_BUG "[node %p type %d] ID mapping index overflows valid mappings\n", + node, node->type); + return -EINVAL; + } - if (smmu->id_mapping_index >= node->mapping_count) { - pr_err(FW_BUG "[node %p type %d] ID mapping index overflows valid mappings\n", - node, node->type); + *index = smmu->id_mapping_index; + return 0; + default: return -EINVAL; } - - *index = smmu->id_mapping_index; - return 0; } static struct acpi_iort_node *iort_node_map_id(struct acpi_iort_node *node, @@ -431,7 +436,7 @@ static struct acpi_iort_node *iort_node_map_id(struct acpi_iort_node *node, * associated ID map for single mapping cases. */ if (node->type == ACPI_IORT_NODE_SMMU_V3) - ret = iort_get_smmu_v3_id_mapping_index(node, &index); + ret = iort_get_id_mapping_index(node, &index); /* Do the ID translation */ for (i = 0; i < node->mapping_count; i++, map++) { @@ -620,6 +625,49 @@ struct irq_domain *iort_get_device_domain(struct device *dev, u32 req_id) return irq_find_matching_fwnode(handle, DOMAIN_BUS_PCI_MSI); } +static void iort_set_device_domain(struct device *dev, + struct acpi_iort_node *node) +{ + struct acpi_iort_its_group *its; + struct acpi_iort_node *msi_parent; + struct acpi_iort_id_mapping *map; + struct fwnode_handle *iort_fwnode; + struct irq_domain *domain; + int ret, index; + + ret = iort_get_id_mapping_index(node, &index); + if (ret < 0) + return; + + map = ACPI_ADD_PTR(struct acpi_iort_id_mapping, node, + node->mapping_offset + index * sizeof(*map)); + + /* Firmware bug! */ + if (!map->output_reference || + !(map->flags & ACPI_IORT_ID_SINGLE_MAPPING)) { + pr_err(FW_BUG "[node %p type %d] Invalid MSI mapping\n", + node, node->type); + return; + } + + msi_parent = ACPI_ADD_PTR(struct acpi_iort_node, iort_table, + map->output_reference); + + if (!msi_parent || msi_parent->type != ACPI_IORT_NODE_ITS_GROUP) + return; + + /* Move to ITS specific data */ + its = (struct acpi_iort_its_group *)msi_parent->node_data; + + iort_fwnode = iort_find_domain_token(its->identifiers[0]); + if (!iort_fwnode) + return; + + domain = irq_find_matching_fwnode(iort_fwnode, DOMAIN_BUS_PLATFORM_MSI); + if (domain) + dev_set_msi_domain(dev, domain); +} + /** * iort_get_platform_device_domain() - Find MSI domain related to a * platform device @@ -1159,6 +1207,8 @@ static int __init iort_add_smmu_platform_device(struct acpi_iort_node *node) /* Configure DMA for the page table walker */ acpi_dma_configure(&pdev->dev, attr); + iort_set_device_domain(&pdev->dev, node); + ret = platform_device_add(pdev); if (ret) goto dma_deconfigure;