mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH v2 0/4] ACPI: LoongArch: Add IOVT table support
@ 2026-07-17  6:37 Bibo Mao
  2026-07-17  6:37 ` [PATCH v2 1/4] ACPI: LoongArch: Add acpi_arch_[late]_init() Bibo Mao
                   ` (3 more replies)
  0 siblings, 4 replies; 10+ messages in thread
From: Bibo Mao @ 2026-07-17  6:37 UTC (permalink / raw)
  To: Huacai Chen, Rafael J . Wysocki
  Cc: Len Brown, Saket Dumbre, linux-kernel, loongarch, linux-acpi,
	acpica-devel, lixianglai

I/O Virtualization Table is ACPI table for LoongArch IOMMU devices, it
is merged on ACPI Spec 6.6, and it can be located at
  https://www.loongson.cn/uploads/images/2024110517404135188.LoongArch-IO-Virtualization-Table-Specification.pdf

Here add IOVT table parsing on LoongArch system, it is for LoongArch
IOMMU driver use in future.
---
v1 ... v2:
  1. Reorganize the patch, patch 1/4 are merged, patch 3/5/6 are merged,
     add patch 2/8 are merged together.
  2. Enrich error printk information in iovt_get_pci_iommu_fwnode(). 
---
Bibo Mao (4):
  ACPI: LoongArch: Add acpi_arch_[late]_init()
  ACPI: LoongArch: Add IOVT device entry table scanning
  ACPI: scan: Add support for LoongArch in acpi_iommu_configure_id()
  MAINTAINERS: Add entry for drivers/acpi/loongarch

 MAINTAINERS                     |   9 +
 arch/loongarch/Kconfig          |   1 +
 drivers/acpi/Kconfig            |   4 +
 drivers/acpi/Makefile           |   2 +-
 drivers/acpi/bus.c              |   2 +
 drivers/acpi/loongarch/Kconfig  |   7 +
 drivers/acpi/loongarch/Makefile |   3 +
 drivers/acpi/loongarch/init.c   |  16 ++
 drivers/acpi/loongarch/init.h   |   5 +
 drivers/acpi/loongarch/iovt.c   | 280 ++++++++++++++++++++++++++++++++
 drivers/acpi/scan.c             |   3 +
 include/acpi/actbl2.h           |   3 +
 include/linux/acpi.h            |   1 +
 include/linux/acpi_iovt.h       |  13 ++
 14 files changed, 348 insertions(+), 1 deletion(-)
 create mode 100644 drivers/acpi/loongarch/Kconfig
 create mode 100644 drivers/acpi/loongarch/Makefile
 create mode 100644 drivers/acpi/loongarch/init.c
 create mode 100644 drivers/acpi/loongarch/init.h
 create mode 100644 drivers/acpi/loongarch/iovt.c
 create mode 100644 include/linux/acpi_iovt.h


base-commit: 58717b2a1365d06c8c64b72aa948541b53fe31eb
-- 
2.39.3


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH v2 1/4] ACPI: LoongArch: Add acpi_arch_[late]_init()
  2026-07-17  6:37 [PATCH v2 0/4] ACPI: LoongArch: Add IOVT table support Bibo Mao
@ 2026-07-17  6:37 ` Bibo Mao
  2026-07-21 19:10   ` Rafael J. Wysocki (Intel)
  2026-07-17  6:37 ` [PATCH v2 2/4] ACPI: LoongArch: Add IOVT device entry table scanning Bibo Mao
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 10+ messages in thread
From: Bibo Mao @ 2026-07-17  6:37 UTC (permalink / raw)
  To: Huacai Chen, Rafael J . Wysocki
  Cc: Len Brown, Saket Dumbre, linux-kernel, loongarch, linux-acpi,
	acpica-devel, lixianglai

LoongArch IOMMU scanning flow is similar with virtio-iommu,
there is early init and late_init. In early init function, PCI
ACS is enabled if there is IOMMU table, and late_init is called
after PCI device scanning, where IOVT table scanning function is
executed.

Here add acpi_arch_init() and acpi_arch_late_init() API on LoongArch,
now they are both empty, In the future, IOVT table parsing will be
added.

Signed-off-by: Bibo Mao <maobibo@loongson.cn>
---
 drivers/acpi/Makefile           |  2 +-
 drivers/acpi/bus.c              |  2 ++
 drivers/acpi/loongarch/Makefile |  2 ++
 drivers/acpi/loongarch/init.c   | 11 +++++++++++
 include/linux/acpi.h            |  1 +
 5 files changed, 17 insertions(+), 1 deletion(-)
 create mode 100644 drivers/acpi/loongarch/Makefile
 create mode 100644 drivers/acpi/loongarch/init.c

diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index d1b0affb844f..91584a3c1e01 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -131,6 +131,6 @@ obj-y				+= dptf/
 obj-$(CONFIG_ARM64)		+= arm64/
 
 obj-$(CONFIG_ACPI_VIOT)		+= viot.o
-
+obj-$(CONFIG_LOONGARCH)		+= loongarch/
 obj-$(CONFIG_RISCV)		+= riscv/
 obj-$(CONFIG_X86)		+= x86/
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index a30a904f6535..5f6924b9e29d 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -1571,6 +1571,7 @@ struct kobject *acpi_kobj;
 EXPORT_SYMBOL_GPL(acpi_kobj);
 
 void __weak __init acpi_arch_init(void) { }
+void __weak __init acpi_arch_late_init(void) { }
 
 static int __init acpi_init(void)
 {
@@ -1609,6 +1610,7 @@ static int __init acpi_init(void)
 	acpi_wakeup_device_init();
 	acpi_debugger_init();
 	acpi_setup_sb_notify_handler();
+	acpi_arch_late_init();
 	acpi_viot_init();
 	return 0;
 }
diff --git a/drivers/acpi/loongarch/Makefile b/drivers/acpi/loongarch/Makefile
new file mode 100644
index 000000000000..d3764139dfaf
--- /dev/null
+++ b/drivers/acpi/loongarch/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0-only
+obj-y					+= init.o
diff --git a/drivers/acpi/loongarch/init.c b/drivers/acpi/loongarch/init.c
new file mode 100644
index 000000000000..b11aa5c7d928
--- /dev/null
+++ b/drivers/acpi/loongarch/init.c
@@ -0,0 +1,11 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <linux/acpi.h>
+
+void __init acpi_arch_init(void)
+{
+}
+
+void __init acpi_arch_late_init(void)
+{
+}
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 60ab50cb8930..c6a180341c2d 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -1617,6 +1617,7 @@ static inline int acpi_pptt_get_cpumask_from_cache_id(u32 cache_id,
 #endif
 
 void acpi_arch_init(void);
+void acpi_arch_late_init(void);
 
 #ifdef CONFIG_ACPI_PCC
 void acpi_init_pcc(void);
-- 
2.39.3


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH v2 2/4] ACPI: LoongArch: Add IOVT device entry table scanning
  2026-07-17  6:37 [PATCH v2 0/4] ACPI: LoongArch: Add IOVT table support Bibo Mao
  2026-07-17  6:37 ` [PATCH v2 1/4] ACPI: LoongArch: Add acpi_arch_[late]_init() Bibo Mao
@ 2026-07-17  6:37 ` Bibo Mao
  2026-07-21 19:09   ` Rafael J. Wysocki (Intel)
  2026-07-17  6:37 ` [PATCH v2 3/4] ACPI: scan: Add support for LoongArch in acpi_iommu_configure_id() Bibo Mao
  2026-07-17  6:37 ` [PATCH v2 4/4] MAINTAINERS: Add entry for drivers/acpi/loongarch Bibo Mao
  3 siblings, 1 reply; 10+ messages in thread
From: Bibo Mao @ 2026-07-17  6:37 UTC (permalink / raw)
  To: Huacai Chen, Rafael J . Wysocki
  Cc: Len Brown, Saket Dumbre, linux-kernel, loongarch, linux-acpi,
	acpica-devel, lixianglai

Similar with acpi_arch_init()/acpi_arch_late_init(), here function
acpi_iovt_init()/acpi_iovt_late_init() is added. Function
acpi_iovt_init() is to enable PCI ACS function if IOMMU device exists
in IOVT table, and function acpi_iovt_late_init() is to scan IOVT
table, add IOMMU devices.

Signed-off-by: Bibo Mao <maobibo@loongson.cn>
---
 drivers/acpi/Kconfig            |   4 +
 drivers/acpi/loongarch/Kconfig  |   7 +
 drivers/acpi/loongarch/Makefile |   1 +
 drivers/acpi/loongarch/init.c   |   5 +
 drivers/acpi/loongarch/init.h   |   5 +
 drivers/acpi/loongarch/iovt.c   | 219 ++++++++++++++++++++++++++++++++
 include/acpi/actbl2.h           |   3 +
 7 files changed, 244 insertions(+)
 create mode 100644 drivers/acpi/loongarch/Kconfig
 create mode 100644 drivers/acpi/loongarch/init.h
 create mode 100644 drivers/acpi/loongarch/iovt.c

diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index f165d14cf61a..192e6f18eda1 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -550,6 +550,10 @@ if ARM64
 source "drivers/acpi/arm64/Kconfig"
 endif
 
+if LOONGARCH
+source "drivers/acpi/loongarch/Kconfig"
+endif
+
 if RISCV
 source "drivers/acpi/riscv/Kconfig"
 endif
diff --git a/drivers/acpi/loongarch/Kconfig b/drivers/acpi/loongarch/Kconfig
new file mode 100644
index 000000000000..91ba3c35b9bf
--- /dev/null
+++ b/drivers/acpi/loongarch/Kconfig
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# ACPI Configuration for LOONGARCH
+#
+
+config ACPI_IOVT
+	bool
diff --git a/drivers/acpi/loongarch/Makefile b/drivers/acpi/loongarch/Makefile
index d3764139dfaf..c338d3102fc1 100644
--- a/drivers/acpi/loongarch/Makefile
+++ b/drivers/acpi/loongarch/Makefile
@@ -1,2 +1,3 @@
 # SPDX-License-Identifier: GPL-2.0-only
 obj-y					+= init.o
+obj-$(CONFIG_ACPI_IOVT)			+= iovt.o
diff --git a/drivers/acpi/loongarch/init.c b/drivers/acpi/loongarch/init.c
index b11aa5c7d928..e7272ee197c7 100644
--- a/drivers/acpi/loongarch/init.c
+++ b/drivers/acpi/loongarch/init.c
@@ -1,11 +1,16 @@
 // SPDX-License-Identifier: GPL-2.0-only
 
 #include <linux/acpi.h>
+#include "init.h"
 
 void __init acpi_arch_init(void)
 {
+	if (IS_ENABLED(CONFIG_ACPI_IOVT))
+		acpi_iovt_init();
 }
 
 void __init acpi_arch_late_init(void)
 {
+	if (IS_ENABLED(CONFIG_ACPI_IOVT))
+		acpi_iovt_late_init();
 }
diff --git a/drivers/acpi/loongarch/init.h b/drivers/acpi/loongarch/init.h
new file mode 100644
index 000000000000..85e5197553ad
--- /dev/null
+++ b/drivers/acpi/loongarch/init.h
@@ -0,0 +1,5 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#include <linux/init.h>
+
+void __init acpi_iovt_init(void);
+void __init acpi_iovt_late_init(void);
diff --git a/drivers/acpi/loongarch/iovt.c b/drivers/acpi/loongarch/iovt.c
new file mode 100644
index 000000000000..fb384664ba78
--- /dev/null
+++ b/drivers/acpi/loongarch/iovt.c
@@ -0,0 +1,219 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <linux/acpi.h>
+#include <linux/pci.h>
+#include "init.h"
+
+struct iovt_device_entry {
+	struct list_head list;
+	int start_devid;
+	int end_devid;
+};
+
+struct iovt_fwnode {
+	struct list_head list;
+	struct fwnode_handle *fwnode;
+	int flag;
+	int segment;
+	int devid;
+	int nid;
+	struct list_head ep_list;
+};
+
+/* Root pointer to the mapped IOVT table */
+static LIST_HEAD(iovt_fwnode_list);
+static DEFINE_SPINLOCK(iovt_fwnode_lock);
+
+#ifdef CONFIG_PCI
+static void __init iovt_enable_acs(struct acpi_iovt_iommu *iommu)
+{
+	static bool acs_enabled __initdata;
+
+	if (acs_enabled)
+		return;
+
+	/* IOMMU V1 only supports PCI device management */
+	if ((iommu->header.type == ACPI_IOVT_IOMMU_V1) ||
+		(iommu->flags & (ACPI_IOVT_PCI_DEVICE | ACPI_IOVT_MAGAGE_BY_SEGMENT))) {
+		pci_request_acs();
+		acs_enabled = true;
+	}
+}
+#else
+static inline void iovt_enable_acs(struct acpi_iovt_iommu *iommu) { }
+#endif
+
+static int __init iovt_get_pci_iommu_fwnode(struct iovt_fwnode *np, u16 segment, u16 bdf)
+{
+	struct pci_dev *pdev;
+	struct fwnode_handle *fwnode;
+
+	pdev = pci_get_domain_bus_and_slot(segment, PCI_BUS_NUM(bdf), bdf & 0xff);
+	if (!pdev) {
+		pr_err("No PCI IOMMU found for segment 0x%x bdf 0x%x\n", segment, bdf);
+		return -ENODEV;
+	}
+
+	fwnode = dev_fwnode(&pdev->dev);
+	if (!fwnode) {
+		/*
+		 * PCI devices aren't necessarily described by ACPI. Create a
+		 * fwnode so the IOMMU subsystem can identify this device.
+		 */
+		fwnode = acpi_alloc_fwnode_static();
+		if (!fwnode) {
+			pci_dev_put(pdev);
+			return -ENOMEM;
+		}
+		set_primary_fwnode(&pdev->dev, fwnode);
+	}
+
+	np->fwnode = dev_fwnode(&pdev->dev);
+	if (np->flag & ACPI_IOVT_PXM_VALID)
+		set_dev_node(&pdev->dev, np->nid);
+	pci_dev_put(pdev);
+	return 0;
+}
+
+static int __init iovt_add_iommu(struct acpi_iovt_iommu *iommu)
+{
+	struct iovt_fwnode *np;
+	struct fwnode_handle *fwnode;
+	struct acpi_iovt_device_entry *ep;
+	struct iovt_device_entry *entry;
+	int i, ret, start_devid;
+	bool is_start = false;
+
+	np = kzalloc_obj(struct iovt_fwnode, GFP_ATOMIC);
+	if (WARN_ON(!np))
+		return -ENOMEM;
+
+	INIT_LIST_HEAD(&np->list);
+	np->flag = iommu->flags;
+	np->segment = iommu->segment;
+	if (np->flag & ACPI_IOVT_PXM_VALID)
+		np->nid = pxm_to_node(iommu->proximity_domain);
+
+	if (np->flag & ACPI_IOVT_PCI_DEVICE) {
+		np->devid = iommu->device_id;
+		ret = iovt_get_pci_iommu_fwnode(np, np->segment, np->devid);
+		if (ret) {
+			kfree(np);
+			return ret;
+		}
+
+	} else {
+		fwnode = acpi_alloc_fwnode_static();
+		if (!fwnode) {
+			kfree(np);
+			return -ENOMEM;
+		}
+
+		np->fwnode = fwnode;
+	}
+
+	/* All devices in the segment are managed by this IOMMU */
+	if (np->flag & ACPI_IOVT_MAGAGE_BY_SEGMENT)
+		goto skip;
+
+	INIT_LIST_HEAD(&np->ep_list);
+	ep = ACPI_ADD_PTR(struct acpi_iovt_device_entry, iommu, iommu->device_entry_offset);
+	for (i = 0; i < iommu->device_entry_num; i++) {
+		switch (ep->type) {
+		case ACPI_IOVT_DEVICE_ENTRY_START:
+			is_start = true;
+			start_devid = ep->device_id;
+			break;
+		case ACPI_IOVT_DEVICE_ENTRY_END:
+			if (!is_start)
+				break;
+
+			entry = kzalloc_obj(struct iovt_device_entry, GFP_ATOMIC);
+			if (!entry)
+				return -ENOMEM;
+
+			entry->start_devid = start_devid;
+			entry->end_devid = ep->device_id;
+			list_add_tail(&entry->list, &np->ep_list);
+			is_start = false;
+			break;
+		case ACPI_IOVT_DEVICE_ENTRY_SINGLE:
+			entry = kzalloc_obj(struct iovt_device_entry, GFP_ATOMIC);
+			if (!entry)
+				return -ENOMEM;
+
+			entry->start_devid = ep->device_id;
+			entry->end_devid = ep->device_id;
+			list_add_tail(&entry->list, &np->ep_list);
+			is_start = false;
+			break;
+		default:
+			break;
+		}
+		ep = ACPI_ADD_PTR(struct acpi_iovt_device_entry, ep, ep->length);
+	}
+
+skip:
+	spin_lock(&iovt_fwnode_lock);
+	list_add_tail(&np->list, &iovt_fwnode_list);
+	spin_unlock(&iovt_fwnode_lock);
+	return 0;
+}
+
+static void __init iovt_init_devices(struct acpi_table_header *header)
+{
+	struct acpi_iovt_iommu *iommu;
+	struct acpi_table_iovt *iovt;
+	int i;
+
+	/* Get the first IOVT node */
+	iovt = (struct acpi_table_iovt *)header;
+	iommu = ACPI_ADD_PTR(struct acpi_iovt_iommu, iovt, iovt->iommu_offset);
+	for (i = 0; i < iovt->iommu_count; i++) {
+		iovt_add_iommu(iommu);
+		iommu = ACPI_ADD_PTR(struct acpi_iovt_iommu, iommu, iommu->header.length);
+	}
+}
+
+void __init acpi_iovt_init(void)
+{
+	acpi_status status;
+	struct acpi_table_header *hdr;
+	struct acpi_table_iovt *iovt;
+	struct acpi_iovt_iommu *iommu;
+	int i;
+
+	status = acpi_get_table(ACPI_SIG_IOVT, 0, &hdr);
+	if (ACPI_FAILURE(status)) {
+		if (status != AE_NOT_FOUND)
+			pr_err("Failed to get table, %s\n", acpi_format_exception(status));
+
+		return;
+	}
+
+	iovt = (struct acpi_table_iovt *)&hdr;
+	iommu = ACPI_ADD_PTR(struct acpi_iovt_iommu, iovt, iovt->iommu_offset);
+	for (i = 0; i < iovt->iommu_count; i++) {
+		iovt_enable_acs(iommu);
+		iommu = ACPI_ADD_PTR(struct acpi_iovt_iommu, iommu, iommu->header.length);
+	}
+
+	acpi_put_table(hdr);
+}
+
+void __init acpi_iovt_late_init(void)
+{
+	acpi_status status;
+	struct acpi_table_header *hdr;
+
+	status = acpi_get_table(ACPI_SIG_IOVT, 0, &hdr);
+	if (ACPI_FAILURE(status)) {
+		if (status != AE_NOT_FOUND)
+			pr_err("Failed to get table, %s\n", acpi_format_exception(status));
+
+		return;
+	}
+
+	iovt_init_devices(hdr);
+	acpi_put_table(hdr);
+}
diff --git a/include/acpi/actbl2.h b/include/acpi/actbl2.h
index baef525367b5..acc51a42c3ed 100644
--- a/include/acpi/actbl2.h
+++ b/include/acpi/actbl2.h
@@ -892,6 +892,9 @@ struct acpi_iovt_header {
 
 /* Values for Type field above */
 
+#define ACPI_IOVT_PCI_DEVICE		BIT(0)
+#define ACPI_IOVT_PXM_VALID		BIT(1)
+#define ACPI_IOVT_MAGAGE_BY_SEGMENT	BIT(2)
 enum acpi_iovt_iommu_type {
 	ACPI_IOVT_IOMMU_V1 = 0x00,
 	ACPI_IOVT_IOMMU_RESERVED = 0x01	/* 1 and greater are reserved */
-- 
2.39.3


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH v2 3/4] ACPI: scan: Add support for LoongArch in acpi_iommu_configure_id()
  2026-07-17  6:37 [PATCH v2 0/4] ACPI: LoongArch: Add IOVT table support Bibo Mao
  2026-07-17  6:37 ` [PATCH v2 1/4] ACPI: LoongArch: Add acpi_arch_[late]_init() Bibo Mao
  2026-07-17  6:37 ` [PATCH v2 2/4] ACPI: LoongArch: Add IOVT device entry table scanning Bibo Mao
@ 2026-07-17  6:37 ` Bibo Mao
  2026-07-21 19:07   ` Rafael J. Wysocki (Intel)
  2026-07-17  6:37 ` [PATCH v2 4/4] MAINTAINERS: Add entry for drivers/acpi/loongarch Bibo Mao
  3 siblings, 1 reply; 10+ messages in thread
From: Bibo Mao @ 2026-07-17  6:37 UTC (permalink / raw)
  To: Huacai Chen, Rafael J . Wysocki
  Cc: Len Brown, Saket Dumbre, linux-kernel, loongarch, linux-acpi,
	acpica-devel, lixianglai

acpi_iommu_configure_id() currently supports only IORT and VIOT. Add
support for IOVT as well.

Signed-off-by: Bibo Mao <maobibo@loongson.cn>
---
 drivers/acpi/loongarch/iovt.c | 61 +++++++++++++++++++++++++++++++++++
 drivers/acpi/scan.c           |  3 ++
 include/linux/acpi_iovt.h     | 13 ++++++++
 3 files changed, 77 insertions(+)
 create mode 100644 include/linux/acpi_iovt.h

diff --git a/drivers/acpi/loongarch/iovt.c b/drivers/acpi/loongarch/iovt.c
index fb384664ba78..09fcf09e0f85 100644
--- a/drivers/acpi/loongarch/iovt.c
+++ b/drivers/acpi/loongarch/iovt.c
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 
 #include <linux/acpi.h>
+#include <linux/acpi_iovt.h>
 #include <linux/pci.h>
 #include "init.h"
 
@@ -217,3 +218,63 @@ void __init acpi_iovt_late_init(void)
 	iovt_init_devices(hdr);
 	acpi_put_table(hdr);
 }
+
+static int iovt_pci_dev_iommu_init(struct pci_dev *pdev, u16 dev_id, void *data)
+{
+	u32 sbdf;
+	struct iovt_fwnode *np;
+	struct device *aliased_dev = data;
+	u32 domain = pci_domain_nr(pdev->bus);
+	struct iovt_device_entry *entry;
+	bool found = false;
+
+	list_for_each_entry(np, &iovt_fwnode_list, list) {
+		if (domain != np->segment)
+			continue;
+
+		/* We're not translating ourself */
+		if (dev_id == np->devid)
+			return -EINVAL;
+
+		if (np->flag & ACPI_IOVT_MAGAGE_BY_SEGMENT) {
+			found = true;
+			break;
+		}
+
+		list_for_each_entry(entry, &np->ep_list, list) {
+			if (dev_id < entry->start_devid)
+				continue;
+
+			if (dev_id > entry->end_devid)
+				continue;
+
+			found = true;
+			break;
+		}
+
+		if (found)
+			break;
+	}
+
+	if (!found)
+		return -ENODEV;
+
+	sbdf = (domain << 16) + dev_id;
+	return acpi_iommu_fwspec_init(aliased_dev, sbdf, np->fwnode);
+}
+
+/*
+ * iovt_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 iovt_iommu_configure_id(struct device *dev, const u32 *id_in)
+{
+	if (!dev_is_pci(dev))
+		return -ENODEV;
+
+	return pci_for_each_dma_alias(to_pci_dev(dev), iovt_pci_dev_iommu_init, dev);
+}
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 9a7ac2eb9ce0..508575f25e10 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -13,6 +13,7 @@
 #include <linux/kernel.h>
 #include <linux/acpi.h>
 #include <linux/acpi_iort.h>
+#include <linux/acpi_iovt.h>
 #include <linux/acpi_rimt.h>
 #include <linux/acpi_viot.h>
 #include <linux/iommu.h>
@@ -1629,6 +1630,8 @@ static int acpi_iommu_configure_id(struct device *dev, const u32 *id_in)
 		err = rimt_iommu_configure_id(dev, id_in);
 	if (err && err != -EPROBE_DEFER)
 		err = viot_iommu_configure(dev);
+	if (err && err != -EPROBE_DEFER)
+		err = iovt_iommu_configure_id(dev, id_in);
 
 	mutex_unlock(&iommu_probe_device_lock);
 
diff --git a/include/linux/acpi_iovt.h b/include/linux/acpi_iovt.h
new file mode 100644
index 000000000000..25a846b96260
--- /dev/null
+++ b/include/linux/acpi_iovt.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef __ACPI_IOVT_H__
+#define __ACPI_IOVT_H__
+
+#if defined(CONFIG_IOMMU_API) && defined(CONFIG_ACPI_IOVT)
+int iovt_iommu_configure_id(struct device *dev, const u32 *id_in);
+#else
+static inline int iovt_iommu_configure_id(struct device *dev, const u32 *id_in)
+{ return -ENODEV; }
+#endif
+
+#endif
-- 
2.39.3


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH v2 4/4] MAINTAINERS: Add entry for drivers/acpi/loongarch
  2026-07-17  6:37 [PATCH v2 0/4] ACPI: LoongArch: Add IOVT table support Bibo Mao
                   ` (2 preceding siblings ...)
  2026-07-17  6:37 ` [PATCH v2 3/4] ACPI: scan: Add support for LoongArch in acpi_iommu_configure_id() Bibo Mao
@ 2026-07-17  6:37 ` Bibo Mao
  3 siblings, 0 replies; 10+ messages in thread
From: Bibo Mao @ 2026-07-17  6:37 UTC (permalink / raw)
  To: Huacai Chen, Rafael J . Wysocki
  Cc: Len Brown, Saket Dumbre, linux-kernel, loongarch, linux-acpi,
	acpica-devel, lixianglai

ACPI defines few LoongArch specific tables which need parsing code
added in drivers/acpi/loongarch. Add maintainer entries for this newly
created folder.

Signed-off-by: Bibo Mao <maobibo@loongson.cn>
---
 MAINTAINERS            | 9 +++++++++
 arch/loongarch/Kconfig | 1 +
 2 files changed, 10 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index ce5c5185c773..d741f87fcf8c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -348,6 +348,15 @@ S:	Maintained
 F:	drivers/acpi/riscv/
 F:	include/linux/acpi_rimt.h
 
+ACPI FOR LoongArch (ACPI/LoongArch)
+M:	Bibo Mao <maobibo@loongson.cn>
+R:	Huacai Chen <chenhuacai@kernel.org>
+L:	linux-acpi@vger.kernel.org
+L:	loongarch@lists.linux.dev
+S:	Maintained
+F:	drivers/acpi/loongarch/
+F:	include/linux/acpi_iovt.h
+
 ACPI PCC(Platform Communication Channel) MAILBOX DRIVER
 M:	Sudeep Holla <sudeep.holla@kernel.org>
 L:	linux-acpi@vger.kernel.org
diff --git a/arch/loongarch/Kconfig b/arch/loongarch/Kconfig
index d8d252325017..ee3d591ace04 100644
--- a/arch/loongarch/Kconfig
+++ b/arch/loongarch/Kconfig
@@ -6,6 +6,7 @@ config LOONGARCH
 	select ACPI_GENERIC_GSI if ACPI
 	select ACPI_MCFG if ACPI
 	select ACPI_HOTPLUG_CPU if ACPI_PROCESSOR && HOTPLUG_CPU
+	select ACPI_IOVT if ACPI
 	select ACPI_PPTT if ACPI
 	select ACPI_SYSTEM_POWER_STATES_SUPPORT	if ACPI
 	select ARCH_BINFMT_ELF_STATE
-- 
2.39.3


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2 3/4] ACPI: scan: Add support for LoongArch in acpi_iommu_configure_id()
  2026-07-17  6:37 ` [PATCH v2 3/4] ACPI: scan: Add support for LoongArch in acpi_iommu_configure_id() Bibo Mao
@ 2026-07-21 19:07   ` Rafael J. Wysocki (Intel)
  0 siblings, 0 replies; 10+ messages in thread
From: Rafael J. Wysocki (Intel) @ 2026-07-21 19:07 UTC (permalink / raw)
  To: Bibo Mao
  Cc: Huacai Chen, Rafael J . Wysocki, Len Brown, Saket Dumbre,
	linux-kernel, loongarch, linux-acpi, acpica-devel, lixianglai

On Fri, Jul 17, 2026 at 8:44 AM Bibo Mao <maobibo@loongson.cn> wrote:
>
> acpi_iommu_configure_id() currently supports only IORT and VIOT. Add
> support for IOVT as well.
>
> Signed-off-by: Bibo Mao <maobibo@loongson.cn>

The one-liner in scan.c is fine with me, so

Acked-by: Rafael J. Wysocki (Intel) <rafael@kernel.org> # ACPI core

for this one, but conditional on the acceptance of the Loongarch-specific parts.

Thanks!

> ---
>  drivers/acpi/loongarch/iovt.c | 61 +++++++++++++++++++++++++++++++++++
>  drivers/acpi/scan.c           |  3 ++
>  include/linux/acpi_iovt.h     | 13 ++++++++
>  3 files changed, 77 insertions(+)
>  create mode 100644 include/linux/acpi_iovt.h
>
> diff --git a/drivers/acpi/loongarch/iovt.c b/drivers/acpi/loongarch/iovt.c
> index fb384664ba78..09fcf09e0f85 100644
> --- a/drivers/acpi/loongarch/iovt.c
> +++ b/drivers/acpi/loongarch/iovt.c
> @@ -1,6 +1,7 @@
>  // SPDX-License-Identifier: GPL-2.0-only
>
>  #include <linux/acpi.h>
> +#include <linux/acpi_iovt.h>
>  #include <linux/pci.h>
>  #include "init.h"
>
> @@ -217,3 +218,63 @@ void __init acpi_iovt_late_init(void)
>         iovt_init_devices(hdr);
>         acpi_put_table(hdr);
>  }
> +
> +static int iovt_pci_dev_iommu_init(struct pci_dev *pdev, u16 dev_id, void *data)
> +{
> +       u32 sbdf;
> +       struct iovt_fwnode *np;
> +       struct device *aliased_dev = data;
> +       u32 domain = pci_domain_nr(pdev->bus);
> +       struct iovt_device_entry *entry;
> +       bool found = false;
> +
> +       list_for_each_entry(np, &iovt_fwnode_list, list) {
> +               if (domain != np->segment)
> +                       continue;
> +
> +               /* We're not translating ourself */
> +               if (dev_id == np->devid)
> +                       return -EINVAL;
> +
> +               if (np->flag & ACPI_IOVT_MAGAGE_BY_SEGMENT) {
> +                       found = true;
> +                       break;
> +               }
> +
> +               list_for_each_entry(entry, &np->ep_list, list) {
> +                       if (dev_id < entry->start_devid)
> +                               continue;
> +
> +                       if (dev_id > entry->end_devid)
> +                               continue;
> +
> +                       found = true;
> +                       break;
> +               }
> +
> +               if (found)
> +                       break;
> +       }
> +
> +       if (!found)
> +               return -ENODEV;
> +
> +       sbdf = (domain << 16) + dev_id;
> +       return acpi_iommu_fwspec_init(aliased_dev, sbdf, np->fwnode);
> +}
> +
> +/*
> + * iovt_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 iovt_iommu_configure_id(struct device *dev, const u32 *id_in)
> +{
> +       if (!dev_is_pci(dev))
> +               return -ENODEV;
> +
> +       return pci_for_each_dma_alias(to_pci_dev(dev), iovt_pci_dev_iommu_init, dev);
> +}
> diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
> index 9a7ac2eb9ce0..508575f25e10 100644
> --- a/drivers/acpi/scan.c
> +++ b/drivers/acpi/scan.c
> @@ -13,6 +13,7 @@
>  #include <linux/kernel.h>
>  #include <linux/acpi.h>
>  #include <linux/acpi_iort.h>
> +#include <linux/acpi_iovt.h>
>  #include <linux/acpi_rimt.h>
>  #include <linux/acpi_viot.h>
>  #include <linux/iommu.h>
> @@ -1629,6 +1630,8 @@ static int acpi_iommu_configure_id(struct device *dev, const u32 *id_in)
>                 err = rimt_iommu_configure_id(dev, id_in);
>         if (err && err != -EPROBE_DEFER)
>                 err = viot_iommu_configure(dev);
> +       if (err && err != -EPROBE_DEFER)
> +               err = iovt_iommu_configure_id(dev, id_in);
>
>         mutex_unlock(&iommu_probe_device_lock);
>
> diff --git a/include/linux/acpi_iovt.h b/include/linux/acpi_iovt.h
> new file mode 100644
> index 000000000000..25a846b96260
> --- /dev/null
> +++ b/include/linux/acpi_iovt.h
> @@ -0,0 +1,13 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +
> +#ifndef __ACPI_IOVT_H__
> +#define __ACPI_IOVT_H__
> +
> +#if defined(CONFIG_IOMMU_API) && defined(CONFIG_ACPI_IOVT)
> +int iovt_iommu_configure_id(struct device *dev, const u32 *id_in);
> +#else
> +static inline int iovt_iommu_configure_id(struct device *dev, const u32 *id_in)
> +{ return -ENODEV; }
> +#endif
> +
> +#endif
> --
> 2.39.3
>

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2 2/4] ACPI: LoongArch: Add IOVT device entry table scanning
  2026-07-17  6:37 ` [PATCH v2 2/4] ACPI: LoongArch: Add IOVT device entry table scanning Bibo Mao
@ 2026-07-21 19:09   ` Rafael J. Wysocki (Intel)
  2026-07-23 12:44     ` Bibo Mao
  0 siblings, 1 reply; 10+ messages in thread
From: Rafael J. Wysocki (Intel) @ 2026-07-21 19:09 UTC (permalink / raw)
  To: Bibo Mao
  Cc: Huacai Chen, Rafael J . Wysocki, Len Brown, Saket Dumbre,
	linux-kernel, loongarch, linux-acpi, acpica-devel, lixianglai

On Fri, Jul 17, 2026 at 8:44 AM Bibo Mao <maobibo@loongson.cn> wrote:
>
> Similar with acpi_arch_init()/acpi_arch_late_init(), here function
> acpi_iovt_init()/acpi_iovt_late_init() is added. Function
> acpi_iovt_init() is to enable PCI ACS function if IOMMU device exists
> in IOVT table, and function acpi_iovt_late_init() is to scan IOVT
> table, add IOMMU devices.
>
> Signed-off-by: Bibo Mao <maobibo@loongson.cn>
> ---
>  drivers/acpi/Kconfig            |   4 +
>  drivers/acpi/loongarch/Kconfig  |   7 +
>  drivers/acpi/loongarch/Makefile |   1 +
>  drivers/acpi/loongarch/init.c   |   5 +
>  drivers/acpi/loongarch/init.h   |   5 +
>  drivers/acpi/loongarch/iovt.c   | 219 ++++++++++++++++++++++++++++++++
>  include/acpi/actbl2.h           |   3 +

The actbl2.h change should go through upstream ACPICA, shouldn't it?

>  7 files changed, 244 insertions(+)
>  create mode 100644 drivers/acpi/loongarch/Kconfig
>  create mode 100644 drivers/acpi/loongarch/init.h
>  create mode 100644 drivers/acpi/loongarch/iovt.c
>
> diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
> index f165d14cf61a..192e6f18eda1 100644
> --- a/drivers/acpi/Kconfig
> +++ b/drivers/acpi/Kconfig
> @@ -550,6 +550,10 @@ if ARM64
>  source "drivers/acpi/arm64/Kconfig"
>  endif
>
> +if LOONGARCH
> +source "drivers/acpi/loongarch/Kconfig"
> +endif
> +
>  if RISCV
>  source "drivers/acpi/riscv/Kconfig"
>  endif
> diff --git a/drivers/acpi/loongarch/Kconfig b/drivers/acpi/loongarch/Kconfig
> new file mode 100644
> index 000000000000..91ba3c35b9bf
> --- /dev/null
> +++ b/drivers/acpi/loongarch/Kconfig
> @@ -0,0 +1,7 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +#
> +# ACPI Configuration for LOONGARCH
> +#
> +
> +config ACPI_IOVT
> +       bool
> diff --git a/drivers/acpi/loongarch/Makefile b/drivers/acpi/loongarch/Makefile
> index d3764139dfaf..c338d3102fc1 100644
> --- a/drivers/acpi/loongarch/Makefile
> +++ b/drivers/acpi/loongarch/Makefile
> @@ -1,2 +1,3 @@
>  # SPDX-License-Identifier: GPL-2.0-only
>  obj-y                                  += init.o
> +obj-$(CONFIG_ACPI_IOVT)                        += iovt.o
> diff --git a/drivers/acpi/loongarch/init.c b/drivers/acpi/loongarch/init.c
> index b11aa5c7d928..e7272ee197c7 100644
> --- a/drivers/acpi/loongarch/init.c
> +++ b/drivers/acpi/loongarch/init.c
> @@ -1,11 +1,16 @@
>  // SPDX-License-Identifier: GPL-2.0-only
>
>  #include <linux/acpi.h>
> +#include "init.h"
>
>  void __init acpi_arch_init(void)
>  {
> +       if (IS_ENABLED(CONFIG_ACPI_IOVT))
> +               acpi_iovt_init();
>  }
>
>  void __init acpi_arch_late_init(void)
>  {
> +       if (IS_ENABLED(CONFIG_ACPI_IOVT))
> +               acpi_iovt_late_init();
>  }
> diff --git a/drivers/acpi/loongarch/init.h b/drivers/acpi/loongarch/init.h
> new file mode 100644
> index 000000000000..85e5197553ad
> --- /dev/null
> +++ b/drivers/acpi/loongarch/init.h
> @@ -0,0 +1,5 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +#include <linux/init.h>
> +
> +void __init acpi_iovt_init(void);
> +void __init acpi_iovt_late_init(void);
> diff --git a/drivers/acpi/loongarch/iovt.c b/drivers/acpi/loongarch/iovt.c
> new file mode 100644
> index 000000000000..fb384664ba78
> --- /dev/null
> +++ b/drivers/acpi/loongarch/iovt.c
> @@ -0,0 +1,219 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +
> +#include <linux/acpi.h>
> +#include <linux/pci.h>
> +#include "init.h"
> +
> +struct iovt_device_entry {
> +       struct list_head list;
> +       int start_devid;
> +       int end_devid;
> +};
> +
> +struct iovt_fwnode {
> +       struct list_head list;
> +       struct fwnode_handle *fwnode;
> +       int flag;
> +       int segment;
> +       int devid;
> +       int nid;
> +       struct list_head ep_list;
> +};
> +
> +/* Root pointer to the mapped IOVT table */
> +static LIST_HEAD(iovt_fwnode_list);
> +static DEFINE_SPINLOCK(iovt_fwnode_lock);
> +
> +#ifdef CONFIG_PCI
> +static void __init iovt_enable_acs(struct acpi_iovt_iommu *iommu)
> +{
> +       static bool acs_enabled __initdata;
> +
> +       if (acs_enabled)
> +               return;
> +
> +       /* IOMMU V1 only supports PCI device management */
> +       if ((iommu->header.type == ACPI_IOVT_IOMMU_V1) ||
> +               (iommu->flags & (ACPI_IOVT_PCI_DEVICE | ACPI_IOVT_MAGAGE_BY_SEGMENT))) {
> +               pci_request_acs();
> +               acs_enabled = true;
> +       }
> +}
> +#else
> +static inline void iovt_enable_acs(struct acpi_iovt_iommu *iommu) { }
> +#endif
> +
> +static int __init iovt_get_pci_iommu_fwnode(struct iovt_fwnode *np, u16 segment, u16 bdf)
> +{
> +       struct pci_dev *pdev;
> +       struct fwnode_handle *fwnode;
> +
> +       pdev = pci_get_domain_bus_and_slot(segment, PCI_BUS_NUM(bdf), bdf & 0xff);
> +       if (!pdev) {
> +               pr_err("No PCI IOMMU found for segment 0x%x bdf 0x%x\n", segment, bdf);
> +               return -ENODEV;
> +       }
> +
> +       fwnode = dev_fwnode(&pdev->dev);
> +       if (!fwnode) {
> +               /*
> +                * PCI devices aren't necessarily described by ACPI. Create a
> +                * fwnode so the IOMMU subsystem can identify this device.
> +                */
> +               fwnode = acpi_alloc_fwnode_static();
> +               if (!fwnode) {
> +                       pci_dev_put(pdev);
> +                       return -ENOMEM;
> +               }
> +               set_primary_fwnode(&pdev->dev, fwnode);
> +       }
> +
> +       np->fwnode = dev_fwnode(&pdev->dev);
> +       if (np->flag & ACPI_IOVT_PXM_VALID)
> +               set_dev_node(&pdev->dev, np->nid);
> +       pci_dev_put(pdev);
> +       return 0;
> +}
> +
> +static int __init iovt_add_iommu(struct acpi_iovt_iommu *iommu)
> +{
> +       struct iovt_fwnode *np;
> +       struct fwnode_handle *fwnode;
> +       struct acpi_iovt_device_entry *ep;
> +       struct iovt_device_entry *entry;
> +       int i, ret, start_devid;
> +       bool is_start = false;
> +
> +       np = kzalloc_obj(struct iovt_fwnode, GFP_ATOMIC);
> +       if (WARN_ON(!np))
> +               return -ENOMEM;
> +
> +       INIT_LIST_HEAD(&np->list);
> +       np->flag = iommu->flags;
> +       np->segment = iommu->segment;
> +       if (np->flag & ACPI_IOVT_PXM_VALID)
> +               np->nid = pxm_to_node(iommu->proximity_domain);
> +
> +       if (np->flag & ACPI_IOVT_PCI_DEVICE) {
> +               np->devid = iommu->device_id;
> +               ret = iovt_get_pci_iommu_fwnode(np, np->segment, np->devid);
> +               if (ret) {
> +                       kfree(np);
> +                       return ret;
> +               }
> +
> +       } else {
> +               fwnode = acpi_alloc_fwnode_static();
> +               if (!fwnode) {
> +                       kfree(np);
> +                       return -ENOMEM;
> +               }
> +
> +               np->fwnode = fwnode;
> +       }
> +
> +       /* All devices in the segment are managed by this IOMMU */
> +       if (np->flag & ACPI_IOVT_MAGAGE_BY_SEGMENT)
> +               goto skip;
> +
> +       INIT_LIST_HEAD(&np->ep_list);
> +       ep = ACPI_ADD_PTR(struct acpi_iovt_device_entry, iommu, iommu->device_entry_offset);
> +       for (i = 0; i < iommu->device_entry_num; i++) {
> +               switch (ep->type) {
> +               case ACPI_IOVT_DEVICE_ENTRY_START:
> +                       is_start = true;
> +                       start_devid = ep->device_id;
> +                       break;
> +               case ACPI_IOVT_DEVICE_ENTRY_END:
> +                       if (!is_start)
> +                               break;
> +
> +                       entry = kzalloc_obj(struct iovt_device_entry, GFP_ATOMIC);
> +                       if (!entry)
> +                               return -ENOMEM;
> +
> +                       entry->start_devid = start_devid;
> +                       entry->end_devid = ep->device_id;
> +                       list_add_tail(&entry->list, &np->ep_list);
> +                       is_start = false;
> +                       break;
> +               case ACPI_IOVT_DEVICE_ENTRY_SINGLE:
> +                       entry = kzalloc_obj(struct iovt_device_entry, GFP_ATOMIC);
> +                       if (!entry)
> +                               return -ENOMEM;
> +
> +                       entry->start_devid = ep->device_id;
> +                       entry->end_devid = ep->device_id;
> +                       list_add_tail(&entry->list, &np->ep_list);
> +                       is_start = false;
> +                       break;
> +               default:
> +                       break;
> +               }
> +               ep = ACPI_ADD_PTR(struct acpi_iovt_device_entry, ep, ep->length);
> +       }
> +
> +skip:
> +       spin_lock(&iovt_fwnode_lock);
> +       list_add_tail(&np->list, &iovt_fwnode_list);
> +       spin_unlock(&iovt_fwnode_lock);
> +       return 0;
> +}
> +
> +static void __init iovt_init_devices(struct acpi_table_header *header)
> +{
> +       struct acpi_iovt_iommu *iommu;
> +       struct acpi_table_iovt *iovt;
> +       int i;
> +
> +       /* Get the first IOVT node */
> +       iovt = (struct acpi_table_iovt *)header;
> +       iommu = ACPI_ADD_PTR(struct acpi_iovt_iommu, iovt, iovt->iommu_offset);
> +       for (i = 0; i < iovt->iommu_count; i++) {
> +               iovt_add_iommu(iommu);
> +               iommu = ACPI_ADD_PTR(struct acpi_iovt_iommu, iommu, iommu->header.length);
> +       }
> +}
> +
> +void __init acpi_iovt_init(void)
> +{
> +       acpi_status status;
> +       struct acpi_table_header *hdr;
> +       struct acpi_table_iovt *iovt;
> +       struct acpi_iovt_iommu *iommu;
> +       int i;
> +
> +       status = acpi_get_table(ACPI_SIG_IOVT, 0, &hdr);
> +       if (ACPI_FAILURE(status)) {
> +               if (status != AE_NOT_FOUND)
> +                       pr_err("Failed to get table, %s\n", acpi_format_exception(status));
> +
> +               return;
> +       }
> +
> +       iovt = (struct acpi_table_iovt *)&hdr;
> +       iommu = ACPI_ADD_PTR(struct acpi_iovt_iommu, iovt, iovt->iommu_offset);
> +       for (i = 0; i < iovt->iommu_count; i++) {
> +               iovt_enable_acs(iommu);
> +               iommu = ACPI_ADD_PTR(struct acpi_iovt_iommu, iommu, iommu->header.length);
> +       }
> +
> +       acpi_put_table(hdr);
> +}
> +
> +void __init acpi_iovt_late_init(void)
> +{
> +       acpi_status status;
> +       struct acpi_table_header *hdr;
> +
> +       status = acpi_get_table(ACPI_SIG_IOVT, 0, &hdr);
> +       if (ACPI_FAILURE(status)) {
> +               if (status != AE_NOT_FOUND)
> +                       pr_err("Failed to get table, %s\n", acpi_format_exception(status));
> +
> +               return;
> +       }
> +
> +       iovt_init_devices(hdr);
> +       acpi_put_table(hdr);
> +}
> diff --git a/include/acpi/actbl2.h b/include/acpi/actbl2.h
> index baef525367b5..acc51a42c3ed 100644
> --- a/include/acpi/actbl2.h
> +++ b/include/acpi/actbl2.h
> @@ -892,6 +892,9 @@ struct acpi_iovt_header {
>
>  /* Values for Type field above */
>
> +#define ACPI_IOVT_PCI_DEVICE           BIT(0)
> +#define ACPI_IOVT_PXM_VALID            BIT(1)
> +#define ACPI_IOVT_MAGAGE_BY_SEGMENT    BIT(2)
>  enum acpi_iovt_iommu_type {
>         ACPI_IOVT_IOMMU_V1 = 0x00,
>         ACPI_IOVT_IOMMU_RESERVED = 0x01 /* 1 and greater are reserved */
> --
> 2.39.3
>

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2 1/4] ACPI: LoongArch: Add acpi_arch_[late]_init()
  2026-07-17  6:37 ` [PATCH v2 1/4] ACPI: LoongArch: Add acpi_arch_[late]_init() Bibo Mao
@ 2026-07-21 19:10   ` Rafael J. Wysocki (Intel)
  2026-07-23 12:47     ` Bibo Mao
  0 siblings, 1 reply; 10+ messages in thread
From: Rafael J. Wysocki (Intel) @ 2026-07-21 19:10 UTC (permalink / raw)
  To: Bibo Mao
  Cc: Huacai Chen, Rafael J . Wysocki, Len Brown, Saket Dumbre,
	linux-kernel, loongarch, linux-acpi, acpica-devel, lixianglai

On Fri, Jul 17, 2026 at 8:44 AM Bibo Mao <maobibo@loongson.cn> wrote:
>
> LoongArch IOMMU scanning flow is similar with virtio-iommu,
> there is early init and late_init. In early init function, PCI
> ACS is enabled if there is IOMMU table, and late_init is called
> after PCI device scanning, where IOVT table scanning function is
> executed.
>
> Here add acpi_arch_init() and acpi_arch_late_init() API on LoongArch,
> now they are both empty, In the future, IOVT table parsing will be
> added.
>
> Signed-off-by: Bibo Mao <maobibo@loongson.cn>
> ---
>  drivers/acpi/Makefile           |  2 +-
>  drivers/acpi/bus.c              |  2 ++
>  drivers/acpi/loongarch/Makefile |  2 ++
>  drivers/acpi/loongarch/init.c   | 11 +++++++++++
>  include/linux/acpi.h            |  1 +
>  5 files changed, 17 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/acpi/loongarch/Makefile
>  create mode 100644 drivers/acpi/loongarch/init.c
>
> diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
> index d1b0affb844f..91584a3c1e01 100644
> --- a/drivers/acpi/Makefile
> +++ b/drivers/acpi/Makefile
> @@ -131,6 +131,6 @@ obj-y                               += dptf/
>  obj-$(CONFIG_ARM64)            += arm64/
>
>  obj-$(CONFIG_ACPI_VIOT)                += viot.o
> -
> +obj-$(CONFIG_LOONGARCH)                += loongarch/
>  obj-$(CONFIG_RISCV)            += riscv/
>  obj-$(CONFIG_X86)              += x86/
> diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
> index a30a904f6535..5f6924b9e29d 100644
> --- a/drivers/acpi/bus.c
> +++ b/drivers/acpi/bus.c
> @@ -1571,6 +1571,7 @@ struct kobject *acpi_kobj;
>  EXPORT_SYMBOL_GPL(acpi_kobj);
>
>  void __weak __init acpi_arch_init(void) { }
> +void __weak __init acpi_arch_late_init(void) { }
>
>  static int __init acpi_init(void)
>  {
> @@ -1609,6 +1610,7 @@ static int __init acpi_init(void)
>         acpi_wakeup_device_init();
>         acpi_debugger_init();
>         acpi_setup_sb_notify_handler();
> +       acpi_arch_late_init();
>         acpi_viot_init();
>         return 0;
>  }
> diff --git a/drivers/acpi/loongarch/Makefile b/drivers/acpi/loongarch/Makefile
> new file mode 100644
> index 000000000000..d3764139dfaf
> --- /dev/null
> +++ b/drivers/acpi/loongarch/Makefile
> @@ -0,0 +1,2 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +obj-y                                  += init.o
> diff --git a/drivers/acpi/loongarch/init.c b/drivers/acpi/loongarch/init.c
> new file mode 100644
> index 000000000000..b11aa5c7d928
> --- /dev/null
> +++ b/drivers/acpi/loongarch/init.c
> @@ -0,0 +1,11 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +
> +#include <linux/acpi.h>
> +
> +void __init acpi_arch_init(void)
> +{
> +}
> +
> +void __init acpi_arch_late_init(void)
> +{
> +}
> diff --git a/include/linux/acpi.h b/include/linux/acpi.h
> index 60ab50cb8930..c6a180341c2d 100644
> --- a/include/linux/acpi.h
> +++ b/include/linux/acpi.h
> @@ -1617,6 +1617,7 @@ static inline int acpi_pptt_get_cpumask_from_cache_id(u32 cache_id,
>  #endif
>
>  void acpi_arch_init(void);
> +void acpi_arch_late_init(void);
>
>  #ifdef CONFIG_ACPI_PCC
>  void acpi_init_pcc(void);
> --

Please fold this one into the patch in which the new function is actually used.

Thanks!

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2 2/4] ACPI: LoongArch: Add IOVT device entry table scanning
  2026-07-21 19:09   ` Rafael J. Wysocki (Intel)
@ 2026-07-23 12:44     ` Bibo Mao
  0 siblings, 0 replies; 10+ messages in thread
From: Bibo Mao @ 2026-07-23 12:44 UTC (permalink / raw)
  To: Rafael J. Wysocki (Intel)
  Cc: Huacai Chen, Len Brown, Saket Dumbre, linux-kernel, loongarch,
	linux-acpi, acpica-devel, lixianglai



On 2026/7/22 上午3:09, Rafael J. Wysocki (Intel) wrote:
> On Fri, Jul 17, 2026 at 8:44 AM Bibo Mao <maobibo@loongson.cn> wrote:
>>
>> Similar with acpi_arch_init()/acpi_arch_late_init(), here function
>> acpi_iovt_init()/acpi_iovt_late_init() is added. Function
>> acpi_iovt_init() is to enable PCI ACS function if IOMMU device exists
>> in IOVT table, and function acpi_iovt_late_init() is to scan IOVT
>> table, add IOMMU devices.
>>
>> Signed-off-by: Bibo Mao <maobibo@loongson.cn>
>> ---
>>   drivers/acpi/Kconfig            |   4 +
>>   drivers/acpi/loongarch/Kconfig  |   7 +
>>   drivers/acpi/loongarch/Makefile |   1 +
>>   drivers/acpi/loongarch/init.c   |   5 +
>>   drivers/acpi/loongarch/init.h   |   5 +
>>   drivers/acpi/loongarch/iovt.c   | 219 ++++++++++++++++++++++++++++++++
>>   include/acpi/actbl2.h           |   3 +
> 
> The actbl2.h change should go through upstream ACPICA, shouldn't it?
yes, will update these macro definitions in upstream ACPICA firstly.

Regards
Bibo Mao
> 
>>   7 files changed, 244 insertions(+)
>>   create mode 100644 drivers/acpi/loongarch/Kconfig
>>   create mode 100644 drivers/acpi/loongarch/init.h
>>   create mode 100644 drivers/acpi/loongarch/iovt.c
>>
>> diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
>> index f165d14cf61a..192e6f18eda1 100644
>> --- a/drivers/acpi/Kconfig
>> +++ b/drivers/acpi/Kconfig
>> @@ -550,6 +550,10 @@ if ARM64
>>   source "drivers/acpi/arm64/Kconfig"
>>   endif
>>
>> +if LOONGARCH
>> +source "drivers/acpi/loongarch/Kconfig"
>> +endif
>> +
>>   if RISCV
>>   source "drivers/acpi/riscv/Kconfig"
>>   endif
>> diff --git a/drivers/acpi/loongarch/Kconfig b/drivers/acpi/loongarch/Kconfig
>> new file mode 100644
>> index 000000000000..91ba3c35b9bf
>> --- /dev/null
>> +++ b/drivers/acpi/loongarch/Kconfig
>> @@ -0,0 +1,7 @@
>> +# SPDX-License-Identifier: GPL-2.0-only
>> +#
>> +# ACPI Configuration for LOONGARCH
>> +#
>> +
>> +config ACPI_IOVT
>> +       bool
>> diff --git a/drivers/acpi/loongarch/Makefile b/drivers/acpi/loongarch/Makefile
>> index d3764139dfaf..c338d3102fc1 100644
>> --- a/drivers/acpi/loongarch/Makefile
>> +++ b/drivers/acpi/loongarch/Makefile
>> @@ -1,2 +1,3 @@
>>   # SPDX-License-Identifier: GPL-2.0-only
>>   obj-y                                  += init.o
>> +obj-$(CONFIG_ACPI_IOVT)                        += iovt.o
>> diff --git a/drivers/acpi/loongarch/init.c b/drivers/acpi/loongarch/init.c
>> index b11aa5c7d928..e7272ee197c7 100644
>> --- a/drivers/acpi/loongarch/init.c
>> +++ b/drivers/acpi/loongarch/init.c
>> @@ -1,11 +1,16 @@
>>   // SPDX-License-Identifier: GPL-2.0-only
>>
>>   #include <linux/acpi.h>
>> +#include "init.h"
>>
>>   void __init acpi_arch_init(void)
>>   {
>> +       if (IS_ENABLED(CONFIG_ACPI_IOVT))
>> +               acpi_iovt_init();
>>   }
>>
>>   void __init acpi_arch_late_init(void)
>>   {
>> +       if (IS_ENABLED(CONFIG_ACPI_IOVT))
>> +               acpi_iovt_late_init();
>>   }
>> diff --git a/drivers/acpi/loongarch/init.h b/drivers/acpi/loongarch/init.h
>> new file mode 100644
>> index 000000000000..85e5197553ad
>> --- /dev/null
>> +++ b/drivers/acpi/loongarch/init.h
>> @@ -0,0 +1,5 @@
>> +/* SPDX-License-Identifier: GPL-2.0-only */
>> +#include <linux/init.h>
>> +
>> +void __init acpi_iovt_init(void);
>> +void __init acpi_iovt_late_init(void);
>> diff --git a/drivers/acpi/loongarch/iovt.c b/drivers/acpi/loongarch/iovt.c
>> new file mode 100644
>> index 000000000000..fb384664ba78
>> --- /dev/null
>> +++ b/drivers/acpi/loongarch/iovt.c
>> @@ -0,0 +1,219 @@
>> +// SPDX-License-Identifier: GPL-2.0-only
>> +
>> +#include <linux/acpi.h>
>> +#include <linux/pci.h>
>> +#include "init.h"
>> +
>> +struct iovt_device_entry {
>> +       struct list_head list;
>> +       int start_devid;
>> +       int end_devid;
>> +};
>> +
>> +struct iovt_fwnode {
>> +       struct list_head list;
>> +       struct fwnode_handle *fwnode;
>> +       int flag;
>> +       int segment;
>> +       int devid;
>> +       int nid;
>> +       struct list_head ep_list;
>> +};
>> +
>> +/* Root pointer to the mapped IOVT table */
>> +static LIST_HEAD(iovt_fwnode_list);
>> +static DEFINE_SPINLOCK(iovt_fwnode_lock);
>> +
>> +#ifdef CONFIG_PCI
>> +static void __init iovt_enable_acs(struct acpi_iovt_iommu *iommu)
>> +{
>> +       static bool acs_enabled __initdata;
>> +
>> +       if (acs_enabled)
>> +               return;
>> +
>> +       /* IOMMU V1 only supports PCI device management */
>> +       if ((iommu->header.type == ACPI_IOVT_IOMMU_V1) ||
>> +               (iommu->flags & (ACPI_IOVT_PCI_DEVICE | ACPI_IOVT_MAGAGE_BY_SEGMENT))) {
>> +               pci_request_acs();
>> +               acs_enabled = true;
>> +       }
>> +}
>> +#else
>> +static inline void iovt_enable_acs(struct acpi_iovt_iommu *iommu) { }
>> +#endif
>> +
>> +static int __init iovt_get_pci_iommu_fwnode(struct iovt_fwnode *np, u16 segment, u16 bdf)
>> +{
>> +       struct pci_dev *pdev;
>> +       struct fwnode_handle *fwnode;
>> +
>> +       pdev = pci_get_domain_bus_and_slot(segment, PCI_BUS_NUM(bdf), bdf & 0xff);
>> +       if (!pdev) {
>> +               pr_err("No PCI IOMMU found for segment 0x%x bdf 0x%x\n", segment, bdf);
>> +               return -ENODEV;
>> +       }
>> +
>> +       fwnode = dev_fwnode(&pdev->dev);
>> +       if (!fwnode) {
>> +               /*
>> +                * PCI devices aren't necessarily described by ACPI. Create a
>> +                * fwnode so the IOMMU subsystem can identify this device.
>> +                */
>> +               fwnode = acpi_alloc_fwnode_static();
>> +               if (!fwnode) {
>> +                       pci_dev_put(pdev);
>> +                       return -ENOMEM;
>> +               }
>> +               set_primary_fwnode(&pdev->dev, fwnode);
>> +       }
>> +
>> +       np->fwnode = dev_fwnode(&pdev->dev);
>> +       if (np->flag & ACPI_IOVT_PXM_VALID)
>> +               set_dev_node(&pdev->dev, np->nid);
>> +       pci_dev_put(pdev);
>> +       return 0;
>> +}
>> +
>> +static int __init iovt_add_iommu(struct acpi_iovt_iommu *iommu)
>> +{
>> +       struct iovt_fwnode *np;
>> +       struct fwnode_handle *fwnode;
>> +       struct acpi_iovt_device_entry *ep;
>> +       struct iovt_device_entry *entry;
>> +       int i, ret, start_devid;
>> +       bool is_start = false;
>> +
>> +       np = kzalloc_obj(struct iovt_fwnode, GFP_ATOMIC);
>> +       if (WARN_ON(!np))
>> +               return -ENOMEM;
>> +
>> +       INIT_LIST_HEAD(&np->list);
>> +       np->flag = iommu->flags;
>> +       np->segment = iommu->segment;
>> +       if (np->flag & ACPI_IOVT_PXM_VALID)
>> +               np->nid = pxm_to_node(iommu->proximity_domain);
>> +
>> +       if (np->flag & ACPI_IOVT_PCI_DEVICE) {
>> +               np->devid = iommu->device_id;
>> +               ret = iovt_get_pci_iommu_fwnode(np, np->segment, np->devid);
>> +               if (ret) {
>> +                       kfree(np);
>> +                       return ret;
>> +               }
>> +
>> +       } else {
>> +               fwnode = acpi_alloc_fwnode_static();
>> +               if (!fwnode) {
>> +                       kfree(np);
>> +                       return -ENOMEM;
>> +               }
>> +
>> +               np->fwnode = fwnode;
>> +       }
>> +
>> +       /* All devices in the segment are managed by this IOMMU */
>> +       if (np->flag & ACPI_IOVT_MAGAGE_BY_SEGMENT)
>> +               goto skip;
>> +
>> +       INIT_LIST_HEAD(&np->ep_list);
>> +       ep = ACPI_ADD_PTR(struct acpi_iovt_device_entry, iommu, iommu->device_entry_offset);
>> +       for (i = 0; i < iommu->device_entry_num; i++) {
>> +               switch (ep->type) {
>> +               case ACPI_IOVT_DEVICE_ENTRY_START:
>> +                       is_start = true;
>> +                       start_devid = ep->device_id;
>> +                       break;
>> +               case ACPI_IOVT_DEVICE_ENTRY_END:
>> +                       if (!is_start)
>> +                               break;
>> +
>> +                       entry = kzalloc_obj(struct iovt_device_entry, GFP_ATOMIC);
>> +                       if (!entry)
>> +                               return -ENOMEM;
>> +
>> +                       entry->start_devid = start_devid;
>> +                       entry->end_devid = ep->device_id;
>> +                       list_add_tail(&entry->list, &np->ep_list);
>> +                       is_start = false;
>> +                       break;
>> +               case ACPI_IOVT_DEVICE_ENTRY_SINGLE:
>> +                       entry = kzalloc_obj(struct iovt_device_entry, GFP_ATOMIC);
>> +                       if (!entry)
>> +                               return -ENOMEM;
>> +
>> +                       entry->start_devid = ep->device_id;
>> +                       entry->end_devid = ep->device_id;
>> +                       list_add_tail(&entry->list, &np->ep_list);
>> +                       is_start = false;
>> +                       break;
>> +               default:
>> +                       break;
>> +               }
>> +               ep = ACPI_ADD_PTR(struct acpi_iovt_device_entry, ep, ep->length);
>> +       }
>> +
>> +skip:
>> +       spin_lock(&iovt_fwnode_lock);
>> +       list_add_tail(&np->list, &iovt_fwnode_list);
>> +       spin_unlock(&iovt_fwnode_lock);
>> +       return 0;
>> +}
>> +
>> +static void __init iovt_init_devices(struct acpi_table_header *header)
>> +{
>> +       struct acpi_iovt_iommu *iommu;
>> +       struct acpi_table_iovt *iovt;
>> +       int i;
>> +
>> +       /* Get the first IOVT node */
>> +       iovt = (struct acpi_table_iovt *)header;
>> +       iommu = ACPI_ADD_PTR(struct acpi_iovt_iommu, iovt, iovt->iommu_offset);
>> +       for (i = 0; i < iovt->iommu_count; i++) {
>> +               iovt_add_iommu(iommu);
>> +               iommu = ACPI_ADD_PTR(struct acpi_iovt_iommu, iommu, iommu->header.length);
>> +       }
>> +}
>> +
>> +void __init acpi_iovt_init(void)
>> +{
>> +       acpi_status status;
>> +       struct acpi_table_header *hdr;
>> +       struct acpi_table_iovt *iovt;
>> +       struct acpi_iovt_iommu *iommu;
>> +       int i;
>> +
>> +       status = acpi_get_table(ACPI_SIG_IOVT, 0, &hdr);
>> +       if (ACPI_FAILURE(status)) {
>> +               if (status != AE_NOT_FOUND)
>> +                       pr_err("Failed to get table, %s\n", acpi_format_exception(status));
>> +
>> +               return;
>> +       }
>> +
>> +       iovt = (struct acpi_table_iovt *)&hdr;
>> +       iommu = ACPI_ADD_PTR(struct acpi_iovt_iommu, iovt, iovt->iommu_offset);
>> +       for (i = 0; i < iovt->iommu_count; i++) {
>> +               iovt_enable_acs(iommu);
>> +               iommu = ACPI_ADD_PTR(struct acpi_iovt_iommu, iommu, iommu->header.length);
>> +       }
>> +
>> +       acpi_put_table(hdr);
>> +}
>> +
>> +void __init acpi_iovt_late_init(void)
>> +{
>> +       acpi_status status;
>> +       struct acpi_table_header *hdr;
>> +
>> +       status = acpi_get_table(ACPI_SIG_IOVT, 0, &hdr);
>> +       if (ACPI_FAILURE(status)) {
>> +               if (status != AE_NOT_FOUND)
>> +                       pr_err("Failed to get table, %s\n", acpi_format_exception(status));
>> +
>> +               return;
>> +       }
>> +
>> +       iovt_init_devices(hdr);
>> +       acpi_put_table(hdr);
>> +}
>> diff --git a/include/acpi/actbl2.h b/include/acpi/actbl2.h
>> index baef525367b5..acc51a42c3ed 100644
>> --- a/include/acpi/actbl2.h
>> +++ b/include/acpi/actbl2.h
>> @@ -892,6 +892,9 @@ struct acpi_iovt_header {
>>
>>   /* Values for Type field above */
>>
>> +#define ACPI_IOVT_PCI_DEVICE           BIT(0)
>> +#define ACPI_IOVT_PXM_VALID            BIT(1)
>> +#define ACPI_IOVT_MAGAGE_BY_SEGMENT    BIT(2)
>>   enum acpi_iovt_iommu_type {
>>          ACPI_IOVT_IOMMU_V1 = 0x00,
>>          ACPI_IOVT_IOMMU_RESERVED = 0x01 /* 1 and greater are reserved */
>> --
>> 2.39.3
>>


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2 1/4] ACPI: LoongArch: Add acpi_arch_[late]_init()
  2026-07-21 19:10   ` Rafael J. Wysocki (Intel)
@ 2026-07-23 12:47     ` Bibo Mao
  0 siblings, 0 replies; 10+ messages in thread
From: Bibo Mao @ 2026-07-23 12:47 UTC (permalink / raw)
  To: Rafael J. Wysocki (Intel)
  Cc: Huacai Chen, Len Brown, Saket Dumbre, linux-kernel, loongarch,
	linux-acpi, acpica-devel, lixianglai



On 2026/7/22 上午3:10, Rafael J. Wysocki (Intel) wrote:
> On Fri, Jul 17, 2026 at 8:44 AM Bibo Mao <maobibo@loongson.cn> wrote:
>>
>> LoongArch IOMMU scanning flow is similar with virtio-iommu,
>> there is early init and late_init. In early init function, PCI
>> ACS is enabled if there is IOMMU table, and late_init is called
>> after PCI device scanning, where IOVT table scanning function is
>> executed.
>>
>> Here add acpi_arch_init() and acpi_arch_late_init() API on LoongArch,
>> now they are both empty, In the future, IOVT table parsing will be
>> added.
>>
>> Signed-off-by: Bibo Mao <maobibo@loongson.cn>
>> ---
>>   drivers/acpi/Makefile           |  2 +-
>>   drivers/acpi/bus.c              |  2 ++
>>   drivers/acpi/loongarch/Makefile |  2 ++
>>   drivers/acpi/loongarch/init.c   | 11 +++++++++++
>>   include/linux/acpi.h            |  1 +
>>   5 files changed, 17 insertions(+), 1 deletion(-)
>>   create mode 100644 drivers/acpi/loongarch/Makefile
>>   create mode 100644 drivers/acpi/loongarch/init.c
>>
>> diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
>> index d1b0affb844f..91584a3c1e01 100644
>> --- a/drivers/acpi/Makefile
>> +++ b/drivers/acpi/Makefile
>> @@ -131,6 +131,6 @@ obj-y                               += dptf/
>>   obj-$(CONFIG_ARM64)            += arm64/
>>
>>   obj-$(CONFIG_ACPI_VIOT)                += viot.o
>> -
>> +obj-$(CONFIG_LOONGARCH)                += loongarch/
>>   obj-$(CONFIG_RISCV)            += riscv/
>>   obj-$(CONFIG_X86)              += x86/
>> diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
>> index a30a904f6535..5f6924b9e29d 100644
>> --- a/drivers/acpi/bus.c
>> +++ b/drivers/acpi/bus.c
>> @@ -1571,6 +1571,7 @@ struct kobject *acpi_kobj;
>>   EXPORT_SYMBOL_GPL(acpi_kobj);
>>
>>   void __weak __init acpi_arch_init(void) { }
>> +void __weak __init acpi_arch_late_init(void) { }
>>
>>   static int __init acpi_init(void)
>>   {
>> @@ -1609,6 +1610,7 @@ static int __init acpi_init(void)
>>          acpi_wakeup_device_init();
>>          acpi_debugger_init();
>>          acpi_setup_sb_notify_handler();
>> +       acpi_arch_late_init();
>>          acpi_viot_init();
>>          return 0;
>>   }
>> diff --git a/drivers/acpi/loongarch/Makefile b/drivers/acpi/loongarch/Makefile
>> new file mode 100644
>> index 000000000000..d3764139dfaf
>> --- /dev/null
>> +++ b/drivers/acpi/loongarch/Makefile
>> @@ -0,0 +1,2 @@
>> +# SPDX-License-Identifier: GPL-2.0-only
>> +obj-y                                  += init.o
>> diff --git a/drivers/acpi/loongarch/init.c b/drivers/acpi/loongarch/init.c
>> new file mode 100644
>> index 000000000000..b11aa5c7d928
>> --- /dev/null
>> +++ b/drivers/acpi/loongarch/init.c
>> @@ -0,0 +1,11 @@
>> +// SPDX-License-Identifier: GPL-2.0-only
>> +
>> +#include <linux/acpi.h>
>> +
>> +void __init acpi_arch_init(void)
>> +{
>> +}
>> +
>> +void __init acpi_arch_late_init(void)
>> +{
>> +}
>> diff --git a/include/linux/acpi.h b/include/linux/acpi.h
>> index 60ab50cb8930..c6a180341c2d 100644
>> --- a/include/linux/acpi.h
>> +++ b/include/linux/acpi.h
>> @@ -1617,6 +1617,7 @@ static inline int acpi_pptt_get_cpumask_from_cache_id(u32 cache_id,
>>   #endif
>>
>>   void acpi_arch_init(void);
>> +void acpi_arch_late_init(void);
>>
>>   #ifdef CONFIG_ACPI_PCC
>>   void acpi_init_pcc(void);
>> --
> 
> Please fold this one into the patch in which the new function is actually used.
Hi Rafael,

Thanks for reviewing my patch.

yeap, will fold this one into the patch where it is actually used.

Regards
Bibo Mao
> 
> Thanks!
> 


^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2026-07-23 12:47 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-07-17  6:37 [PATCH v2 0/4] ACPI: LoongArch: Add IOVT table support Bibo Mao
2026-07-17  6:37 ` [PATCH v2 1/4] ACPI: LoongArch: Add acpi_arch_[late]_init() Bibo Mao
2026-07-21 19:10   ` Rafael J. Wysocki (Intel)
2026-07-23 12:47     ` Bibo Mao
2026-07-17  6:37 ` [PATCH v2 2/4] ACPI: LoongArch: Add IOVT device entry table scanning Bibo Mao
2026-07-21 19:09   ` Rafael J. Wysocki (Intel)
2026-07-23 12:44     ` Bibo Mao
2026-07-17  6:37 ` [PATCH v2 3/4] ACPI: scan: Add support for LoongArch in acpi_iommu_configure_id() Bibo Mao
2026-07-21 19:07   ` Rafael J. Wysocki (Intel)
2026-07-17  6:37 ` [PATCH v2 4/4] MAINTAINERS: Add entry for drivers/acpi/loongarch Bibo Mao

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®