From patchwork Mon Jan 2 22:30:15 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sinan Kaya X-Patchwork-Id: 9494185 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 A735760414 for ; Mon, 2 Jan 2017 22:33:00 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 99D9024560 for ; Mon, 2 Jan 2017 22:33:00 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8E1152684F; Mon, 2 Jan 2017 22:33:00 +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=-6.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI, T_DKIM_INVALID, T_TVD_MIME_EPI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D751724560 for ; Mon, 2 Jan 2017 22:32:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756370AbdABWa4 (ORCPT ); Mon, 2 Jan 2017 17:30:56 -0500 Received: from smtp.codeaurora.org ([198.145.29.96]:43644 "EHLO smtp.codeaurora.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750735AbdABWaV (ORCPT ); Mon, 2 Jan 2017 17:30:21 -0500 Received: by smtp.codeaurora.org (Postfix, from userid 1000) id 92E7861406; Mon, 2 Jan 2017 22:30:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1483396220; bh=0irY1sLM3qMBb9+G1dV1r2GUvVtKuKvDGFOW6XJRyn8=; h=Subject:To:References:Cc:From:Date:In-Reply-To:From; b=eR1RFe1O+4GhqssNRzKQKUOyLEaYPIkxwwyvZAlKbkY/uaXyYywUJSVDEoOZvrAk3 1ljouRa06RdhEGKFT1ccKpL2qR+R+3DDKK0bmaEsOOmeBHjzLEqIkczoq2ya0To9s9 3anYbe4GYr0I7moA9pM/uRPzuXdnRkYYZKW3BWTU= Received: from [10.228.68.15] (global_nat1_iad_fw.qualcomm.com [129.46.232.65]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: okaya@smtp.codeaurora.org) by smtp.codeaurora.org (Postfix) with ESMTPSA id B533F612D0; Mon, 2 Jan 2017 22:30:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1483396218; bh=0irY1sLM3qMBb9+G1dV1r2GUvVtKuKvDGFOW6XJRyn8=; h=Subject:To:References:Cc:From:Date:In-Reply-To:From; b=XKDH4YR8JR0znmyexg5JIg9VfqfYTiGet1KIHpRJcWdBVAyOhHPPrZ7rlap+TYbGS JsjpjBiLFbzY6t/4Y4nivPNK6cl2ylw5U4nr/wOb4BrlyhlxeNEyehiXeT6PYAULCM XeuaQlRt8HMyYFQjs8zd+LmqvuvDPFJ7VfcmJqGg= DMARC-Filter: OpenDMARC Filter v1.3.1 smtp.codeaurora.org B533F612D0 Authentication-Results: pdx-caf-mail.web.codeaurora.org; dmarc=none header.from=codeaurora.org Authentication-Results: pdx-caf-mail.web.codeaurora.org; spf=pass smtp.mailfrom=okaya@codeaurora.org Subject: Re: [PATCH v6 10/14] ACPI: ARM64: IORT: rework iort_node_get_id() for NC->SMMU->ITS case To: Hanjun Guo , Marc Zyngier , "Rafael J. Wysocki" , Lorenzo Pieralisi References: <1483363905-2806-1-git-send-email-hanjun.guo@linaro.org> <1483363905-2806-11-git-send-email-hanjun.guo@linaro.org> Cc: linux-acpi@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linuxarm@huawei.com, Thomas Gleixner , Greg KH , Tomasz Nowicki , Ma Jun , Kefeng Wang , Agustin Vega-Frias , charles.garcia-tobin@arm.com, huxinwei@huawei.com, yimin@huawei.com, Jon Masters From: Sinan Kaya Message-ID: Date: Mon, 2 Jan 2017 17:30:15 -0500 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:45.0) Gecko/20100101 Thunderbird/45.6.0 MIME-Version: 1.0 In-Reply-To: <1483363905-2806-11-git-send-email-hanjun.guo@linaro.org> Sender: linux-acpi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Hi Hanjun, On 1/2/2017 8:31 AM, Hanjun Guo wrote: > iort_node_get_id() for now only support NC(named componant)->SMMU > or NC->ITS cases, we also have other device topology such NC-> > SMMU->ITS, so rework iort_node_get_id() for those cases. > > Signed-off-by: Hanjun Guo > Tested-by: Majun > Tested-by: Xinwei Kong > Cc: Lorenzo Pieralisi > --- > drivers/acpi/arm64/iort.c | 61 ++++++++++++++++++++++++++--------------------- > 1 file changed, 34 insertions(+), 27 deletions(-) > > diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c > index 6b72fcb..99f079b 100644 > --- a/drivers/acpi/arm64/iort.c > +++ b/drivers/acpi/arm64/iort.c > @@ -292,22 +292,28 @@ static acpi_status iort_match_node_callback(struct acpi_iort_node *node, > return status; > } > > -static int iort_id_map(struct acpi_iort_id_mapping *map, u8 type, u32 rid_in, > - u32 *rid_out) > +static int iort_id_single_map(struct acpi_iort_id_mapping *map, u8 type, > + u32 *rid_out) > { > /* 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) { > - *rid_out = map->output_base; > + if (rid_out) > + *rid_out = map->output_base; > return 0; > } > > pr_warn(FW_BUG "[map %p] SINGLE MAPPING flag not allowed for node type %d, skipping ID map\n", > map, type); > - return -ENXIO; > } > > + return -ENXIO; > +} > + > +static int iort_id_map(struct acpi_iort_id_mapping *map, u32 rid_in, > + u32 *rid_out) > +{ > if (rid_in < map->input_base || > (rid_in >= map->input_base + map->id_count)) > return -ENXIO; > @@ -324,33 +330,34 @@ struct acpi_iort_node *iort_node_get_id(struct acpi_iort_node *node, > struct acpi_iort_node *parent; > struct acpi_iort_id_mapping *map; > > - if (!node->mapping_offset || !node->mapping_count || > - index >= node->mapping_count) > - return NULL; > - > - map = ACPI_ADD_PTR(struct acpi_iort_id_mapping, node, > - node->mapping_offset); > + while (node) { > + if (!node->mapping_offset || !node->mapping_count || > + index >= node->mapping_count) > + return NULL; > > - /* Firmware bug! */ > - if (!map->output_reference) { > - pr_err(FW_BUG "[node %p type %d] ID map has NULL parent reference\n", > - node, node->type); > - return NULL; > - } > + map = ACPI_ADD_PTR(struct acpi_iort_id_mapping, node, > + node->mapping_offset); > > - parent = ACPI_ADD_PTR(struct acpi_iort_node, iort_table, > - map->output_reference); > + /* Firmware bug! */ > + if (!map->output_reference) { > + pr_err(FW_BUG "[node %p type %d] ID map has NULL parent reference\n", > + node, node->type); > + return NULL; > + } > > - if (!(IORT_TYPE_MASK(parent->type) & type_mask)) > - return NULL; > + parent = ACPI_ADD_PTR(struct acpi_iort_node, iort_table, > + map->output_reference); > > - if (map[index].flags & ACPI_IORT_ID_SINGLE_MAPPING) { > - if (node->type == ACPI_IORT_NODE_NAMED_COMPONENT || > - node->type == ACPI_IORT_NODE_PCI_ROOT_COMPLEX) { > - if (id_out) > - *id_out = map[index].output_base; > - return parent; > + /* go upstream to find its parent */ > + if (!(IORT_TYPE_MASK(parent->type) & type_mask)) { > + node = parent; > + continue; > } > + > + if (iort_id_single_map(&map[index], node->type, id_out)) > + break; > + > + return parent; > } > > return NULL; > @@ -388,7 +395,7 @@ static struct acpi_iort_node *iort_node_map_rid(struct acpi_iort_node *node, > > /* Do the RID translation */ > for (i = 0; i < node->mapping_count; i++, map++) { > - if (!iort_id_map(map, node->type, rid, &rid)) > + if (!iort_id_map(map, rid, &rid)) > break; > } > > I wanted to follow up on your note for NC->SMMU->ITS case as I do have this use case on the Qualcomm QDF2400 server and HIDMA DMA Engine. HIDMA is capable of sending MSI interrupts towards the GIC ITS. I don't know if this patch is supposed to fix the NC->SMMU->ITS case as it suggests in the commit message but it doesn't seems to be working for me. Maybe, it was a to do for you. It wasn't quite clear from the commit. I debugged the code and came up with the following patch. Feel free to incorporate/rework with your existing patch. A named node can have an output ID of 0x20 and SMMU can have an output parameter of 0x80000. The device ID needs to be 0x80000+0x20 for this use case. With the addition of this patch on top of the first 11 patches, I'm also providing my tested by here for the first 11 patches. Tested-by: Sinan Kaya diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c index 882e624..19cb97a 100644 --- a/drivers/acpi/arm64/iort.c +++ b/drivers/acpi/arm64/iort.c @@ -296,18 +296,16 @@ static int iort_id_single_map(struct acpi_iort_id_mapping *map, u8 type, u32 *rid_out) { /* 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) { - if (rid_out) - *rid_out = map->output_base; - return 0; - } - - pr_warn(FW_BUG "[map %p] SINGLE MAPPING flag not allowed for node type %d, skipping ID map\n", - map, type); + if (type == ACPI_IORT_NODE_NAMED_COMPONENT || + type == ACPI_IORT_NODE_PCI_ROOT_COMPLEX) { + if (rid_out) + *rid_out = map->output_base; + return 0; } + pr_warn(FW_BUG "[map %p] SINGLE MAPPING flag not allowed for node type %d, skipping ID map\n", + map, type); + return -ENXIO; } @@ -327,13 +325,20 @@ struct acpi_iort_node *iort_node_get_id(struct acpi_iort_node *node, u32 *id_out, u8 type_mask, int index) { - struct acpi_iort_node *parent; - struct acpi_iort_id_mapping *map; + u32 id = 0; while (node) { - if (!node->mapping_offset || !node->mapping_count || - index >= node->mapping_count) - return NULL; + struct acpi_iort_id_mapping *map; + + if (IORT_TYPE_MASK(node->type) & type_mask) { + if (id_out) + *id_out = id; + + return node; + } + + if (!node->mapping_offset || !node->mapping_count) + goto fail_map; map = ACPI_ADD_PTR(struct acpi_iort_id_mapping, node, node->mapping_offset); @@ -342,24 +347,25 @@ struct acpi_iort_node *iort_node_get_id(struct acpi_iort_node *node, if (!map->output_reference) { pr_err(FW_BUG "[node %p type %d] ID map has NULL parent reference\n", node, node->type); - return NULL; + goto fail_map; } - parent = ACPI_ADD_PTR(struct acpi_iort_node, iort_table, - map->output_reference); - - /* go upstream to find its parent */ - if (!(IORT_TYPE_MASK(parent->type) & type_mask)) { - node = parent; - continue; + if (map->flags & ACPI_IORT_ID_SINGLE_MAPPING) { + if (iort_id_single_map(&map[index], node->type, &id)) + goto fail_map; + } else { + if (iort_id_map(map, id, &id)) + goto fail_map; } - if (iort_id_single_map(&map[index], node->type, id_out)) - break; + if (index == node->mapping_count) + goto fail_map; - return parent; + node = ACPI_ADD_PTR(struct acpi_iort_node, iort_table, + map->output_reference); } +fail_map: return NULL; }