From patchwork Wed Jan 11 15:06:33 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hanjun Guo X-Patchwork-Id: 9510441 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 9827F601E7 for ; Wed, 11 Jan 2017 15:23:11 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8783428616 for ; Wed, 11 Jan 2017 15:23:11 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7A01428634; Wed, 11 Jan 2017 15:23:11 +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.1 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED, T_DKIM_INVALID autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 3DFFF28616 for ; Wed, 11 Jan 2017 15:23:07 +0000 (UTC) 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 1cRKjx-0006xn-W7; Wed, 11 Jan 2017 15:23:06 +0000 Received: from casper.infradead.org ([2001:770:15f::2]) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1cRKjv-0006OT-5i for linux-arm-kernel@bombadil.infradead.org; Wed, 11 Jan 2017 15:23:03 +0000 Received: from mail-pf0-x232.google.com ([2607:f8b0:400e:c00::232]) by casper.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1cRKWL-0007TF-Bj for linux-arm-kernel@lists.infradead.org; Wed, 11 Jan 2017 15:09:10 +0000 Received: by mail-pf0-x232.google.com with SMTP id 189so50729382pfu.3 for ; Wed, 11 Jan 2017 07:08:43 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=4NJV2iuhDBj0CiGYdTjLdkSqOlIyuaR7FmLKYrt/Dxc=; b=AksnF2x7S+uwnrViepSwCh5oiM7gSoTBY71rcJmucRn/adJb4hZI3okTJXBjwaS6z5 cOuaA/A4GjaRiMzTdGcl1oiXQ4D8A0kM1OFG9rYZqpiZLls2cGGtwFT3Ap7HDjIRHlwH MavXl0u8QZTRojr41w+QKj4Zp1nRhfXLctnYg= 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=4NJV2iuhDBj0CiGYdTjLdkSqOlIyuaR7FmLKYrt/Dxc=; b=jq52RzlkYXmteYuMw+5O/VdaO54hIMEHbkytF3CjrssoZzTM10t1/NgCLbqNUXhjsv nefmyxiQm6vzk1k3l88LghH+vd8n0cSHf/1pQHVbfnH396UdlA8jwtq3IVvg271qJ+dw xqgZBRY2LsAyFII6Kfn4lCLSFp/Cbauh4oz0qq6xJaVWIA2IgIC+yBXBlT1sFxH0CpnZ hN/XjOCX7Ww149TyG1s4feKQwb5lS5A2QKpjLUjAnN2KMHBZbnCfi7CQTAwf4qvwfkkc cAWAAIy8kSUDZXRk5KZ0Fgtn4t1jjeuj2W2+eVj0WW0nLOFGMIibDAmXfFS9ak6oFL3B QQKA== X-Gm-Message-State: AIkVDXKyGuYxyD9ngkfBwZvi7M1kL4WSW5JeLVjPdHbYf2IImHGuIJ8NePa+g+Uhb9/Svj3b X-Received: by 10.84.133.129 with SMTP id f1mr13848191plf.64.1484147321674; Wed, 11 Jan 2017 07:08:41 -0800 (PST) Received: from localhost ([104.237.91.103]) by smtp.googlemail.com with ESMTPSA id 78sm14657525pfj.23.2017.01.11.07.08.39 (version=TLS1_2 cipher=AES128-SHA bits=128/128); Wed, 11 Jan 2017 07:08:41 -0800 (PST) From: Hanjun Guo To: Marc Zyngier , "Rafael J. Wysocki" , Lorenzo Pieralisi Subject: [PATCH v7 09/15] ACPI: platform-msi: retrieve dev id from IORT Date: Wed, 11 Jan 2017 23:06:33 +0800 Message-Id: <1484147199-4267-10-git-send-email-hanjun.guo@linaro.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1484147199-4267-1-git-send-email-hanjun.guo@linaro.org> References: <1484147199-4267-1-git-send-email-hanjun.guo@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20170111_150901_593258_DA88BDF7 X-CRM114-Status: GOOD ( 26.03 ) 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: huxinwei@huawei.com, Kefeng Wang , Matthias Brugger , Jon Masters , yimin@huawei.com, Greg KH , linux-kernel@vger.kernel.org, linuxarm@huawei.com, Sinan Kaya , linux-acpi@vger.kernel.org, Xinwei Kong , Hanjun Guo , Tomasz Nowicki , Thomas Gleixner , Agustin Vega-Frias , linux-arm-kernel@lists.infradead.org, Ma Jun 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 For devices connecting to ITS, it needs dev id to identify itself, and this dev id is represented in the IORT table in named component node [1] for platform devices, so in this patch we will scan the IORT to retrieve device's dev id. For named components we know that there are always two steps involved (second optional): (1) Retrieve the initial id (this may well provide the final mapping) (2) Map the id (optional if (1) represents the map type we need), this is needed for use cases such as NC (named component) -> SMMU -> ITS mappings. we have API iort_node_get_id() for step (1) above and iort_node_map_rid() for step (2), so create a wrapper iort_node_map_platform_id() to retrieve the dev id. [1]: https://static.docs.arm.com/den0049/b/DEN0049B_IO_Remapping_Table.pdf Suggested-by: Lorenzo Pieralisi Suggested-by: Tomasz Nowicki Signed-off-by: Hanjun Guo Cc: Marc Zyngier Cc: Lorenzo Pieralisi Cc: Sinan Kaya Cc: Tomasz Nowicki Cc: Thomas Gleixner --- drivers/acpi/arm64/iort.c | 56 +++++++++++++++++++++++++++ drivers/irqchip/irq-gic-v3-its-platform-msi.c | 4 +- include/linux/acpi_iort.h | 8 ++++ 3 files changed, 67 insertions(+), 1 deletion(-) diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c index 069a690..95fd20b 100644 --- a/drivers/acpi/arm64/iort.c +++ b/drivers/acpi/arm64/iort.c @@ -30,6 +30,7 @@ #define IORT_MSI_TYPE (1 << ACPI_IORT_NODE_ITS_GROUP) #define IORT_IOMMU_TYPE ((1 << ACPI_IORT_NODE_SMMU) | \ (1 << ACPI_IORT_NODE_SMMU_V3)) +#define IORT_TYPE_ANY (IORT_MSI_TYPE | IORT_IOMMU_TYPE) struct iort_its_msi_chip { struct list_head list; @@ -406,6 +407,34 @@ static struct acpi_iort_node *iort_node_map_id(struct acpi_iort_node *node, return NULL; } +static +struct acpi_iort_node *iort_node_map_platform_id(struct acpi_iort_node *node, + u32 *id_out, u8 type_mask, + int index) +{ + struct acpi_iort_node *parent; + u32 id; + + /* step 1: retrieve the initial dev id */ + parent = iort_node_get_id(node, &id, IORT_TYPE_ANY, index); + if (!parent) + return NULL; + + /* + * optional step 2: map the initial dev id if its parent is not + * the target type we wanted, map it again for the use cases such + * as NC (named component) -> SMMU -> ITS. If the type is matched, + * return the parent pointer directly. + */ + if (!(IORT_TYPE_MASK(parent->type) & type_mask)) + parent = iort_node_map_id(parent, id, id_out, type_mask); + else + if (id_out) + *id_out = id; + + return parent; +} + static struct acpi_iort_node *iort_find_dev_node(struct device *dev) { struct pci_bus *pbus; @@ -444,6 +473,33 @@ u32 iort_msi_map_rid(struct device *dev, u32 req_id) } /** + * iort_pmsi_get_dev_id() - Get the device id for a device + * @dev: The device for which the mapping is to be done. + * @dev_id: The device ID found. + * + * Returns: 0 for successful find a dev id, errors otherwise + */ +int iort_pmsi_get_dev_id(struct device *dev, u32 *dev_id) +{ + int i; + struct acpi_iort_node *node; + + if (!iort_table) + return -ENODEV; + + node = iort_find_dev_node(dev); + 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)) + return 0; + } + + return -ENODEV; +} + +/** * iort_dev_find_its_id() - Find the ITS identifier for a device * @dev: The device. * @req_id: Device's requester ID diff --git a/drivers/irqchip/irq-gic-v3-its-platform-msi.c b/drivers/irqchip/irq-gic-v3-its-platform-msi.c index ebe933e..e801fc0 100644 --- a/drivers/irqchip/irq-gic-v3-its-platform-msi.c +++ b/drivers/irqchip/irq-gic-v3-its-platform-msi.c @@ -15,6 +15,7 @@ * along with this program. If not, see . */ +#include #include #include #include @@ -56,7 +57,8 @@ static int its_pmsi_prepare(struct irq_domain *domain, struct device *dev, msi_info = msi_get_domain_info(domain->parent); - ret = of_pmsi_get_dev_id(domain, dev, &dev_id); + ret = dev->of_node ? of_pmsi_get_dev_id(domain, dev, &dev_id) : + iort_pmsi_get_dev_id(dev, &dev_id); if (ret) return ret; diff --git a/include/linux/acpi_iort.h b/include/linux/acpi_iort.h index 77e0809..ef99fd52 100644 --- a/include/linux/acpi_iort.h +++ b/include/linux/acpi_iort.h @@ -33,6 +33,7 @@ void acpi_iort_init(void); bool iort_node_match(u8 type); u32 iort_msi_map_rid(struct device *dev, u32 req_id); +int iort_pmsi_get_dev_id(struct device *dev, u32 *dev_id); struct irq_domain *iort_get_device_domain(struct device *dev, u32 req_id); /* IOMMU interface */ void iort_set_dma_mask(struct device *dev); @@ -42,9 +43,16 @@ static inline void acpi_iort_init(void) { } static inline bool iort_node_match(u8 type) { return false; } static inline u32 iort_msi_map_rid(struct device *dev, u32 req_id) { return req_id; } + static inline struct irq_domain *iort_get_device_domain(struct device *dev, u32 req_id) { return NULL; } + +static inline int iort_pmsi_get_dev_id(struct device *dev, u32 *dev_id) +{ + return -ENODEV; +} + /* IOMMU interface */ static inline void iort_set_dma_mask(struct device *dev) { } static inline