From nobody Sun Feb 8 01:50:34 2026 Received: from mail-pf1-f172.google.com (mail-pf1-f172.google.com [209.85.210.172]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 64AD328D82D for ; Tue, 10 Jun 2025 10:46:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749552423; cv=none; b=RGgvXVtxlh7m1CcqbexkImK5VMcGMMz3h91jOyjl/J1K00yPO1RWPKsqwK6iIArLiy9UAqDlKQxizr/kAn0/1tUr1S1hMP/IiZrGN/pU05mzjZDd5ygWktwkB7ubArA136AMxTgjuKBXObZ99tRGpfwlfFgaakl65bBPM3XuNb8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749552423; c=relaxed/simple; bh=AbeUa7oMgcWWxhKR5HdiZpOtxTepX/NHaXq0Go8csdY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ZzfLwvYx+oP3vSI+zg54QoC0XLTYQmnLe2HXUgz4NwHg+20e2xmMQHa6O+gaFOTzNM30YAte6mmEkr2els1moy3PMYzKbJGYjdHHZn1+y3YwZ1finQw3vRR9iv+vA/GSJInA+UlwG+p1v38OavxC+Z+CFShgFw9NFHZ6+xDYSwc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ventanamicro.com; spf=pass smtp.mailfrom=ventanamicro.com; dkim=pass (2048-bit key) header.d=ventanamicro.com header.i=@ventanamicro.com header.b=FhstGigp; arc=none smtp.client-ip=209.85.210.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ventanamicro.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ventanamicro.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ventanamicro.com header.i=@ventanamicro.com header.b="FhstGigp" Received: by mail-pf1-f172.google.com with SMTP id d2e1a72fcca58-74801bc6dc5so3961128b3a.1 for ; Tue, 10 Jun 2025 03:46:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ventanamicro.com; s=google; t=1749552417; x=1750157217; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=UJadeZsf91vMZzGM1aZzFqytc9WcYBPIOZfEwjMnhPs=; b=FhstGigpyVcs2RkAkO10g1BMmfaArPkaVB7HUV1+DjtNsGJ6tdDvCyeZfhUlO0E+AO v1ppg87feUwlMLWoeKKAVLsqI5EPhyJGPw6WTTbi1Dg5Dy79AWGK/A4MHWioohPG19QY 8Ix/W+4plN2fnW8lD8PP1TY89w9uUTY63F5YkessbHnltwV6VTQ9bZmNNk7ZL+f/fCzZ ajAyuZN3tq9RDpzIiiYHStxpuzHbMeHC8RAmCmexASDqMYALMovDP7hQMM8Iv2QjG19G IW48uZoUeGQ5Lon7vda6oX1NGn6Wo51r8mIqkbN7qVIMKVnqolDjD+i7qURj+EMu279F eRag== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1749552417; x=1750157217; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=UJadeZsf91vMZzGM1aZzFqytc9WcYBPIOZfEwjMnhPs=; b=YfUFZtqJmeKSRtPuWweqvtnMx72AJZkbxy0PigJoUr92CZ4SdygiqNtrSxFYresORc RHBG6r/8NV667LT5Gp99J06NvG4vtr8XYFQ6hUYeWt5DokT8Qsw6SlXQmIpZLVE6D73D 8NPNnKgqDdbqhbjIAR735LJYtImRfXd8Y2VkPj8tHjtBOWZ5J603+pqWKQibTgN6fH+1 8vyrte3PG5cJcTIivI6vgIDEMYFxNsggjRe9kATL3M1celwmc4JZSdPWZWnx4OCdosQE u4vLEHWFVKFa4V52/+3AkGOeQzRMAFPeEZ77TU6+uQRtIqUf0DAelnvuYFQeWw96l8wa RWyg== X-Gm-Message-State: AOJu0YyzTSDpzU0JRmTkq3BvSZlKY3kvW5HKAYQiCxflCsLzM+xdZNAH h9ppFz814sZsdF8vNFHmIOFWVEWoW2nBvRPymEoHu10JJxfif59Vi4m23qWozMamG8EaHcQvmgo 8ymeCtrM= X-Gm-Gg: ASbGncu+3weKNbcy8lmUkqcmnURgtfJlazVlZAzIQc+whzMapRamx4SdKzhGww7GuQC jk3HfKqN+VOhgSQYiPnUHRIJWoaM/H8vBGkyQhmanQGbNNwc8WYj41sqjWurHJY0PDdeQ7wl2/6 FBAM3eb8K4sOZf6BqZCERh7KMzo45vc+9PBM6knY8kd6w32A7puZeCVh/ZxjF+cFc0jqaquqgf8 ly11XXY2RnZOZ+5l/38ZIk7XyHwCx4+t3HmKLuoZho94YPwWgjA42MUuU6ntvMViYMjCSPdv4bK 7p1PkuzU7WjM5gsbZoVKHnw3QYPqJARZpcHDXt/TEEpyij6PZ29WS5tPEyPvGINHWy4Ln6Wb X-Google-Smtp-Source: AGHT+IETvDNywdOafWDEP4hN5G1n2p50ILLYrsZVTynCDylV47c9oRWac3LLkA3rE5vdN9xdcrH6zQ== X-Received: by 2002:a05:6a00:3a1b:b0:742:aed4:3e1 with SMTP id d2e1a72fcca58-7485ea28acfmr3458654b3a.2.1749552417314; Tue, 10 Jun 2025 03:46:57 -0700 (PDT) Received: from sunil-pc.Dlink ([106.51.196.253]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-7482b0842c0sm7152448b3a.73.2025.06.10.03.46.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 10 Jun 2025 03:46:56 -0700 (PDT) From: Sunil V L To: linux-kernel@vger.kernel.org, linux-riscv@lists.infradead.org, linux-acpi@vger.kernel.org, iommu@lists.linux.dev Cc: Paul Walmsley , Palmer Dabbelt , Alexandre Ghiti , "Rafael J . Wysocki" , Len Brown , Tomasz Jeznach , Joerg Roedel , Will Deacon , Robin Murphy , Atish Kumar Patra , Anup Patel , Andrew Jones , Sunil V L , Anup Patel Subject: [PATCH v2 1/3] ACPI: RISC-V: Add support for RIMT Date: Tue, 10 Jun 2025 16:16:39 +0530 Message-ID: <20250610104641.700940-2-sunilvl@ventanamicro.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250610104641.700940-1-sunilvl@ventanamicro.com> References: <20250610104641.700940-1-sunilvl@ventanamicro.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" RISC-V IO Mapping Table (RIMT) is a static ACPI table to communicate IOMMU information to the OS. The spec is available at [1]. The changes at high level are, a) Initialize data structures required for IOMMU/device configuration using the data from RIMT. Provide APIs required for device configuration. b) Provide an API for IOMMU drivers to register the fwnode with RIMT data structures. This API will create a fwnode for PCIe IOMMU. [1] - https://github.com/riscv-non-isa/riscv-acpi-rimt Signed-off-by: Sunil V L Link: https://lore.kernel.org/r/20250514055723.1328557-3-sunilvl@ventanamic= ro.com Signed-off-by: Anup Patel --- MAINTAINERS | 1 + arch/riscv/Kconfig | 1 + drivers/acpi/Kconfig | 4 + drivers/acpi/riscv/Kconfig | 7 + drivers/acpi/riscv/Makefile | 1 + drivers/acpi/riscv/init.c | 2 + drivers/acpi/riscv/init.h | 1 + drivers/acpi/riscv/rimt.c | 523 ++++++++++++++++++++++++++++++++++++ include/linux/acpi_rimt.h | 26 ++ 9 files changed, 566 insertions(+) create mode 100644 drivers/acpi/riscv/Kconfig create mode 100644 drivers/acpi/riscv/rimt.c create mode 100644 include/linux/acpi_rimt.h diff --git a/MAINTAINERS b/MAINTAINERS index a92290fffa16..9d36ad744af5 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -345,6 +345,7 @@ L: linux-acpi@vger.kernel.org L: linux-riscv@lists.infradead.org S: Maintained F: drivers/acpi/riscv/ +F: include/linux/acpi_rimt.h =20 ACPI PCC(Platform Communication Channel) MAILBOX DRIVER M: Sudeep Holla diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index 36061f4732b7..96d64e0a7b97 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -16,6 +16,7 @@ config RISCV select ACPI_MCFG if (ACPI && PCI) select ACPI_PPTT if ACPI select ACPI_REDUCED_HARDWARE_ONLY if ACPI + select ACPI_RIMT if ACPI select ACPI_SPCR_TABLE if ACPI select ARCH_DMA_DEFAULT_COHERENT select ARCH_ENABLE_HUGEPAGE_MIGRATION if HUGETLB_PAGE && MIGRATION diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index 7bc40c2735ac..4381803c308c 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig @@ -546,6 +546,10 @@ if ARM64 source "drivers/acpi/arm64/Kconfig" endif =20 +if RISCV +source "drivers/acpi/riscv/Kconfig" +endif + config ACPI_PPTT bool =20 diff --git a/drivers/acpi/riscv/Kconfig b/drivers/acpi/riscv/Kconfig new file mode 100644 index 000000000000..046296a18d00 --- /dev/null +++ b/drivers/acpi/riscv/Kconfig @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: GPL-2.0-only +# +# ACPI Configuration for RISC-V +# + +config ACPI_RIMT + bool diff --git a/drivers/acpi/riscv/Makefile b/drivers/acpi/riscv/Makefile index a96fdf1e2cb8..1284a076fa88 100644 --- a/drivers/acpi/riscv/Makefile +++ b/drivers/acpi/riscv/Makefile @@ -2,3 +2,4 @@ obj-y +=3D rhct.o init.o irq.o obj-$(CONFIG_ACPI_PROCESSOR_IDLE) +=3D cpuidle.o obj-$(CONFIG_ACPI_CPPC_LIB) +=3D cppc.o +obj-$(CONFIG_ACPI_RIMT) +=3D rimt.o diff --git a/drivers/acpi/riscv/init.c b/drivers/acpi/riscv/init.c index 673e4d5dd752..7c00f7995e86 100644 --- a/drivers/acpi/riscv/init.c +++ b/drivers/acpi/riscv/init.c @@ -10,4 +10,6 @@ void __init acpi_arch_init(void) { riscv_acpi_init_gsi_mapping(); + if (IS_ENABLED(CONFIG_ACPI_RIMT)) + riscv_acpi_rimt_init(); } diff --git a/drivers/acpi/riscv/init.h b/drivers/acpi/riscv/init.h index 0b9a07e4031f..1680aa2aaf23 100644 --- a/drivers/acpi/riscv/init.h +++ b/drivers/acpi/riscv/init.h @@ -2,3 +2,4 @@ #include =20 void __init riscv_acpi_init_gsi_mapping(void); +void __init riscv_acpi_rimt_init(void); diff --git a/drivers/acpi/riscv/rimt.c b/drivers/acpi/riscv/rimt.c new file mode 100644 index 000000000000..8cb6f5cf39e2 --- /dev/null +++ b/drivers/acpi/riscv/rimt.c @@ -0,0 +1,523 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2024-2025, Ventana Micro Systems Inc + * Author: Sunil V L + * + */ + +#include +#include +#include +#include +#include +#include +#include "init.h" + +struct rimt_fwnode { + struct list_head list; + struct acpi_rimt_node *rimt_node; + struct fwnode_handle *fwnode; +}; + +static LIST_HEAD(rimt_fwnode_list); +static DEFINE_SPINLOCK(rimt_fwnode_lock); + +#define RIMT_TYPE_MASK(type) (1 << (type)) +#define RIMT_IOMMU_TYPE BIT(0) + +/* Root pointer to the mapped RIMT table */ +static struct acpi_table_header *rimt_table; + +/** + * rimt_set_fwnode() - Create rimt_fwnode and use it to register + * iommu data in the rimt_fwnode_list + * + * @rimt_node: RIMT table node associated with the IOMMU + * @fwnode: fwnode associated with the RIMT node + * + * Returns: 0 on success + * <0 on failure + */ +static inline int rimt_set_fwnode(struct acpi_rimt_node *rimt_node, + struct fwnode_handle *fwnode) +{ + struct rimt_fwnode *np; + + np =3D kzalloc(sizeof(*np), GFP_ATOMIC); + + if (WARN_ON(!np)) + return -ENOMEM; + + INIT_LIST_HEAD(&np->list); + np->rimt_node =3D rimt_node; + np->fwnode =3D fwnode; + + spin_lock(&rimt_fwnode_lock); + list_add_tail(&np->list, &rimt_fwnode_list); + spin_unlock(&rimt_fwnode_lock); + + return 0; +} + +/** + * rimt_get_fwnode() - Retrieve fwnode associated with an RIMT node + * + * @node: RIMT table node to be looked-up + * + * Returns: fwnode_handle pointer on success, NULL on failure + */ +static inline struct fwnode_handle *rimt_get_fwnode(struct acpi_rimt_node = *node) +{ + struct rimt_fwnode *curr; + struct fwnode_handle *fwnode =3D NULL; + + spin_lock(&rimt_fwnode_lock); + list_for_each_entry(curr, &rimt_fwnode_list, list) { + if (curr->rimt_node =3D=3D node) { + fwnode =3D curr->fwnode; + break; + } + } + spin_unlock(&rimt_fwnode_lock); + + return fwnode; +} + +static acpi_status rimt_match_node_callback(struct acpi_rimt_node *node, + void *context) +{ + struct device *dev =3D context; + acpi_status status =3D AE_NOT_FOUND; + + if (node->type =3D=3D ACPI_RIMT_NODE_TYPE_IOMMU) { + struct acpi_rimt_iommu *iommu_node =3D (struct acpi_rimt_iommu *)&node->= node_data; + + if (dev_is_pci(dev)) { + struct pci_dev *pdev; + u16 bdf; + + pdev =3D to_pci_dev(dev); + bdf =3D PCI_DEVID(pdev->bus->number, pdev->devfn); + if ((pci_domain_nr(pdev->bus) =3D=3D iommu_node->pcie_segment_number) && + bdf =3D=3D iommu_node->pcie_bdf) { + status =3D AE_OK; + } else { + status =3D AE_NOT_FOUND; + } + } else { + struct platform_device *pdev =3D to_platform_device(dev); + struct resource *res; + + res =3D platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (res && res->start =3D=3D iommu_node->base_address) + status =3D AE_OK; + else + status =3D AE_NOT_FOUND; + } + } else if (node->type =3D=3D ACPI_RIMT_NODE_TYPE_PCIE_ROOT_COMPLEX) { + struct acpi_rimt_pcie_rc *pci_rc; + struct pci_bus *bus; + + bus =3D to_pci_bus(dev); + pci_rc =3D (struct acpi_rimt_pcie_rc *)node->node_data; + + /* + * It is assumed that PCI segment numbers maps one-to-one + * with root complexes. Each segment number can represent only + * one root complex. + */ + status =3D pci_rc->pcie_segment_number =3D=3D pci_domain_nr(bus) ? + AE_OK : AE_NOT_FOUND; + } else if (node->type =3D=3D ACPI_RIMT_NODE_TYPE_PLAT_DEVICE) { + struct acpi_buffer buf =3D { ACPI_ALLOCATE_BUFFER, NULL }; + struct acpi_device *adev; + struct acpi_rimt_platform_device *ncomp; + struct device *plat_dev =3D dev; + + /* + * Walk the device tree to find a device with an + * ACPI companion; there is no point in scanning + * RIMT for a device matching a platform device if + * the device does not have an ACPI companion to + * start with. + */ + do { + adev =3D ACPI_COMPANION(plat_dev); + if (adev) + break; + + plat_dev =3D plat_dev->parent; + } while (plat_dev); + + if (!adev) + return status; + + status =3D acpi_get_name(adev->handle, ACPI_FULL_PATHNAME, &buf); + if (ACPI_FAILURE(status)) { + dev_warn(plat_dev, "Can't get device full path name\n"); + return status; + } + + ncomp =3D (struct acpi_rimt_platform_device *)node->node_data; + status =3D !strcmp(ncomp->device_name, buf.pointer) ? + AE_OK : AE_NOT_FOUND; + acpi_os_free(buf.pointer); + } + + return status; +} + +static struct acpi_rimt_node *rimt_scan_node(enum acpi_rimt_node_type type, + void *context) +{ + struct acpi_rimt_node *rimt_node, *rimt_end; + struct acpi_table_rimt *rimt; + int i; + + if (!rimt_table) + return NULL; + + /* Get the first RIMT node */ + rimt =3D (struct acpi_table_rimt *)rimt_table; + rimt_node =3D ACPI_ADD_PTR(struct acpi_rimt_node, rimt, + rimt->node_offset); + rimt_end =3D ACPI_ADD_PTR(struct acpi_rimt_node, rimt_table, + rimt_table->length); + + for (i =3D 0; i < rimt->num_nodes; i++) { + if (WARN_TAINT(rimt_node >=3D rimt_end, TAINT_FIRMWARE_WORKAROUND, + "RIMT node pointer overflows, bad table!\n")) + return NULL; + + if (rimt_node->type =3D=3D type && + ACPI_SUCCESS(rimt_match_node_callback(rimt_node, context))) + return rimt_node; + + rimt_node =3D ACPI_ADD_PTR(struct acpi_rimt_node, rimt_node, + rimt_node->length); + } + + return NULL; +} + +static bool rimt_pcie_rc_supports_ats(struct acpi_rimt_node *node) +{ + struct acpi_rimt_pcie_rc *pci_rc; + + pci_rc =3D (struct acpi_rimt_pcie_rc *)node->node_data; + return pci_rc->flags & ACPI_RIMT_PCIE_ATS_SUPPORTED; +} + +static int rimt_iommu_xlate(struct device *dev, struct acpi_rimt_node *nod= e, u32 deviceid) +{ + struct fwnode_handle *rimt_fwnode; + + if (!node) + return -ENODEV; + + rimt_fwnode =3D rimt_get_fwnode(node); + + /* + * The IOMMU drivers may not be probed yet. + * Defer the IOMMU configuration + */ + if (!rimt_fwnode) + return -EPROBE_DEFER; + + return acpi_iommu_fwspec_init(dev, deviceid, rimt_fwnode); +} + +struct rimt_pci_alias_info { + struct device *dev; + struct acpi_rimt_node *node; + const struct iommu_ops *ops; +}; + +static int rimt_id_map(struct acpi_rimt_id_mapping *map, u8 type, u32 rid_= in, u32 *rid_out) +{ + if (rid_in < map->source_id_base || + (rid_in > map->source_id_base + map->num_ids)) + return -ENXIO; + + *rid_out =3D map->dest_id_base + (rid_in - map->source_id_base); + return 0; +} + +static struct acpi_rimt_node *rimt_node_get_id(struct acpi_rimt_node *node, + u32 *id_out, int index) +{ + struct acpi_rimt_platform_device *plat_node; + struct acpi_rimt_pcie_rc *pci_node; + u32 id_mapping_offset, num_id_mapping; + struct acpi_rimt_id_mapping *map; + struct acpi_rimt_node *parent; + + if (node->type =3D=3D ACPI_RIMT_NODE_TYPE_PCIE_ROOT_COMPLEX) { + pci_node =3D (struct acpi_rimt_pcie_rc *)&node->node_data; + id_mapping_offset =3D pci_node->id_mapping_offset; + num_id_mapping =3D pci_node->num_id_mappings; + } else if (node->type =3D=3D ACPI_RIMT_NODE_TYPE_PLAT_DEVICE) { + plat_node =3D (struct acpi_rimt_platform_device *)&node->node_data; + id_mapping_offset =3D plat_node->id_mapping_offset; + num_id_mapping =3D plat_node->num_id_mappings; + } else { + return NULL; + } + + if (!id_mapping_offset || !num_id_mapping || index >=3D num_id_mapping) + return NULL; + + map =3D ACPI_ADD_PTR(struct acpi_rimt_id_mapping, node, + id_mapping_offset + index * sizeof(*map)); + + /* Firmware bug! */ + if (!map->dest_offset) { + pr_err(FW_BUG "[node %p type %d] ID map has NULL parent reference\n", + node, node->type); + return NULL; + } + + parent =3D ACPI_ADD_PTR(struct acpi_rimt_node, rimt_table, map->dest_offs= et); + + if (node->type =3D=3D ACPI_RIMT_NODE_TYPE_PLAT_DEVICE || + node->type =3D=3D ACPI_RIMT_NODE_TYPE_PCIE_ROOT_COMPLEX) { + *id_out =3D map->dest_offset; + return parent; + } + + return NULL; +} + +static struct acpi_rimt_node *rimt_node_map_id(struct acpi_rimt_node *node, + u32 id_in, u32 *id_out, + u8 type_mask) +{ + struct acpi_rimt_pcie_rc *pci_node; + struct acpi_rimt_platform_device *plat_node; + u32 id =3D id_in; + u32 id_mapping_offset, num_id_mapping; + + /* Parse the ID mapping tree to find specified node type */ + while (node) { + struct acpi_rimt_id_mapping *map; + int i, rc =3D 0; + u32 map_id =3D id; + + if (RIMT_TYPE_MASK(node->type) & type_mask) { + if (id_out) + *id_out =3D id; + return node; + } + + if (node->type =3D=3D ACPI_RIMT_NODE_TYPE_PCIE_ROOT_COMPLEX) { + pci_node =3D (struct acpi_rimt_pcie_rc *)&node->node_data; + id_mapping_offset =3D pci_node->id_mapping_offset; + num_id_mapping =3D pci_node->num_id_mappings; + } else if (node->type =3D=3D ACPI_RIMT_NODE_TYPE_PLAT_DEVICE) { + plat_node =3D (struct acpi_rimt_platform_device *)&node->node_data; + id_mapping_offset =3D plat_node->id_mapping_offset; + num_id_mapping =3D plat_node->num_id_mappings; + } else { + goto fail_map; + } + + if (!id_mapping_offset || !num_id_mapping) + goto fail_map; + + map =3D ACPI_ADD_PTR(struct acpi_rimt_id_mapping, node, + id_mapping_offset); + + /* Firmware bug! */ + if (!map->dest_offset) { + pr_err(FW_BUG "[node %p type %d] ID map has NULL parent reference\n", + node, node->type); + goto fail_map; + } + + /* Do the ID translation */ + for (i =3D 0; i < num_id_mapping; i++, map++) { + rc =3D rimt_id_map(map, node->type, map_id, &id); + if (!rc) + break; + } + + if (i =3D=3D num_id_mapping) + goto fail_map; + + node =3D ACPI_ADD_PTR(struct acpi_rimt_node, rimt_table, + rc ? 0 : map->dest_offset); + } + +fail_map: + /* Map input ID to output ID unchanged on mapping failure */ + if (id_out) + *id_out =3D id_in; + + return NULL; +} + +static struct acpi_rimt_node *rimt_node_map_platform_id(struct acpi_rimt_n= ode *node, u32 *id_out, + u8 type_mask, int index) +{ + struct acpi_rimt_node *parent; + u32 id; + + parent =3D rimt_node_get_id(node, &id, index); + if (!parent) + return NULL; + + if (!(RIMT_TYPE_MASK(parent->type) & type_mask)) + parent =3D rimt_node_map_id(parent, id, id_out, type_mask); + else + if (id_out) + *id_out =3D id; + + return parent; +} + +static int rimt_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data) +{ + struct rimt_pci_alias_info *info =3D data; + struct acpi_rimt_node *parent; + u32 deviceid; + + parent =3D rimt_node_map_id(info->node, alias, &deviceid, RIMT_IOMMU_TYPE= ); + return rimt_iommu_xlate(info->dev, parent, deviceid); +} + +/* + * RISC-V supports IOMMU as a PCI device or a platform device. + * When it is a platform device, there should be a namespace device as + * well along with RIMT. To create the link between RIMT information and + * the platform device, the IOMMU driver should register itself with the + * RIMT module. This is true for PCI based IOMMU as well. + */ +int rimt_iommu_register(struct device *dev) +{ + struct fwnode_handle *rimt_fwnode; + struct acpi_rimt_node *node; + + node =3D rimt_scan_node(ACPI_RIMT_NODE_TYPE_IOMMU, dev); + if (!node) { + pr_err("Could not find IOMMU node in RIMT\n"); + return -ENODEV; + } + + if (dev_is_pci(dev)) { + rimt_fwnode =3D acpi_alloc_fwnode_static(); + if (!rimt_fwnode) + return -ENOMEM; + + rimt_fwnode->dev =3D dev; + if (!dev->fwnode) + dev->fwnode =3D rimt_fwnode; + + rimt_set_fwnode(node, rimt_fwnode); + } else { + rimt_set_fwnode(node, dev->fwnode); + } + + return 0; +} + +#ifdef CONFIG_IOMMU_API + +static int rimt_plat_iommu_map(struct device *dev, struct acpi_rimt_node *= node) +{ + struct acpi_rimt_node *parent; + int err =3D -ENODEV, i =3D 0; + u32 deviceid =3D 0; + + do { + parent =3D rimt_node_map_platform_id(node, &deviceid, + RIMT_IOMMU_TYPE, + i++); + + if (parent) + err =3D rimt_iommu_xlate(dev, parent, deviceid); + } while (parent && !err); + + return err; +} + +static int rimt_plat_iommu_map_id(struct device *dev, + struct acpi_rimt_node *node, + const u32 *in_id) +{ + struct acpi_rimt_node *parent; + u32 deviceid; + + parent =3D rimt_node_map_id(node, *in_id, &deviceid, RIMT_IOMMU_TYPE); + if (parent) + return rimt_iommu_xlate(dev, parent, deviceid); + + return -ENODEV; +} + +/** + * rimt_iommu_configure_id - Set-up IOMMU configuration for a device. + * + * @dev: device to configure + * @id_in: optional input id const value pointer + * + * Returns: 0 on success, <0 on failure + */ +int rimt_iommu_configure_id(struct device *dev, const u32 *id_in) +{ + struct acpi_rimt_node *node; + int err =3D -ENODEV; + + if (dev_is_pci(dev)) { + struct iommu_fwspec *fwspec; + struct pci_bus *bus =3D to_pci_dev(dev)->bus; + struct rimt_pci_alias_info info =3D { .dev =3D dev }; + + node =3D rimt_scan_node(ACPI_RIMT_NODE_TYPE_PCIE_ROOT_COMPLEX, &bus->dev= ); + if (!node) + return -ENODEV; + + info.node =3D node; + err =3D pci_for_each_dma_alias(to_pci_dev(dev), + rimt_pci_iommu_init, &info); + + fwspec =3D dev_iommu_fwspec_get(dev); + if (fwspec && rimt_pcie_rc_supports_ats(node)) + fwspec->flags |=3D IOMMU_FWSPEC_PCI_RC_ATS; + } else { + node =3D rimt_scan_node(ACPI_RIMT_NODE_TYPE_PLAT_DEVICE, dev); + if (!node) + return -ENODEV; + + err =3D id_in ? rimt_plat_iommu_map_id(dev, node, id_in) : + rimt_plat_iommu_map(dev, node); + } + + return err; +} + +#else +int rimt_iommu_configure_id(struct device *dev, const u32 *id_in) +{ + return -ENODEV; +} +#endif + +void __init riscv_acpi_rimt_init(void) +{ + acpi_status status; + + /* rimt_table will be used at runtime after the rimt init, + * so we don't need to call acpi_put_table() to release + * the RIMT table mapping. + */ + status =3D acpi_get_table(ACPI_SIG_RIMT, 0, &rimt_table); + if (ACPI_FAILURE(status)) { + if (status !=3D AE_NOT_FOUND) { + const char *msg =3D acpi_format_exception(status); + + pr_err("Failed to get table, %s\n", msg); + } + + return; + } +} diff --git a/include/linux/acpi_rimt.h b/include/linux/acpi_rimt.h new file mode 100644 index 000000000000..ce4d136d4f81 --- /dev/null +++ b/include/linux/acpi_rimt.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2024-2025, Ventana Micro Systems Inc. + * Author: Sunil V L + */ + +#ifndef _ACPI_RIMT_H +#define _ACPI_RIMT_H + +#ifdef CONFIG_ACPI_RIMT +int rimt_iommu_configure_id(struct device *dev, const u32 *id_in); + +int rimt_iommu_register(struct device *dev); +#else +static inline int rimt_iommu_register(struct device *dev) +{ + return -ENODEV; +} + +static inline int rimt_iommu_configure_id(struct device *dev, const u32 *i= d_in) +{ + return -ENODEV; +} +#endif + +#endif /* _ACPI_RIMT_H */ --=20 2.43.0 From nobody Sun Feb 8 01:50:34 2026 Received: from mail-pf1-f171.google.com (mail-pf1-f171.google.com [209.85.210.171]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CB4AA28D824 for ; Tue, 10 Jun 2025 10:47:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.171 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749552425; cv=none; b=Y5f7vJYjiokcACZ/Rt0fn8Ay0vcJi0oC7fTcWQ1e92ioaUrT8g+v7Kvudw36hz3ZacAJPWF+4r9vud0I9HcYFqvclV4iJ0ffmZSF0TXTGFwGIS3sZSJSW5LgUt0YBuLG6fAbWBWJDPkKWGEfqHjkZke8eq0kvryTdz2RbuFV4tg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749552425; c=relaxed/simple; bh=h73ucvaKC7tusoZ366WFdpRJo5bbH+f6qpcdSe3pUX4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=MH58AjPtYbomfygA2Pj3kQvMncpnTfeYtqNwAXUqZOPOyOYHLeXDdrIAvaIfM+UhB4rw7egqv0Lfey9OwY/P3ne3KPcAqNQlY5SIr+Kc5zIdIl8xttewSjzz2dSPApbKRlmFhbhB/Z/Yjk3pBzFosgXvXcssipkIBoHJ+msbjzw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ventanamicro.com; spf=pass smtp.mailfrom=ventanamicro.com; dkim=pass (2048-bit key) header.d=ventanamicro.com header.i=@ventanamicro.com header.b=CDEvh3u9; arc=none smtp.client-ip=209.85.210.171 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ventanamicro.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ventanamicro.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ventanamicro.com header.i=@ventanamicro.com header.b="CDEvh3u9" Received: by mail-pf1-f171.google.com with SMTP id d2e1a72fcca58-74801bc6dc5so3961198b3a.1 for ; Tue, 10 Jun 2025 03:47:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ventanamicro.com; s=google; t=1749552422; x=1750157222; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=lOPKLQETC23awiI7CT9ZOjIxOZ+G4ZqvM0do3bqdxho=; b=CDEvh3u9CedjMhCO1N5s+MLcrQ09c8rpZxd9Gk43i32PSsQ+Ja6F3UqxMVQIPNAQol TkEtoMvs4nBTmOJupoMLyJBv+dfbmDuHZmemfajDr5TY6cbmmwF12SwzeRDmksaGDsvw ffCzywMcOC2njLYdREXdk8ZwYm6Ldd5Gocbx2fN8ztuBKrelHE+xbdWQoyuUbIEolpWD QLZJAdD3wLZyKPKeGGdRP2u7N6gYx42W3UEqQDe+pdfnWDOKJgOvBpTV+z1G4kNkPH4k ZMJYBC5NpNuIvkOXNitPLUMblLUH3CCmzu11bRSOTdIf5shw/yjpLquYZkqnobkeWrdH MnTw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1749552422; x=1750157222; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=lOPKLQETC23awiI7CT9ZOjIxOZ+G4ZqvM0do3bqdxho=; b=Y+8MW1aSEkwqMDPuLhSLDBEsicOMaREVh3B67JBJiVxyrOckv44eqsHB8Bn1pnuQUh TVFwhd7mJWPBd7h6foJQ3vfgpmkkr4V0AOMw6zPAFQXgMWbIV7nglhutWyIlbla1QUv8 UGdRCokwK8NdQDHeZhUCojVDRKC36DhA/7XovPbjX0cT4bBV++BBWuSalWkoCvNEOzXV F9EdyYgQxQeiCR+mngv8yux9OBh4IgYEXytLB9K/5+xu/nqCmVE9jEr+tHfzdGbPmueG YxKUXeocjwLihtxYVn8rfNUhGnBMNzH7TX9uftYqEbOd+pXQ8+kd2Kvm4oClaOkaLici NXOA== X-Gm-Message-State: AOJu0Yyd4NRRiyHd8sseC7Aq668/XQdyXzmV2JMxUMdijcu3n5MdEBCh LCZnbofJR1Bhge0f7QZoRg++Z7Mz+m2L5WP6wSoUf4BKy9NDqoxxtQPF8QU340MpeHLIVwCZ0t7 SciGtYyw= X-Gm-Gg: ASbGncuqsaiJvhKemX7TPoIRck4VN/AGWL6Gx3jDVq+BMtftbIKOJ/XfxgYg+dsB/ru sZbRBtDw956kiCGYll7kg1kWp16Ei/9Yaa62ruCqfVBfHOqi7iRaz+c+rWHwgzIAJIfVteFzpMc IzlKm/FIPAiIskzdNyEaY7trMyMt8I7RsdG4pdt8anB/VUXs1dTKwzlx+Wsb/+LCsGk98fi56Qt 6v18VrRELBFkg8K6fxikFpmtHZD/i6At/N2Nr6EUSmo9FSs+w1qhlmZCJJ6yPyywuD8FKsaEjoY onVr3dTAQVtM72Fd2Hv2WGKcVowuqi5rmrZMasCJ4An/7qguSXfIVbpdJZplelsfbcXbQKH0 X-Google-Smtp-Source: AGHT+IEY8u8v01mFisc/TL0W6gCvBjvkLcKdurAn91xGLMr57xfYjH/zVaAAA3K7rATTcPpWb32wlw== X-Received: by 2002:a05:6a00:9292:b0:746:2ae9:fc49 with SMTP id d2e1a72fcca58-7485ea78f73mr3883622b3a.9.1749552422541; Tue, 10 Jun 2025 03:47:02 -0700 (PDT) Received: from sunil-pc.Dlink ([106.51.196.253]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-7482b0842c0sm7152448b3a.73.2025.06.10.03.46.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 10 Jun 2025 03:47:02 -0700 (PDT) From: Sunil V L To: linux-kernel@vger.kernel.org, linux-riscv@lists.infradead.org, linux-acpi@vger.kernel.org, iommu@lists.linux.dev Cc: Paul Walmsley , Palmer Dabbelt , Alexandre Ghiti , "Rafael J . Wysocki" , Len Brown , Tomasz Jeznach , Joerg Roedel , Will Deacon , Robin Murphy , Atish Kumar Patra , Anup Patel , Andrew Jones , Sunil V L , Anup Patel , "Rafael J . Wysocki" Subject: [PATCH v2 2/3] ACPI: scan: Add support for RISC-V in acpi_iommu_configure_id() Date: Tue, 10 Jun 2025 16:16:40 +0530 Message-ID: <20250610104641.700940-3-sunilvl@ventanamicro.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250610104641.700940-1-sunilvl@ventanamicro.com> References: <20250610104641.700940-1-sunilvl@ventanamicro.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" acpi_iommu_configure_id() currently supports only IORT (ARM) and VIOT. Add support for RISC-V as well. Signed-off-by: Sunil V L Link: https://lore.kernel.org/r/20250514055723.1328557-4-sunilvl@ventanamic= ro.com Signed-off-by: Anup Patel Acked-by: Rafael J. Wysocki --- drivers/acpi/scan.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index fb1fe9f3b1a3..70f57d58fd61 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -1628,8 +1629,12 @@ static int acpi_iommu_configure_id(struct device *de= v, const u32 *id_in) } =20 err =3D iort_iommu_configure_id(dev, id_in); - if (err && err !=3D -EPROBE_DEFER) - err =3D viot_iommu_configure(dev); + if (err && err !=3D -EPROBE_DEFER) { + err =3D rimt_iommu_configure_id(dev, id_in); + if (err && err !=3D -EPROBE_DEFER) + err =3D viot_iommu_configure(dev); + } + mutex_unlock(&iommu_probe_device_lock); =20 return err; --=20 2.43.0 From nobody Sun Feb 8 01:50:34 2026 Received: from mail-pf1-f169.google.com (mail-pf1-f169.google.com [209.85.210.169]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2BADC28E56D for ; Tue, 10 Jun 2025 10:47:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.169 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749552430; cv=none; b=qkNq1r7570NpQ907HEd6CC/JGwzxsXR1uE+pkEf8XxnL1i01ASLog5O2jxwxvdXalMsv2OI3Y4I2daE+cC7Z7RdqqRQ+g/jVaSgoSnM1vKZEpM+vqGWLR/lKFApwIBtttq4zUpqK6ociUc1Uknzk/GxnWLGRZ2OPn12rccNvB6k= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749552430; c=relaxed/simple; bh=ApG+TqazgePfngwgF8UcC0MB1PI19Gz6v9CqRzVQNfU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=W0/kWgqN3LAjYLFOMA1PTjn6/C4fmQ9m0P+4WNLYR1A3LMGxXCyn9Rga6kTYrf/tIBbLlUMT2scP73VgUz2EqlW5gAMUypY1pfbjUpYoe/+fraT76g1xZnUFC3XrQ/elj4eu2ZFl5d2AIbAMA1fmWKV5HR4LbECbJqwDaSKthlg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ventanamicro.com; spf=pass smtp.mailfrom=ventanamicro.com; dkim=pass (2048-bit key) header.d=ventanamicro.com header.i=@ventanamicro.com header.b=VzVtmgQ1; arc=none smtp.client-ip=209.85.210.169 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ventanamicro.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ventanamicro.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ventanamicro.com header.i=@ventanamicro.com header.b="VzVtmgQ1" Received: by mail-pf1-f169.google.com with SMTP id d2e1a72fcca58-742af84818cso3673308b3a.1 for ; Tue, 10 Jun 2025 03:47:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ventanamicro.com; s=google; t=1749552428; x=1750157228; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=FP3kf43rac5NeyS0tfBg63Ga8H9gH2daKAu3CycI9m8=; b=VzVtmgQ1M8qpWjZBfCGO7762Bjdg2buOTsVqTqNs95gFn5EtFSTlywkN3lz5zbhHpc 3lXMT4HiAGvGVZVqTXUQKj5qIwK5hxmfhZVF/dAQ1jUrwXSps2K3NSWZ49B8/psOGwXJ vCmJcP4mf10mmG1gQI6PkJGKmrFndkHKU8YK3eTm0rnM3XBX4xlyNsvCcJvIBA9sW8tN YucCtORk83BfcGr+F0vPwfFTsdN/CAOzrIJzbW//ITY5AiRqQUSGD1iWidyyNIZeCxwu JLhtVrVDu4+UMHuqoKpb4EuOTUGQ5xOgFuVAmGOCpkgi/S/plVngxN4JGl063BQ8nu87 7XoQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1749552428; x=1750157228; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=FP3kf43rac5NeyS0tfBg63Ga8H9gH2daKAu3CycI9m8=; b=Hh1jrCw1xuqEzZmINdkgcASDSs8liQ4oP6GAokDF2Oj/TdnCaid9QBE4mlP92kRwjB Vl/kiHSPIov4vr9GhwG7pulXVl6bXXltE/YroRNERNoOITueJPeobSaxfEZQ+Qv0xx3/ j6tew4s2PBfaa/uaCstwb6kXp2wca9HzvmeP0dpZqNCAYEP87wKK911QBcl7nNrBvTwc Y0QtnM5DxB4MuGkYxFpk1dCIjWV6q6dW0oyVj7HPZLb27Hu2CT56nffkrsEn0drnXSwW rjeDKbXohKRokeqyyoDyAhWcEiiIVC8Ucss1RxjfgkCvs5i4onvhcFWLLN14LPIjpqUA uGEw== X-Gm-Message-State: AOJu0Yxh4S/lJfmKd7X+bW6GOm6BAwQ1IsMProhRJO5HKB0E56IJOMkr qGCgovJUNqTMaSsaYagcNu0kS/ymPvRYIX3rCOwAMKJ6adhBem7KHDgfb3L0yLoab8C3gZvCekv J3s9SJzs= X-Gm-Gg: ASbGncvFqQHLIcz4yQTgm7Erf5gkon23G6kUFubVei1KyajlYl971uVi6r+vqsebwEk iJL1D7I/stuv1TG8M/QGBUtQG8Q5WCzeoEBNySkzcIrRGMvC3nOZ+bX2kGMq0P44qXzo12OmdoM FY/8aEMqzaJOOZfNOZEu07qwQZZ8ifGhSKUyaX0d02WDA+nvvpXXbSChsN+5Gg9y7k9A1r6BHjx Dczn1ozlpdxY+zRIrpifgYTpOvV0sHTG+i554c98RCCGBZ3PaNko9T6X7ZQ2H4YhmxAquEJM8xa S6UPEH+WiaAqL6sYgL8vxCOMixFhLqSNBdK/pJHr64+Cd0s5AfdIvSf2LXqn1Bbdu3uT0JQB X-Google-Smtp-Source: AGHT+IHO3whMIsadT1gQS1uvXLzDhfAzklgArmoSaPyZ84SGmfZlfdnm+MiFoYtdG6mfvNnmI8Mwbw== X-Received: by 2002:a05:6a00:194d:b0:740:b394:3ebd with SMTP id d2e1a72fcca58-74827e7faa7mr22225344b3a.7.1749552427592; Tue, 10 Jun 2025 03:47:07 -0700 (PDT) Received: from sunil-pc.Dlink ([106.51.196.253]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-7482b0842c0sm7152448b3a.73.2025.06.10.03.47.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 10 Jun 2025 03:47:07 -0700 (PDT) From: Sunil V L To: linux-kernel@vger.kernel.org, linux-riscv@lists.infradead.org, linux-acpi@vger.kernel.org, iommu@lists.linux.dev Cc: Paul Walmsley , Palmer Dabbelt , Alexandre Ghiti , "Rafael J . Wysocki" , Len Brown , Tomasz Jeznach , Joerg Roedel , Will Deacon , Robin Murphy , Atish Kumar Patra , Anup Patel , Andrew Jones , Sunil V L , Anup Patel Subject: [PATCH v2 3/3] iommu/riscv: Add ACPI support Date: Tue, 10 Jun 2025 16:16:41 +0530 Message-ID: <20250610104641.700940-4-sunilvl@ventanamicro.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250610104641.700940-1-sunilvl@ventanamicro.com> References: <20250610104641.700940-1-sunilvl@ventanamicro.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" RISC-V IO Mapping Table (RIMT) provides the information about the IOMMU to the OS in ACPI. Add support for ACPI in RISC-V IOMMU drivers by using RIMT data. The changes at high level are, a) Register the IOMMU with RIMT data structures. b) Enable probing of platform IOMMU in ACPI way using the ACPIID defined for the RISC-V IOMMU in the BRS spec [1]. Configure the MSI domain if the platform IOMMU uses MSIs. [1] - https://github.com/riscv-non-isa/riscv-brs/blob/main/acpi-id.adoc Signed-off-by: Sunil V L Link: https://lore.kernel.org/r/20250514055723.1328557-5-sunilvl@ventanamic= ro.com Signed-off-by: Anup Patel --- drivers/iommu/riscv/iommu-platform.c | 17 ++++++++++++++++- drivers/iommu/riscv/iommu.c | 10 ++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/drivers/iommu/riscv/iommu-platform.c b/drivers/iommu/riscv/iom= mu-platform.c index 725e919b97ef..83a28c83f991 100644 --- a/drivers/iommu/riscv/iommu-platform.c +++ b/drivers/iommu/riscv/iommu-platform.c @@ -10,6 +10,8 @@ * Tomasz Jeznach */ =20 +#include +#include #include #include #include @@ -46,6 +48,7 @@ static int riscv_iommu_platform_probe(struct platform_dev= ice *pdev) enum riscv_iommu_igs_settings igs; struct device *dev =3D &pdev->dev; struct riscv_iommu_device *iommu =3D NULL; + struct irq_domain *msi_domain; struct resource *res =3D NULL; int vec, ret; =20 @@ -76,8 +79,13 @@ static int riscv_iommu_platform_probe(struct platform_de= vice *pdev) switch (igs) { case RISCV_IOMMU_CAPABILITIES_IGS_BOTH: case RISCV_IOMMU_CAPABILITIES_IGS_MSI: - if (is_of_node(dev->fwnode)) + if (is_of_node(dev_fwnode(dev))) { of_msi_configure(dev, to_of_node(dev->fwnode)); + } else { + msi_domain =3D irq_find_matching_fwnode(imsic_acpi_get_fwnode(dev), + DOMAIN_BUS_PLATFORM_MSI); + dev_set_msi_domain(dev, msi_domain); + } =20 if (!dev_get_msi_domain(dev)) { dev_warn(dev, "failed to find an MSI domain\n"); @@ -150,6 +158,12 @@ static const struct of_device_id riscv_iommu_of_match[= ] =3D { {}, }; =20 +static const struct acpi_device_id riscv_iommu_acpi_match[] =3D { + { "RSCV0004", 0 }, + {} +}; +MODULE_DEVICE_TABLE(acpi, riscv_iommu_acpi_match); + static struct platform_driver riscv_iommu_platform_driver =3D { .probe =3D riscv_iommu_platform_probe, .remove =3D riscv_iommu_platform_remove, @@ -158,6 +172,7 @@ static struct platform_driver riscv_iommu_platform_driv= er =3D { .name =3D "riscv,iommu", .of_match_table =3D riscv_iommu_of_match, .suppress_bind_attrs =3D true, + .acpi_match_table =3D riscv_iommu_acpi_match, }, }; =20 diff --git a/drivers/iommu/riscv/iommu.c b/drivers/iommu/riscv/iommu.c index bb57092ca901..45a263c9e0d5 100644 --- a/drivers/iommu/riscv/iommu.c +++ b/drivers/iommu/riscv/iommu.c @@ -12,6 +12,8 @@ =20 #define pr_fmt(fmt) "riscv-iommu: " fmt =20 +#include +#include #include #include #include @@ -1651,6 +1653,14 @@ int riscv_iommu_init(struct riscv_iommu_device *iomm= u) goto err_iodir_off; } =20 + if (!acpi_disabled) { + rc =3D rimt_iommu_register(iommu->dev); + if (rc) { + dev_err_probe(iommu->dev, rc, "cannot register iommu with RIMT\n"); + goto err_remove_sysfs; + } + } + rc =3D iommu_device_register(&iommu->iommu, &riscv_iommu_ops, iommu->dev); if (rc) { dev_err_probe(iommu->dev, rc, "cannot register iommu interface\n"); --=20 2.43.0