From patchwork Tue Jun 7 13:30:59 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lorenzo Pieralisi X-Patchwork-Id: 9161279 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 2D7F36086C for ; Tue, 7 Jun 2016 13:33:29 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1DBCB26E1A for ; Tue, 7 Jun 2016 13:33:29 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 0EC7C2656B; Tue, 7 Jun 2016 13:33:29 +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.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=unavailable version=3.3.1 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.wl.linuxfoundation.org (Postfix) with ESMTPS id A7CE42656B for ; Tue, 7 Jun 2016 13:33:28 +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 1bAH6q-0001EH-No; Tue, 07 Jun 2016 13:31:56 +0000 Received: from foss.arm.com ([217.140.101.70]) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1bAH6K-0000mx-On for linux-arm-kernel@lists.infradead.org; Tue, 07 Jun 2016 13:31:26 +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 258D7442; Tue, 7 Jun 2016 06:31:40 -0700 (PDT) Received: from red-moon.cambridge.arm.com (red-moon.cambridge.arm.com [10.1.203.137]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 5DD113F213; Tue, 7 Jun 2016 06:31:03 -0700 (PDT) From: Lorenzo Pieralisi To: iommu@lists.linux-foundation.org Subject: [RFC PATCH v2 04/15] drivers: acpi: iort: add support for IOMMU registration Date: Tue, 7 Jun 2016 14:30:59 +0100 Message-Id: <1465306270-27076-5-git-send-email-lorenzo.pieralisi@arm.com> X-Mailer: git-send-email 2.6.4 In-Reply-To: <1465306270-27076-1-git-send-email-lorenzo.pieralisi@arm.com> References: <1465306270-27076-1-git-send-email-lorenzo.pieralisi@arm.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20160607_063124_935331_6CC11418 X-CRM114-Status: GOOD ( 14.87 ) 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: Lorenzo Pieralisi , Marc Zyngier , Tomasz Nowicki , Joerg Roedel , "Rafael J. Wysocki" , linux-kernel@vger.kernel.org, Will Deacon , Sinan Kaya , linux-acpi@vger.kernel.org, linux-pci@vger.kernel.org, Hanjun Guo , Jon Masters , Robin Murphy , 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-Virus-Scanned: ClamAV using ClamSMTP The ACPI IORT table provide entries for IOMMU (aka SMMU in ARM world) components that allow creating the kernel data structures required to probe and initialize the IOMMU devices. This patch provides support in the IORT kernel code to register IOMMU components and their respective IOMMU operations, along with a hook (ie iommu_xlate()) that is used to translate devices ids to ids usable by the SMMU driver to set-up IOMMU group/domain configuration. Signed-off-by: Lorenzo Pieralisi Cc: Hanjun Guo Cc: Tomasz Nowicki Cc: "Rafael J. Wysocki" --- drivers/acpi/iort.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/iort.h | 5 ++++ 2 files changed, 77 insertions(+) diff --git a/drivers/acpi/iort.c b/drivers/acpi/iort.c index 226eb6d..7cc9880 100644 --- a/drivers/acpi/iort.c +++ b/drivers/acpi/iort.c @@ -19,10 +19,13 @@ #define pr_fmt(fmt) "ACPI: IORT: " fmt #include +#include #include #include #include +#include #include +#include struct iort_its_msi_chip { struct list_head list; @@ -30,6 +33,75 @@ struct iort_its_msi_chip { u32 translation_id; }; +struct iort_ops_node { + struct list_head list; + struct acpi_iort_node *node; + const struct iommu_ops *ops; + int (*iommu_xlate)(struct device *dev, u32 streamid, + struct acpi_iort_node *node); +}; +static LIST_HEAD(iort_iommu_ops); +static DEFINE_SPINLOCK(iort_ops_lock); + +/** + * iort_smmu_set_ops - Create iort_ops_node and use it to register + * iommu data in the iort_iommu_ops list. + * + * @node: IORT table node associated with the IOMMU + * @ops: IOMMU operations associated with the IORT node + * @iommu_xlate: iommu translate function to be used to carry out stream id + * translation + * + * Returns: 0 on success + * -ENOMEM on failure + */ +int iort_smmu_set_ops(struct acpi_iort_node *node, + const struct iommu_ops *ops, + int (*iommu_xlate)(struct device *dev, u32 streamid, + struct acpi_iort_node *node)) +{ + struct iort_ops_node *iommu = kzalloc(sizeof(*iommu), GFP_KERNEL); + + if (WARN_ON(!iommu)) + return -ENOMEM; + + INIT_LIST_HEAD(&iommu->list); + iommu->node = node; + iommu->ops = ops; + iommu->iommu_xlate = iommu_xlate; + + spin_lock(&iort_ops_lock); + list_add_tail(&iommu->list, &iort_iommu_ops); + spin_unlock(&iort_ops_lock); + + return 0; +} + +/** + * iort_smmu_get_ops_node - Retrieve iort_ops_node associated with an + * IORT node. + * + * @node: IORT table node to be looked-up + * + * Returns: iort_ops_node pointer on success + * NULL on failure +*/ +const struct iort_ops_node *iort_smmu_get_ops_node(struct acpi_iort_node *node) +{ + struct iort_ops_node *curr, *iommu_node = NULL; + + spin_lock(&iort_ops_lock); + list_for_each_entry(curr, &iort_iommu_ops, list) { + if (curr->node == node) { + iommu_node = curr; + break; + } + } + spin_unlock(&iort_ops_lock); + + return iommu_node; +} + typedef acpi_status (*iort_find_node_callback) (struct acpi_iort_node *node, void *context); diff --git a/include/linux/iort.h b/include/linux/iort.h index 6f2fec3..5053cc3 100644 --- a/include/linux/iort.h +++ b/include/linux/iort.h @@ -35,5 +35,10 @@ static inline u32 iort_pci_get_msi_rid(struct pci_dev *pdev, u32 req_id) static inline struct irq_domain * iort_pci_get_domain(struct pci_dev *pdev, u32 req_id) { return NULL; } #endif +int iort_smmu_set_ops(struct acpi_iort_node *node, + const struct iommu_ops *ops, + int (*iommu_xlate)(struct device *dev, + u32 streamid, + struct acpi_iort_node *node)); #endif /* __IORT_H__ */