Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/2] drivers/perf: hisi: Updates for HiSilicon uncore PMUs
From: Yushan Wang @ 2026-04-23 15:29 UTC (permalink / raw)
  To: will, mark.rutland, robin.murphy, linux-arm-kernel, linux-kernel
  Cc: fanghao11, linuxarm, liuyonglong, prime.zeng, wangzhou1,
	wangyushan12

This patchset added support of ITS PMU, and new version of MN PMU.

ITS PMU supports counting number and latency of interrupts by catagory,
and statistics of micro-ops of ITS.

The new version of MN PMU added cycles event, to be used for MN metric
computing.

Yifan Wu (1):
  drivers/perf: hisi: Add new function for HiSilicon MN PMU driver

Yushan Wang (1):
  drivers/perf: hisi: Support uncore ITS PMU

 Documentation/admin-guide/perf/hisi-pmu.rst  |   6 +
 drivers/perf/hisilicon/Makefile              |   2 +-
 drivers/perf/hisilicon/hisi_uncore_its_pmu.c | 365 +++++++++++++++++++
 drivers/perf/hisilicon/hisi_uncore_mn_pmu.c  |  61 +++-
 4 files changed, 427 insertions(+), 7 deletions(-)
 create mode 100644 drivers/perf/hisilicon/hisi_uncore_its_pmu.c

-- 
2.33.0



^ permalink raw reply

* [PATCH 2/2] drivers/perf: hisi: Add new function for HiSilicon MN PMU driver
From: Yushan Wang @ 2026-04-23 15:29 UTC (permalink / raw)
  To: will, mark.rutland, robin.murphy, linux-arm-kernel, linux-kernel
  Cc: fanghao11, linuxarm, liuyonglong, prime.zeng, wangzhou1,
	wangyushan12
In-Reply-To: <20260423152959.1458563-1-wangyushan12@huawei.com>

From: Yifan Wu <wuyifan50@huawei.com>

MN (Miscellaneous Node) is a hybrid node in ARM CHI. The MN PMU driver
using the HiSilicon uncore PMU framework.

On HiSilicon HIP13 platform, cycle event is supported on MN PMU. The
cycle event is exposed directly in driver and some variables shall be
added suffix to distinguish the version.

Signed-off-by: Yifan Wu <wuyifan50@huawei.com>
Signed-off-by: Yushan Wang <wangyushan12@huawei.com>
---
 drivers/perf/hisilicon/hisi_uncore_mn_pmu.c | 61 +++++++++++++++++++--
 1 file changed, 55 insertions(+), 6 deletions(-)

diff --git a/drivers/perf/hisilicon/hisi_uncore_mn_pmu.c b/drivers/perf/hisilicon/hisi_uncore_mn_pmu.c
index 4df4eebe243e..cdd5a1591408 100644
--- a/drivers/perf/hisilicon/hisi_uncore_mn_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_mn_pmu.c
@@ -192,7 +192,7 @@ static const struct attribute_group hisi_mn_pmu_format_group = {
 	.attrs = hisi_mn_pmu_format_attr,
 };
 
-static struct attribute *hisi_mn_pmu_events_attr[] = {
+static struct attribute *hisi_mn_pmu_events_attr_v1[] = {
 	HISI_PMU_EVENT_ATTR(req_eobarrier_num,		0x00),
 	HISI_PMU_EVENT_ATTR(req_ecbarrier_num,		0x01),
 	HISI_PMU_EVENT_ATTR(req_dvmop_num,		0x02),
@@ -219,14 +219,55 @@ static struct attribute *hisi_mn_pmu_events_attr[] = {
 	NULL
 };
 
-static const struct attribute_group hisi_mn_pmu_events_group = {
+static const struct attribute_group hisi_mn_pmu_events_group_v1 = {
 	.name = "events",
-	.attrs = hisi_mn_pmu_events_attr,
+	.attrs = hisi_mn_pmu_events_attr_v1,
 };
 
-static const struct attribute_group *hisi_mn_pmu_attr_groups[] = {
+static const struct attribute_group *hisi_mn_pmu_attr_groups_v1[] = {
 	&hisi_mn_pmu_format_group,
-	&hisi_mn_pmu_events_group,
+	&hisi_mn_pmu_events_group_v1,
+	&hisi_pmu_cpumask_attr_group,
+	&hisi_pmu_identifier_group,
+	NULL
+};
+
+static struct attribute *hisi_mn_pmu_events_attr_v2[] = {
+	HISI_PMU_EVENT_ATTR(req_eobarrier_num,		0x00),
+	HISI_PMU_EVENT_ATTR(req_ecbarrier_num,		0x01),
+	HISI_PMU_EVENT_ATTR(req_dvmop_num,		0x02),
+	HISI_PMU_EVENT_ATTR(req_dvmsync_num,		0x03),
+	HISI_PMU_EVENT_ATTR(req_retry_num,		0x04),
+	HISI_PMU_EVENT_ATTR(req_writenosnp_num,		0x05),
+	HISI_PMU_EVENT_ATTR(req_readnosnp_num,		0x06),
+	HISI_PMU_EVENT_ATTR(snp_dvm_num,		0x07),
+	HISI_PMU_EVENT_ATTR(snp_dvmsync_num,		0x08),
+	HISI_PMU_EVENT_ATTR(l3t_req_dvm_num,		0x09),
+	HISI_PMU_EVENT_ATTR(l3t_req_dvmsync_num,	0x0A),
+	HISI_PMU_EVENT_ATTR(mn_req_dvm_num,		0x0B),
+	HISI_PMU_EVENT_ATTR(mn_req_dvmsync_num,		0x0C),
+	HISI_PMU_EVENT_ATTR(pa_req_dvm_num,		0x0D),
+	HISI_PMU_EVENT_ATTR(pa_req_dvmsync_num,		0x0E),
+	HISI_PMU_EVENT_ATTR(cycles,					0x0F),
+	HISI_PMU_EVENT_ATTR(snp_dvm_latency,		0x80),
+	HISI_PMU_EVENT_ATTR(snp_dvmsync_latency,	0x81),
+	HISI_PMU_EVENT_ATTR(l3t_req_dvm_latency,	0x82),
+	HISI_PMU_EVENT_ATTR(l3t_req_dvmsync_latency,	0x83),
+	HISI_PMU_EVENT_ATTR(mn_req_dvm_latency,		0x84),
+	HISI_PMU_EVENT_ATTR(mn_req_dvmsync_latency,	0x85),
+	HISI_PMU_EVENT_ATTR(pa_req_dvm_latency,		0x86),
+	HISI_PMU_EVENT_ATTR(pa_req_dvmsync_latency,	0x87),
+	NULL
+};
+
+static const struct attribute_group hisi_mn_pmu_events_group_v2 = {
+	.name = "events",
+	.attrs = hisi_mn_pmu_events_attr_v2,
+};
+
+static const struct attribute_group *hisi_mn_pmu_attr_groups_v2[] = {
+	&hisi_mn_pmu_format_group,
+	&hisi_mn_pmu_events_group_v2,
 	&hisi_pmu_cpumask_attr_group,
 	&hisi_pmu_identifier_group,
 	NULL
@@ -351,7 +392,14 @@ static struct hisi_mn_pmu_regs hisi_mn_v1_pmu_regs = {
 };
 
 static const struct hisi_pmu_dev_info hisi_mn_v1 = {
-	.attr_groups = hisi_mn_pmu_attr_groups,
+	.attr_groups = hisi_mn_pmu_attr_groups_v1,
+	.counter_bits = 48,
+	.check_event = HISI_MN_EVTYPE_MASK,
+	.private = &hisi_mn_v1_pmu_regs,
+};
+
+static const struct hisi_pmu_dev_info hisi_mn_v2 = {
+	.attr_groups = hisi_mn_pmu_attr_groups_v2,
 	.counter_bits = 48,
 	.check_event = HISI_MN_EVTYPE_MASK,
 	.private = &hisi_mn_v1_pmu_regs,
@@ -359,6 +407,7 @@ static const struct hisi_pmu_dev_info hisi_mn_v1 = {
 
 static const struct acpi_device_id hisi_mn_pmu_acpi_match[] = {
 	{ "HISI0222", (kernel_ulong_t) &hisi_mn_v1 },
+	{ "HISI0224", (kernel_ulong_t) &hisi_mn_v2 },
 	{ }
 };
 MODULE_DEVICE_TABLE(acpi, hisi_mn_pmu_acpi_match);
-- 
2.33.0



^ permalink raw reply related

* [PATCH 1/2] drivers/perf: hisi: Support uncore ITS PMU
From: Yushan Wang @ 2026-04-23 15:29 UTC (permalink / raw)
  To: will, mark.rutland, robin.murphy, linux-arm-kernel, linux-kernel
  Cc: fanghao11, linuxarm, liuyonglong, prime.zeng, wangzhou1,
	wangyushan12
In-Reply-To: <20260423152959.1458563-1-wangyushan12@huawei.com>

Support uncore ITS PMU, which provides the capability of counting
the number of interrupts routed to ITS by interrupt catagories, and the
latency. It also supports collecting statistics of micro-ops of ITS.

The driver adapts to HiSilicon uncore PMU framework. It does not support
overflow interruption, which is the same as NoC PMU, so a few dummy
functions or handling interrupts are left empty.

Signed-off-by: Yushan Wang <wangyushan12@huawei.com>
---
 Documentation/admin-guide/perf/hisi-pmu.rst  |   6 +
 drivers/perf/hisilicon/Makefile              |   2 +-
 drivers/perf/hisilicon/hisi_uncore_its_pmu.c | 365 +++++++++++++++++++
 3 files changed, 372 insertions(+), 1 deletion(-)
 create mode 100644 drivers/perf/hisilicon/hisi_uncore_its_pmu.c

diff --git a/Documentation/admin-guide/perf/hisi-pmu.rst b/Documentation/admin-guide/perf/hisi-pmu.rst
index d56b2d690709..66ce9f2e6fe3 100644
--- a/Documentation/admin-guide/perf/hisi-pmu.rst
+++ b/Documentation/admin-guide/perf/hisi-pmu.rst
@@ -128,6 +128,12 @@ channel with this option. The current supported channels are as follows:
 7. tt_en: NoC PMU supports counting only transactions that have tracetag set
 if this option is set. See the 2nd list for more information about tracetag.
 
+8. int_id: ITS PMU supports filtering by interrupt id, which is defined by
+   hardware. Interrupt id takes up to 32 bits, and can be devided into 2 parts:
+
+- Upper 16 bits: DeviceID if counting LPI, PEID if counting SGI/PPI.
+- Lower 16 bits: EventID if counting LPI, IntID if counting SGI/PPI.
+
 For HiSilicon uncore PMU v3 whose identifier is 0x40, some uncore PMUs are
 further divided into parts for finer granularity of tracing, each part has its
 own dedicated PMU, and all such PMUs together cover the monitoring job of events
diff --git a/drivers/perf/hisilicon/Makefile b/drivers/perf/hisilicon/Makefile
index 186be3d02238..5f28cfdb8a72 100644
--- a/drivers/perf/hisilicon/Makefile
+++ b/drivers/perf/hisilicon/Makefile
@@ -2,7 +2,7 @@
 obj-$(CONFIG_HISI_PMU) += hisi_uncore_pmu.o hisi_uncore_l3c_pmu.o \
 			  hisi_uncore_hha_pmu.o hisi_uncore_ddrc_pmu.o hisi_uncore_sllc_pmu.o \
 			  hisi_uncore_pa_pmu.o hisi_uncore_cpa_pmu.o hisi_uncore_uc_pmu.o \
-			  hisi_uncore_noc_pmu.o hisi_uncore_mn_pmu.o
+			  hisi_uncore_noc_pmu.o hisi_uncore_mn_pmu.o hisi_uncore_its_pmu.o
 
 obj-$(CONFIG_HISI_PCIE_PMU) += hisi_pcie_pmu.o
 obj-$(CONFIG_HNS3_PMU) += hns3_pmu.o
diff --git a/drivers/perf/hisilicon/hisi_uncore_its_pmu.c b/drivers/perf/hisilicon/hisi_uncore_its_pmu.c
new file mode 100644
index 000000000000..608c298b8944
--- /dev/null
+++ b/drivers/perf/hisilicon/hisi_uncore_its_pmu.c
@@ -0,0 +1,365 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Driver for HiSilicon Uncore ITS PMU device
+ *
+ * Copyright (c) 2026 HiSilicon Technologies Co., Ltd.
+ * Author: Yushan Wang <wangyushan12@huawei.com>
+ */
+#include <linux/bitops.h>
+#include <linux/cpuhotplug.h>
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/property.h>
+#include <linux/sysfs.h>
+
+#include "hisi_uncore_pmu.h"
+
+#define ITS_PMU_VERSION			0x21000
+#define ITS_PMU_GLOBAL_CTRL		0x21004
+#define ITS_PMU_GLOBAL_CTRL_PMU_EN	BIT(0)
+#define ITS_PMU_COUNTER_CTRL		0x21008
+#define ITS_PMU_EVENT_CTRL		0x2100c
+#define ITS_PMU_COUNTER0		0x21010
+
+#define ITS_PMU_INT_ID_MASK		0x20008
+#define ITS_PMU_INT_ID_CTRL		0x20084
+
+#define ITS_PMU_NR_COUNTERS		4
+
+#define ITS_PMU_EVENT_CNTRn(cntr0, n)	((cntr0) + 8 * (n))
+#define ITS_PMU_CNTR_CTRL_MASK(n)	GENMASK(8 * ((n) + 1) - 1, 8 * (n))
+#define ITS_PMU_CNTR_EVENT_CFG(n, e)	((e) << ((n) * 8))
+#define ITS_PMU_EVENT_CTRL_TYPE		GENMASK(12, 0)
+
+HISI_PMU_EVENT_ATTR_EXTRACTOR(int_id, config1, 31, 0);
+
+/* Dynamic CPU hotplug state used by this PMU driver */
+static enum cpuhp_state hisi_its_pmu_cpuhp_state;
+
+struct hisi_its_pmu_regs {
+	u32 version;
+	u32 pmu_ctrl;
+	u32 event_ctrl0;
+	u32 event_cntr0;
+	u32 cntr_ctrl;
+};
+
+static void hisi_its_pmu_write_evtype(struct hisi_pmu *its_pmu, int idx, u32 type)
+{
+	struct hisi_its_pmu_regs *reg_info = its_pmu->dev_info->private;
+	u32 reg;
+
+	reg = readl(its_pmu->base + reg_info->event_ctrl0);
+	reg &= ~ITS_PMU_CNTR_CTRL_MASK(idx);
+	reg |= ITS_PMU_CNTR_EVENT_CFG(idx, type);
+	writel(reg, its_pmu->base + reg_info->event_ctrl0);
+}
+
+static u64 hisi_its_pmu_read_counter(struct hisi_pmu *its_pmu,
+				     struct hw_perf_event *hwc)
+{
+	struct hisi_its_pmu_regs *reg_info = its_pmu->dev_info->private;
+
+	return readq(its_pmu->base + ITS_PMU_EVENT_CNTRn(reg_info->event_cntr0, hwc->idx));
+}
+
+static void hisi_its_pmu_write_counter(struct hisi_pmu *its_pmu,
+				       struct hw_perf_event *hwc, u64 val)
+{
+	struct hisi_its_pmu_regs *reg_info = its_pmu->dev_info->private;
+
+	writeq(val, its_pmu->base + ITS_PMU_EVENT_CNTRn(reg_info->event_cntr0, hwc->idx));
+}
+
+static void hisi_its_pmu_enable_counter(struct hisi_pmu *its_pmu,
+					struct hw_perf_event *hwc)
+{
+	struct hisi_its_pmu_regs *reg_info = its_pmu->dev_info->private;
+	u32 reg;
+
+	reg = readl(its_pmu->base + reg_info->cntr_ctrl);
+	reg |= BIT(hwc->idx);
+	writel(reg, its_pmu->base + reg_info->cntr_ctrl);
+}
+
+static void hisi_its_pmu_disable_counter(struct hisi_pmu *its_pmu,
+					 struct hw_perf_event *hwc)
+{
+	struct hisi_its_pmu_regs *reg_info = its_pmu->dev_info->private;
+	u32 reg;
+
+	reg = readl(its_pmu->base + reg_info->cntr_ctrl);
+	reg &= ~BIT(hwc->idx);
+	writel(reg, its_pmu->base + reg_info->cntr_ctrl);
+}
+
+static void hisi_its_pmu_enable_counter_int(struct hisi_pmu *its_pmu,
+					    struct hw_perf_event *hwc)
+{
+	/* We don't support interrupt, so a stub here. */
+}
+
+static void hisi_its_pmu_disable_counter_int(struct hisi_pmu *its_pmu,
+					     struct hw_perf_event *hwc)
+{
+}
+
+static void hisi_its_pmu_start_counters(struct hisi_pmu *its_pmu)
+{
+	struct hisi_its_pmu_regs *reg_info = its_pmu->dev_info->private;
+	u32 reg;
+
+	reg = readl(its_pmu->base + reg_info->pmu_ctrl);
+	reg |= ITS_PMU_GLOBAL_CTRL_PMU_EN;
+	writel(reg, its_pmu->base + reg_info->pmu_ctrl);
+}
+
+static void hisi_its_pmu_stop_counters(struct hisi_pmu *its_pmu)
+{
+	struct hisi_its_pmu_regs *reg_info = its_pmu->dev_info->private;
+	u32 reg;
+
+	reg = readl(its_pmu->base + reg_info->pmu_ctrl);
+	reg &= ~ITS_PMU_GLOBAL_CTRL_PMU_EN;
+	writel(reg, its_pmu->base + reg_info->pmu_ctrl);
+}
+
+static void hisi_its_pmu_enable_filter(struct perf_event *event)
+{
+	struct hisi_pmu *its_pmu = to_hisi_pmu(event->pmu);
+	u32 int_id = hisi_get_int_id(event);
+	u32 reg = int_id ? 0 : -1U;
+
+	if (int_id)
+		writel(int_id, its_pmu->base + ITS_PMU_INT_ID_CTRL);
+
+	writel(reg, its_pmu->base + ITS_PMU_INT_ID_MASK);
+}
+
+static void hisi_its_pmu_disable_filter(struct perf_event *event)
+{
+	struct hisi_pmu *its_pmu = to_hisi_pmu(event->pmu);
+	u32 int_id = hisi_get_int_id(event);
+
+	if (bitmap_weight(its_pmu->pmu_events.used_mask, its_pmu->num_counters) > 1)
+		return;
+
+	if (int_id) {
+		writel(0, its_pmu->base + ITS_PMU_INT_ID_CTRL);
+		writel(-1U, its_pmu->base + ITS_PMU_INT_ID_MASK);
+	}
+}
+
+static const struct hisi_uncore_ops hisi_uncore_its_ops = {
+	.write_evtype		= hisi_its_pmu_write_evtype,
+	.get_event_idx		= hisi_uncore_pmu_get_event_idx,
+	.read_counter		= hisi_its_pmu_read_counter,
+	.write_counter		= hisi_its_pmu_write_counter,
+	.enable_counter		= hisi_its_pmu_enable_counter,
+	.disable_counter	= hisi_its_pmu_disable_counter,
+	.enable_counter_int	= hisi_its_pmu_enable_counter_int,
+	.disable_counter_int	= hisi_its_pmu_disable_counter_int,
+	.start_counters		= hisi_its_pmu_start_counters,
+	.stop_counters		= hisi_its_pmu_stop_counters,
+	.enable_filter		= hisi_its_pmu_enable_filter,
+	.disable_filter		= hisi_its_pmu_disable_filter,
+};
+
+static struct attribute *hisi_its_pmu_format_attrs[] = {
+	HISI_PMU_FORMAT_ATTR(event, "config:0-16"),
+	HISI_PMU_FORMAT_ATTR(int_id, "config1:0-31"),
+	NULL
+};
+
+static const struct attribute_group hisi_its_pmu_format_group = {
+	.name = "format",
+	.attrs = hisi_its_pmu_format_attrs,
+};
+
+static struct attribute *hisi_its_pmu_events_attrs[] = {
+	HISI_PMU_EVENT_ATTR(lpi_num, 0xc0),
+	HISI_PMU_EVENT_ATTR(lpi_time, 0x80),
+	HISI_PMU_EVENT_ATTR(sgi_num, 0xc1),
+	HISI_PMU_EVENT_ATTR(sgi_time, 0x81),
+	HISI_PMU_EVENT_ATTR(ppi_num, 0xc2),
+	HISI_PMU_EVENT_ATTR(ppi_time, 0x82),
+	HISI_PMU_EVENT_ATTR(sl3_lpi_num, 0xc3),
+	HISI_PMU_EVENT_ATTR(sl3_sgi_num, 0xc4),
+	HISI_PMU_EVENT_ATTR(sl3_ppi_num, 0xc5),
+	HISI_PMU_EVENT_ATTR(sl0_ddr_read, 0xc9),
+	HISI_PMU_EVENT_ATTR(sl0_ddr_time, 0x89),
+	HISI_PMU_EVENT_ATTR(sl1_ddr_read, 0xca),
+	HISI_PMU_EVENT_ATTR(sl1_ddr_time, 0x8a),
+	HISI_PMU_EVENT_ATTR(sl2_ddr_read, 0xcb),
+	HISI_PMU_EVENT_ATTR(sl2_ddr_time, 0x8b),
+	HISI_PMU_EVENT_ATTR(cycles, 0xcc),
+	NULL
+};
+
+static const struct attribute_group hisi_its_pmu_events_group = {
+	.name = "events",
+	.attrs = hisi_its_pmu_events_attrs,
+};
+
+static const struct attribute_group *hisi_its_pmu_attr_groups[] = {
+	&hisi_its_pmu_format_group,
+	&hisi_its_pmu_events_group,
+	&hisi_pmu_cpumask_attr_group,
+	&hisi_pmu_identifier_group,
+	NULL
+};
+
+static int hisi_its_pmu_dev_init(struct platform_device *pdev, struct hisi_pmu *its_pmu)
+{
+	struct hisi_its_pmu_regs *reg_info;
+
+	hisi_uncore_pmu_init_topology(its_pmu, &pdev->dev);
+
+	if (its_pmu->topo.scl_id < 0)
+		return dev_err_probe(&pdev->dev, -EINVAL, "failed to get scl-id\n");
+
+	if (its_pmu->topo.index_id < 0)
+		return dev_err_probe(&pdev->dev, -EINVAL, "failed to get idx-id\n");
+
+	its_pmu->base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(its_pmu->base))
+		return dev_err_probe(&pdev->dev, PTR_ERR(its_pmu->base),
+				     "fail to remap io memory\n");
+
+	its_pmu->dev_info = device_get_match_data(&pdev->dev);
+	if (!its_pmu->dev_info)
+		return -ENODEV;
+
+	its_pmu->pmu_events.attr_groups = its_pmu->dev_info->attr_groups;
+	its_pmu->counter_bits = its_pmu->dev_info->counter_bits;
+	its_pmu->check_event = its_pmu->dev_info->check_event;
+	its_pmu->num_counters = ITS_PMU_NR_COUNTERS;
+	its_pmu->ops = &hisi_uncore_its_ops;
+	its_pmu->dev = &pdev->dev;
+	its_pmu->on_cpu = -1;
+
+	reg_info = its_pmu->dev_info->private;
+	its_pmu->identifier = readl(its_pmu->base + reg_info->version);
+
+	return 0;
+}
+
+static void hisi_its_pmu_remove_cpuhp_instance(void *hotplug_node)
+{
+	cpuhp_state_remove_instance_nocalls(hisi_its_pmu_cpuhp_state, hotplug_node);
+}
+
+static void hisi_its_pmu_unregister_pmu(void *pmu)
+{
+	perf_pmu_unregister(pmu);
+}
+
+static int hisi_its_pmu_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct hisi_pmu *its_pmu;
+	char *name;
+	int ret;
+
+	its_pmu = devm_kzalloc(dev, sizeof(*its_pmu), GFP_KERNEL);
+	if (!its_pmu)
+		return -ENOMEM;
+
+	/*
+	 * HiSilicon Uncore PMU framework needs to get common hisi_pmu device
+	 * from device's drvdata.
+	 */
+	platform_set_drvdata(pdev, its_pmu);
+
+	ret = hisi_its_pmu_dev_init(pdev, its_pmu);
+	if (ret)
+		return ret;
+
+	ret = cpuhp_state_add_instance(hisi_its_pmu_cpuhp_state, &its_pmu->node);
+	if (ret)
+		return dev_err_probe(dev, ret, "Fail to register cpuhp instance\n");
+
+	ret = devm_add_action_or_reset(dev, hisi_its_pmu_remove_cpuhp_instance,
+				       &its_pmu->node);
+	if (ret)
+		return ret;
+
+	hisi_pmu_init(its_pmu, THIS_MODULE);
+
+	name = devm_kasprintf(dev, GFP_KERNEL, "hisi_scl%d_its%d",
+			      its_pmu->topo.scl_id, its_pmu->topo.index_id);
+	if (!name)
+		return -ENOMEM;
+
+	ret = perf_pmu_register(&its_pmu->pmu, name, -1);
+	if (ret)
+		return dev_err_probe(dev, ret, "Fail to register PMU\n");
+
+	return devm_add_action_or_reset(dev, hisi_its_pmu_unregister_pmu,
+					&its_pmu->pmu);
+}
+
+static struct hisi_its_pmu_regs hisi_its_v1_pmu_regs = {
+	.version = ITS_PMU_VERSION,
+	.pmu_ctrl = ITS_PMU_GLOBAL_CTRL,
+	.event_ctrl0 = ITS_PMU_EVENT_CTRL,
+	.event_cntr0 = ITS_PMU_COUNTER0,
+	.cntr_ctrl = ITS_PMU_COUNTER_CTRL,
+};
+
+static const struct hisi_pmu_dev_info hisi_its_v1 = {
+	.attr_groups = hisi_its_pmu_attr_groups,
+	.counter_bits = 48,
+	.check_event = ITS_PMU_EVENT_CTRL_TYPE,
+	.private = &hisi_its_v1_pmu_regs,
+};
+
+static const struct acpi_device_id hisi_its_pmu_ids[] = {
+	{ "HISI0591", (kernel_ulong_t) &hisi_its_v1 },
+	{ }
+};
+MODULE_DEVICE_TABLE(acpi, hisi_its_pmu_ids);
+
+static struct platform_driver hisi_its_pmu_driver = {
+	.driver = {
+		.name = "hisi_its_pmu",
+		.acpi_match_table = hisi_its_pmu_ids,
+		.suppress_bind_attrs = true,
+	},
+	.probe = hisi_its_pmu_probe,
+};
+
+static int __init hisi_its_pmu_module_init(void)
+{
+	int ret = cpuhp_setup_state_multi(CPUHP_AP_ONLINE_DYN,
+					  "perf/hisi/its:online",
+					  hisi_uncore_pmu_online_cpu,
+					  hisi_uncore_pmu_offline_cpu);
+	if (ret < 0) {
+		pr_err("hisi_its_pmu: Fail to setup cpuhp callbacks, ret = %d\n", ret);
+		return ret;
+	}
+	hisi_its_pmu_cpuhp_state = ret;
+
+	ret = platform_driver_register(&hisi_its_pmu_driver);
+	if (ret)
+		cpuhp_remove_multi_state(hisi_its_pmu_cpuhp_state);
+
+	return ret;
+}
+module_init(hisi_its_pmu_module_init);
+
+static void __exit hisi_its_pmu_module_exit(void)
+{
+	platform_driver_unregister(&hisi_its_pmu_driver);
+	cpuhp_remove_multi_state(hisi_its_pmu_cpuhp_state);
+}
+module_exit(hisi_its_pmu_module_exit);
+
+MODULE_IMPORT_NS("HISI_PMU");
+MODULE_DESCRIPTION("HiSilicon SoC Uncore ITS PMU driver");
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Yushan Wang <wangyushan12@huawei.com>");
-- 
2.33.0



^ permalink raw reply related

* Re: [PATCH v3 06/11] iommu: Defer __iommu_group_free_device() to be outside group->mutex
From: Nicolin Chen @ 2026-04-23 15:47 UTC (permalink / raw)
  To: Baolu Lu
  Cc: Will Deacon, Robin Murphy, Joerg Roedel, Bjorn Helgaas,
	Jason Gunthorpe, Rafael J . Wysocki, Len Brown,
	Pranjal Shrivastava, Mostafa Saleh, Kevin Tian, linux-arm-kernel,
	iommu, linux-kernel, linux-acpi, linux-pci, vsethi, Shuai Xue
In-Reply-To: <3570e178-f887-45c9-a251-e089915cfbd9@linux.intel.com>

On Thu, Apr 23, 2026 at 03:55:02PM +0800, Baolu Lu wrote:
> On 4/17/26 07:28, Nicolin Chen wrote:
> > +static void __iommu_group_empty_assert_owner_cnt(struct iommu_group *group)
> > +{
> > +	lockdep_assert_held(&group->mutex);
> > +	/*
> > +	 * If the group has become empty then ownership must have been
> > +	 * released, and the current domain must be set back to NULL or
> > +	 * the default domain.
> > +	 */
> 
> Nit: this comment doesn't quite match the following code. The code
> doesn't check "group->domain != NULL". Or perhaps in that case,
> group->default_domain must be NULL?

This is the original patch from Jason:
https://lore.kernel.org/r/4-v3-328044aa278c+45e49-iommu_probe_jgg@nvidia.com

I kept the comments as-is, though It might be slightly confusing?

I think it means:
If group->default_domain == NULL, it does check "set back to NULL".
If group->default_domain != NULL, it then checks "default domain".

Maybe it could be "must be set back to the default domain (which
itself can be NULL"?

> Furthermore, if a device is currently quarantined, group->domain will be
> the blocking_domain. If that quarantined device is then hot-removed and
> happens to be the last device in the group, will this WARN_ON trigger
> unnecessarily?

If a device is quarantined, its group->domain is retained to the
previously attached domain. Its blocking state is logged in the
gdev->blocked flag. So, I think it can pass the test.

Thanks
Nicolin


^ permalink raw reply

* [PATCH v4 1/8] dt-bindings: thermal: amlogic: Add support for T7
From: Ronald Claveau via B4 Relay @ 2026-04-23 16:07 UTC (permalink / raw)
  To: Guillaume La Roque, Rafael J. Wysocki, Daniel Lezcano, Zhang Rui,
	Lukasz Luba, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Neil Armstrong, Kevin Hilman, Jerome Brunet, Martin Blumenstingl
  Cc: linux-pm, linux-amlogic, devicetree, linux-kernel,
	linux-arm-kernel, Ronald Claveau, Conor Dooley
In-Reply-To: <20260423-add-thermal-t7-vim4-v4-0-d4c1528d5044@aliel.fr>

From: Ronald Claveau <linux-kernel-dev@aliel.fr>

Add the amlogic,t7-thermal compatible for the Amlogic T7 thermal sensor.

Unlike existing variants which use a phandle to the ao-secure syscon,
the T7 relies on a secure monitor interface described by a phandle and
a sensor index argument.

The T7 integrates multiple thermal sensors, all accessed through the
same SMC call. The sensor index argument is required to identify which
sensor's calibration data the secure monitor should return, as a single
SM_THERMAL_CALIB_READ command serves all of them.

Introduce the amlogic,secure-monitor property as a phandle-array and
make amlogic,ao-secure or amlogic,secure-monitor conditionally required
depending on the compatible.

Acked-by: Conor Dooley <conor.dooley@microchip.com>
Signed-off-by: Ronald Claveau <linux-kernel-dev@aliel.fr>
---
 .../bindings/thermal/amlogic,thermal.yaml          | 37 ++++++++++++++++++++--
 1 file changed, 35 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/thermal/amlogic,thermal.yaml b/Documentation/devicetree/bindings/thermal/amlogic,thermal.yaml
index 70b273271754b..e28612510d679 100644
--- a/Documentation/devicetree/bindings/thermal/amlogic,thermal.yaml
+++ b/Documentation/devicetree/bindings/thermal/amlogic,thermal.yaml
@@ -21,7 +21,9 @@ properties:
               - amlogic,g12a-cpu-thermal
               - amlogic,g12a-ddr-thermal
           - const: amlogic,g12a-thermal
-      - const: amlogic,a1-cpu-thermal
+      - enum:
+          - amlogic,a1-cpu-thermal
+          - amlogic,t7-thermal
 
   reg:
     maxItems: 1
@@ -42,12 +44,34 @@ properties:
   '#thermal-sensor-cells':
     const: 0
 
+  amlogic,secure-monitor:
+    description: phandle to the secure monitor
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    items:
+      - items:
+          - description: phandle to the secure monitor
+          - description: sensor index to get specific calibration data
+
 required:
   - compatible
   - reg
   - interrupts
   - clocks
-  - amlogic,ao-secure
+
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - amlogic,a1-cpu-thermal
+              - amlogic,g12a-thermal
+    then:
+      required:
+        - amlogic,ao-secure
+    else:
+      required:
+        - amlogic,secure-monitor
 
 unevaluatedProperties: false
 
@@ -62,4 +86,13 @@ examples:
         #thermal-sensor-cells = <0>;
         amlogic,ao-secure = <&sec_AO>;
     };
+  - |
+    temperature-sensor@20000 {
+        compatible = "amlogic,t7-thermal";
+        reg = <0x0 0x20000 0x0 0x50>;
+        interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
+        clocks = <&clkc_periphs CLKID_TS>;
+        #thermal-sensor-cells = <0>;
+        amlogic,secure-monitor = <&sm 1>;
+    };
 ...

-- 
2.49.0




^ permalink raw reply related

* [PATCH v4 2/8] firmware: meson: sm: Thermal calibration read via secure monitor
From: Ronald Claveau via B4 Relay @ 2026-04-23 16:07 UTC (permalink / raw)
  To: Guillaume La Roque, Rafael J. Wysocki, Daniel Lezcano, Zhang Rui,
	Lukasz Luba, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Neil Armstrong, Kevin Hilman, Jerome Brunet, Martin Blumenstingl
  Cc: linux-pm, linux-amlogic, devicetree, linux-kernel,
	linux-arm-kernel, Ronald Claveau
In-Reply-To: <20260423-add-thermal-t7-vim4-v4-0-d4c1528d5044@aliel.fr>

From: Ronald Claveau <linux-kernel-dev@aliel.fr>

Add SM_THERMAL_CALIB_READ to the secure monitor command enum and
introduce meson_sm_get_thermal_calib() to allow drivers to retrieve
thermal sensor calibration data through the firmware interface.

Signed-off-by: Ronald Claveau <linux-kernel-dev@aliel.fr>
---
 include/linux/firmware/meson/meson_sm.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/include/linux/firmware/meson/meson_sm.h b/include/linux/firmware/meson/meson_sm.h
index 8eaf8922ab020..3ebc2bd9a9760 100644
--- a/include/linux/firmware/meson/meson_sm.h
+++ b/include/linux/firmware/meson/meson_sm.h
@@ -12,6 +12,7 @@ enum {
 	SM_EFUSE_WRITE,
 	SM_EFUSE_USER_MAX,
 	SM_GET_CHIP_ID,
+	SM_THERMAL_CALIB_READ,
 	SM_A1_PWRC_SET,
 	SM_A1_PWRC_GET,
 };
@@ -27,5 +28,7 @@ int meson_sm_call_read(struct meson_sm_firmware *fw, void *buffer,
 		       unsigned int bsize, unsigned int cmd_index, u32 arg0,
 		       u32 arg1, u32 arg2, u32 arg3, u32 arg4);
 struct meson_sm_firmware *meson_sm_get(struct device_node *firmware_node);
+int meson_sm_get_thermal_calib(struct meson_sm_firmware *fw, u32 *trim_info,
+			       u32 tsensor_id);
 
 #endif /* _MESON_SM_FW_H_ */

-- 
2.49.0




^ permalink raw reply related

* [PATCH v4 6/8] arm64: dts: amlogic: t7: Add thermal sensor nodes
From: Ronald Claveau via B4 Relay @ 2026-04-23 16:07 UTC (permalink / raw)
  To: Guillaume La Roque, Rafael J. Wysocki, Daniel Lezcano, Zhang Rui,
	Lukasz Luba, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Neil Armstrong, Kevin Hilman, Jerome Brunet, Martin Blumenstingl
  Cc: linux-pm, linux-amlogic, devicetree, linux-kernel,
	linux-arm-kernel, Ronald Claveau
In-Reply-To: <20260423-add-thermal-t7-vim4-v4-0-d4c1528d5044@aliel.fr>

From: Ronald Claveau <linux-kernel-dev@aliel.fr>

Add six temperature sensor nodes using the amlogic,t7-thermal compatible:
a73, a53, gpu, nna, vpu, and hevc. Each sensor retrieves its calibration
data from the secure monitor via the amlogic,secure-monitor phandle with
the corresponding tsensor_id argument.

Signed-off-by: Ronald Claveau <linux-kernel-dev@aliel.fr>
---
 arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi | 58 +++++++++++++++++++++++++++++
 1 file changed, 58 insertions(+)

diff --git a/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi b/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
index 7aec65f036a9c..62f259b2b17d2 100644
--- a/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
+++ b/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
@@ -656,6 +656,24 @@ sec_ao: ao-secure@10220 {
 				amlogic,has-chip-id;
 			};
 
+			a73_tsensor: temperature-sensor@20000 {
+				compatible = "amlogic,t7-thermal";
+				reg = <0x0 0x20000 0x0 0x50>;
+				interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clkc_periphs CLKID_TS>;
+				#thermal-sensor-cells = <0>;
+				amlogic,secure-monitor = <&sm 1>;
+			};
+
+			a53_tsensor: temperature-sensor@22000 {
+				compatible = "amlogic,t7-thermal";
+				reg = <0x0 0x22000 0x0 0x50>;
+				interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clkc_periphs CLKID_TS>;
+				#thermal-sensor-cells = <0>;
+				amlogic,secure-monitor = <&sm 2>;
+			};
+
 			pwm_ao_ef: pwm@30000 {
 				compatible = "amlogic,t7-pwm", "amlogic,meson-s4-pwm";
 				reg = <0x0 0x30000 0x0 0x24>;
@@ -770,6 +788,46 @@ sd_emmc_c: mmc@8c000 {
 				assigned-clock-parents = <&xtal>;
 				status = "disabled";
 			};
+
+			gpu_tsensor: temperature-sensor@94000 {
+				compatible = "amlogic,t7-thermal";
+				reg = <0x0 0x94000 0x0 0x50>;
+				interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clkc_periphs CLKID_TS>;
+				power-domains = <&pwrc PWRC_T7_MALI_TOP_ID>;
+				#thermal-sensor-cells = <0>;
+				amlogic,secure-monitor = <&sm 3>;
+			};
+
+			nna_tsensor: temperature-sensor@96000 {
+				compatible = "amlogic,t7-thermal";
+				reg = <0x0 0x96000 0x0 0x50>;
+				interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clkc_periphs CLKID_TS>;
+				power-domains = <&pwrc PWRC_T7_NNA_TOP_ID>;
+				#thermal-sensor-cells = <0>;
+				amlogic,secure-monitor = <&sm 4>;
+			};
+
+			vpu_tsensor: temperature-sensor@98000 {
+				compatible = "amlogic,t7-thermal";
+				reg = <0x0 0x98000 0x0 0x50>;
+				interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clkc_periphs CLKID_TS>;
+				power-domains = <&pwrc PWRC_T7_VPU_HDMI_ID>;
+				#thermal-sensor-cells = <0>;
+				amlogic,secure-monitor = <&sm 6>;
+			};
+
+			hevc_tsensor: temperature-sensor@9a000 {
+				compatible = "amlogic,t7-thermal";
+				reg = <0x0 0x9a000 0x0 0x50>;
+				interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&clkc_periphs CLKID_TS>;
+				power-domains = <&pwrc PWRC_T7_DOS_HEVC_ID>;
+				#thermal-sensor-cells = <0>;
+				amlogic,secure-monitor = <&sm 5>;
+			};
 		};
 
 	};

-- 
2.49.0




^ permalink raw reply related

* [PATCH v4 0/8] arm64: amlogic: T7 thermal support
From: Ronald Claveau via B4 Relay @ 2026-04-23 16:07 UTC (permalink / raw)
  To: Guillaume La Roque, Rafael J. Wysocki, Daniel Lezcano, Zhang Rui,
	Lukasz Luba, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Neil Armstrong, Kevin Hilman, Jerome Brunet, Martin Blumenstingl
  Cc: linux-pm, linux-amlogic, devicetree, linux-kernel,
	linux-arm-kernel, Ronald Claveau, Conor Dooley

This series adds thermal monitoring support for the Amlogic T7 SoC,
used on the Khadas VIM4 board.

The T7 exposes six thermal sensors (a53, a73, gpu, nna, vpu, hevc),
each accessible through the secure monitor firmware interface rather
than a directly mapped eFuse register as on older SoCs.

The series is organized as follows:

- Patch 1 extends the amlogic,t7-thermal DT binding to describe the
  new amlogic,secure-monitor property.
- Patches 2-3 extend the Meson secure monitor driver to expose a
  thermal calibration read command (SMC ID 0x82000047).
- Patch 4 adds the secure monitor readout path to the amlogic thermal
  driver and introduces the amlogic,t7-thermal compatible.
- Patches 5-7 wire up the T7 DTSI with CPU cooling cells, sensor
  nodes, and thermal zones.
- Patch 8 extends the Khadas VIM4 DTS to map all thermal zones to the
  on-board MCU fan controller (states 30–100, corresponding to the
  FAN_CTRL register range 0x1E–0x64).

Signed-off-by: Ronald Claveau <linux-kernel-dev@aliel.fr>
---
Changes in v4:
- PATCH 4: Extract SM and syscon setup into amlogic_thermal_probe_sm() and
           amlogic_thermal_probe_syscon() removing amlogic_thermal_initialize()
           from Daniel's feedback.
           Also fix pre-existing bug: move calibration readout before
           devm_thermal_of_zone_register() to avoid reading uninitialized
           trim_info, according to Daniel's feedback.
- Link to v3: https://lore.kernel.org/r/20260421-add-thermal-t7-vim4-v3-0-a2e7215ed003@aliel.fr

Changes in v3:
- PATCH 1: Replace second if check by an else statement.
  Remove unnecessary label in example according to Conor's feedback
- Link to v2: https://lore.kernel.org/r/20260413-add-thermal-t7-vim4-v2-0-1002d90a0602@aliel.fr

Changes in v2:
- PATCH 1: change two const entries to enum, explain why sensor index is needed
  reorder conditional compatible for required, and fallback only according to
  Krzysztof's feedback.
- PATCH 3: Add kerneldoc for meson_sm_get_thermal_calib exported function
  according to Krzysztof's feedback.
- Link to v1: https://lore.kernel.org/r/20260410-add-thermal-t7-vim4-v1-0-19f2b8da74d7@aliel.fr

---
Ronald Claveau (8):
      dt-bindings: thermal: amlogic: Add support for T7
      firmware: meson: sm: Thermal calibration read via secure monitor
      firmware: meson: sm: Add thermal calibration SMC call
      thermal: amlogic: Add support for secure monitor calibration readout
      arm64: dts: amlogic: t7: Add cooling cells to all CPUs
      arm64: dts: amlogic: t7: Add thermal sensor nodes
      arm64: dts: amlogic: t7: Add thermal zones
      arm64: dts: amlogic: t7: khadas-vim4: Add fan cooling to thermal zones

 .../bindings/thermal/amlogic,thermal.yaml          |  37 +++-
 .../dts/amlogic/amlogic-t7-a311d2-khadas-vim4.dts  | 102 +++++++++
 arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi        | 245 +++++++++++++++++++++
 drivers/firmware/meson/meson_sm.c                  |  29 ++-
 drivers/thermal/amlogic_thermal.c                  | 115 +++++++---
 include/linux/firmware/meson/meson_sm.h            |   3 +
 6 files changed, 494 insertions(+), 37 deletions(-)
---
base-commit: f7b64ed948718290209074a50bb0df17e5944873
change-id: 20260410-add-thermal-t7-vim4-00e571badcc1
prerequisite-message-id: <20260326092645.1053261-1-jian.hu@amlogic.com>
prerequisite-patch-id: f03a086b4137158412b2d47b3de793b858de8dde
prerequisite-patch-id: 123970c9b29c2090440f2fd71c85d3c6fd8e36de
prerequisite-patch-id: 3e2e56b0926ba327b520f935df4ced5089bbe503
prerequisite-patch-id: 65a5d76ffdbc9b3aab3385bb65cb027004c30e7e
prerequisite-patch-id: 237269801826dd3ad7fb16eb4d7d6d4eab504278
prerequisite-patch-id: 57e9b08a968aedf543d3d0d56cf1ca4db20b2a16
prerequisite-change-id: 20260326-add-bcm43752-compatible-e264a4f7973a:v2
prerequisite-patch-id: cd98b74fa56af72af2553f391c400981d83cd4f4
prerequisite-patch-id: b730f5e42be1d89d193e63a0265495cdbf2c7d7b
prerequisite-change-id: 20260330-fix-invalid-property-bbe54d933f71:v2
prerequisite-patch-id: 8d675e7a239985c762843515b241f0a2f45f9c92
prerequisite-change-id: 20260331-fix-aml-t7-null-reset-2b608ebf9da4:v1
prerequisite-patch-id: 5b5de77af11747ce964404fb827d2ee2bff47ea5
prerequisite-patch-id: 1e37fc75fed1e533adee0f3e7e6ead1f8ff3c55c
prerequisite-patch-id: 65a5d76ffdbc9b3aab3385bb65cb027004c30e7e
prerequisite-patch-id: 2daf583fb5e7449a02bd217d8aca330171b598aa
prerequisite-patch-id: 237269801826dd3ad7fb16eb4d7d6d4eab504278
prerequisite-patch-id: d1ddf9b7710e91f8062de83bd7ba55afb2c4c112
prerequisite-patch-id: 57e9b08a968aedf543d3d0d56cf1ca4db20b2a16
prerequisite-patch-id: cd98b74fa56af72af2553f391c400981d83cd4f4
prerequisite-patch-id: b730f5e42be1d89d193e63a0265495cdbf2c7d7b
prerequisite-patch-id: 9debd88fa60febed9cd7208f86603b4c2d270520
prerequisite-patch-id: 314ef9ff0c4d1d15dab1dea9d92aa065f1eac3e9
prerequisite-change-id: 20260402-add-mcu-fan-khadas-vim4-ac1cbe553c9b:v4
prerequisite-patch-id: f03a086b4137158412b2d47b3de793b858de8dde
prerequisite-patch-id: 123970c9b29c2090440f2fd71c85d3c6fd8e36de
prerequisite-patch-id: 3e2e56b0926ba327b520f935df4ced5089bbe503
prerequisite-patch-id: 65a5d76ffdbc9b3aab3385bb65cb027004c30e7e
prerequisite-patch-id: 237269801826dd3ad7fb16eb4d7d6d4eab504278
prerequisite-patch-id: 57e9b08a968aedf543d3d0d56cf1ca4db20b2a16
prerequisite-patch-id: cd98b74fa56af72af2553f391c400981d83cd4f4
prerequisite-patch-id: b730f5e42be1d89d193e63a0265495cdbf2c7d7b
prerequisite-patch-id: 8d675e7a239985c762843515b241f0a2f45f9c92
prerequisite-patch-id: 9debd88fa60febed9cd7208f86603b4c2d270520
prerequisite-patch-id: 314ef9ff0c4d1d15dab1dea9d92aa065f1eac3e9
prerequisite-patch-id: e6a1b58b91a877504a12ae68bee71eb4e496c33b
prerequisite-patch-id: 406f88d7dabd3a870b358fb53c21686f29eb32b7
prerequisite-patch-id: d7a75ae3be0f54e0a7e81ccb0043a2f05423c9d0
prerequisite-patch-id: 5e19dc5ace12b532284246f5c2ff3f214d8a9c4f
prerequisite-patch-id: d6a87ebcf5246eb67b94ca0908afa3df9f9383fe
prerequisite-patch-id: 4809bbedf79f59e1abc52c17cffc0b1bbb43d365
prerequisite-patch-id: c050e8bac4b5491f6c7008a5ccb26f20fad38b46
prerequisite-patch-id: 30677db8fc57270787245103c0d5acf8791307b0

Best regards,
-- 
Ronald Claveau <linux-kernel-dev@aliel.fr>




^ permalink raw reply

* [PATCH v4 7/8] arm64: dts: amlogic: t7: Add thermal zones
From: Ronald Claveau via B4 Relay @ 2026-04-23 16:07 UTC (permalink / raw)
  To: Guillaume La Roque, Rafael J. Wysocki, Daniel Lezcano, Zhang Rui,
	Lukasz Luba, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Neil Armstrong, Kevin Hilman, Jerome Brunet, Martin Blumenstingl
  Cc: linux-pm, linux-amlogic, devicetree, linux-kernel,
	linux-arm-kernel, Ronald Claveau
In-Reply-To: <20260423-add-thermal-t7-vim4-v4-0-d4c1528d5044@aliel.fr>

From: Ronald Claveau <linux-kernel-dev@aliel.fr>

Add thermal zones for all six sensors: a53, a73, gpu, nna, vpu, and hevc.

Signed-off-by: Ronald Claveau <linux-kernel-dev@aliel.fr>
---
 arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi | 179 ++++++++++++++++++++++++++++
 1 file changed, 179 insertions(+)

diff --git a/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi b/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
index 62f259b2b17d2..c6ea0f20a879f 100644
--- a/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
+++ b/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
@@ -9,6 +9,7 @@
 #include <dt-bindings/clock/amlogic,t7-scmi.h>
 #include <dt-bindings/clock/amlogic,t7-pll-clkc.h>
 #include <dt-bindings/clock/amlogic,t7-peripherals-clkc.h>
+#include <dt-bindings/thermal/thermal.h>
 
 / {
 	interrupt-parent = <&gic>;
@@ -829,6 +830,184 @@ hevc_tsensor: temperature-sensor@9a000 {
 				amlogic,secure-monitor = <&sm 5>;
 			};
 		};
+	};
+
+	thermal-zones {
+		a53_thermal: a53-thermal {
+			polling-delay = <1000>;
+			polling-delay-passive = <100>;
+			thermal-sensors = <&a53_tsensor>;
+
+			trips {
+				a53_passive: a53-passive {
+					temperature = <85000>; /* millicelsius */
+					hysteresis = <2000>; /* millicelsius */
+					type = "passive";
+				};
+
+				a53_hot: a53-hot {
+					temperature = <95000>; /* millicelsius */
+					hysteresis = <2000>; /* millicelsius */
+					type = "hot";
+				};
+
+				a53_critical: a53-critical {
+					temperature = <110000>; /* millicelsius */
+					hysteresis = <2000>; /* millicelsius */
+					type = "critical";
+				};
+			};
+
+			cooling-maps {
+				map-a53 {
+					trip = <&a53_passive>;
+					cooling-device =
+						<&cpu100 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+						<&cpu101 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+						<&cpu102 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+						<&cpu103 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+				};
+			};
+		};
+
+		a73_thermal: a73-thermal {
+			polling-delay = <1000>;
+			polling-delay-passive = <100>;
+			thermal-sensors = <&a73_tsensor>;
+
+			trips {
+				a73_passive: a73-passive {
+					temperature = <85000>; /* millicelsius */
+					hysteresis = <2000>; /* millicelsius */
+					type = "passive";
+				};
+
+				a73_hot: a73-hot {
+					temperature = <95000>; /* millicelsius */
+					hysteresis = <2000>; /* millicelsius */
+					type = "hot";
+				};
+
+				a73_critical: a73-critical {
+					temperature = <110000>; /* millicelsius */
+					hysteresis = <2000>; /* millicelsius */
+					type = "critical";
+				};
+			};
+
+			cooling-maps {
+				map-a73 {
+					trip = <&a73_passive>;
+					cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+							 <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+							 <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+							 <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+				};
+			};
+		};
+
+		gpu_thermal: gpu-thermal {
+			polling-delay = <1000>;
+			polling-delay-passive = <100>;
+			thermal-sensors = <&gpu_tsensor>;
+
+			trips {
+				gpu_passive: gpu-passive {
+					temperature = <95000>;
+					hysteresis = <5000>;
+					type = "passive";
+				};
+
+				gpu_hot: gpu-hot {
+					temperature = <105000>;
+					hysteresis = <5000>;
+					type = "passive";
+				};
 
+				gpu_critical: gpu-critical {
+					temperature = <115000>;
+					hysteresis = <1000>;
+					type = "critical";
+				};
+			};
+		};
+
+		hevc_thermal: hevc-thermal {
+			polling-delay = <1000>;
+			polling-delay-passive = <100>;
+			thermal-sensors = <&hevc_tsensor>;
+
+			trips {
+				hevc_passive: hevc-passive {
+					temperature = <95000>;
+					hysteresis = <5000>;
+					type = "passive";
+				};
+
+				hevc_hot: hevc-hot {
+					temperature = <105000>;
+					hysteresis = <5000>;
+					type = "passive";
+				};
+
+				hevc_critical: hevc-critical {
+					temperature = <115000>;
+					hysteresis = <1000>;
+					type = "critical";
+				};
+			};
+		};
+
+		nna_thermal: nna-thermal {
+			polling-delay = <1000>;
+			polling-delay-passive = <100>;
+			thermal-sensors = <&nna_tsensor>;
+
+			trips {
+				nna_passive: nna-passive {
+					temperature = <95000>;
+					hysteresis = <5000>;
+					type = "passive";
+				};
+
+				nna_hot: nna-hot {
+					temperature = <105000>;
+					hysteresis = <5000>;
+					type = "passive";
+				};
+
+				nna_critical: nna-critical {
+					temperature = <115000>;
+					hysteresis = <1000>;
+					type = "critical";
+				};
+			};
+		};
+
+		vpu_thermal: vpu-thermal {
+			polling-delay = <1000>;
+			polling-delay-passive = <100>;
+			thermal-sensors = <&vpu_tsensor>;
+
+			trips {
+				vpu_passive: vpu-passive {
+					temperature = <95000>;
+					hysteresis = <5000>;
+					type = "passive";
+				};
+
+				vpu_hot: vpu-hot {
+					temperature = <105000>;
+					hysteresis = <5000>;
+					type = "passive";
+				};
+
+				vpu_critical: vpu-critical {
+					temperature = <115000>;
+					hysteresis = <1000>;
+					type = "critical";
+				};
+			};
+		};
 	};
 };

-- 
2.49.0




^ permalink raw reply related

* [PATCH v4 3/8] firmware: meson: sm: Add thermal calibration SMC call
From: Ronald Claveau via B4 Relay @ 2026-04-23 16:07 UTC (permalink / raw)
  To: Guillaume La Roque, Rafael J. Wysocki, Daniel Lezcano, Zhang Rui,
	Lukasz Luba, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Neil Armstrong, Kevin Hilman, Jerome Brunet, Martin Blumenstingl
  Cc: linux-pm, linux-amlogic, devicetree, linux-kernel,
	linux-arm-kernel, Ronald Claveau
In-Reply-To: <20260423-add-thermal-t7-vim4-v4-0-d4c1528d5044@aliel.fr>

From: Ronald Claveau <linux-kernel-dev@aliel.fr>

Add SM_THERMAL_CALIB_READ at SMC ID 0x82000047 in the command
table and implement meson_sm_get_thermal_calib(), which forwards the
tsensor_id argument to the secure monitor and returns the calibration data.

Also realign the CMD() column to improve readability.

Signed-off-by: Ronald Claveau <linux-kernel-dev@aliel.fr>
---
 drivers/firmware/meson/meson_sm.c | 29 ++++++++++++++++++++++++-----
 1 file changed, 24 insertions(+), 5 deletions(-)

diff --git a/drivers/firmware/meson/meson_sm.c b/drivers/firmware/meson/meson_sm.c
index 3ab67aaa9e5da..4e57986724212 100644
--- a/drivers/firmware/meson/meson_sm.c
+++ b/drivers/firmware/meson/meson_sm.c
@@ -41,12 +41,13 @@ static const struct meson_sm_chip gxbb_chip = {
 	.cmd_shmem_in_base	= 0x82000020,
 	.cmd_shmem_out_base	= 0x82000021,
 	.cmd = {
-		CMD(SM_EFUSE_READ,	0x82000030),
-		CMD(SM_EFUSE_WRITE,	0x82000031),
+		CMD(SM_EFUSE_READ,		0x82000030),
+		CMD(SM_EFUSE_WRITE,		0x82000031),
 		CMD(SM_EFUSE_USER_MAX,	0x82000033),
-		CMD(SM_GET_CHIP_ID,	0x82000044),
-		CMD(SM_A1_PWRC_SET,	0x82000093),
-		CMD(SM_A1_PWRC_GET,	0x82000095),
+		CMD(SM_GET_CHIP_ID,		0x82000044),
+		CMD(SM_THERMAL_CALIB_READ,	0x82000047),
+		CMD(SM_A1_PWRC_SET,		0x82000093),
+		CMD(SM_A1_PWRC_GET,		0x82000095),
 		{ /* sentinel */ },
 	},
 };
@@ -245,6 +246,24 @@ struct meson_sm_firmware *meson_sm_get(struct device_node *sm_node)
 }
 EXPORT_SYMBOL_GPL(meson_sm_get);
 
+/**
+ *
+ * meson_sm_get_thermal_calib - Read thermal sensor calibration data.
+ * @fw:		Pointer to secure-monitor firmware.
+ * @trim_info:	Pointer to store the returned calibration data.
+ * @tsensor_id:	Sensor index to identify which sensor's calibration data
+ *		to retrieve
+ *
+ * Return: 0 on success, negative error code on failure.
+ */
+int meson_sm_get_thermal_calib(struct meson_sm_firmware *fw, u32 *trim_info,
+			       u32 tsensor_id)
+{
+	return meson_sm_call(fw, SM_THERMAL_CALIB_READ, trim_info, tsensor_id,
+			     0, 0, 0, 0);
+}
+EXPORT_SYMBOL_GPL(meson_sm_get_thermal_calib);
+
 #define SM_CHIP_ID_LENGTH	119
 #define SM_CHIP_ID_OFFSET	4
 #define SM_CHIP_ID_SIZE		12

-- 
2.49.0




^ permalink raw reply related

* [PATCH v4 5/8] arm64: dts: amlogic: t7: Add cooling cells to all CPUs
From: Ronald Claveau via B4 Relay @ 2026-04-23 16:07 UTC (permalink / raw)
  To: Guillaume La Roque, Rafael J. Wysocki, Daniel Lezcano, Zhang Rui,
	Lukasz Luba, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Neil Armstrong, Kevin Hilman, Jerome Brunet, Martin Blumenstingl
  Cc: linux-pm, linux-amlogic, devicetree, linux-kernel,
	linux-arm-kernel, Ronald Claveau
In-Reply-To: <20260423-add-thermal-t7-vim4-v4-0-d4c1528d5044@aliel.fr>

From: Ronald Claveau <linux-kernel-dev@aliel.fr>

Add #cooling-cells = <2> to all CPU nodes (both little and big cluster)
to allow them to be used as cooling devices in thermal zone mappings.

Signed-off-by: Ronald Claveau <linux-kernel-dev@aliel.fr>
---
 arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi b/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
index 560c9dce35266..7aec65f036a9c 100644
--- a/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
+++ b/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
@@ -63,6 +63,7 @@ cpu100: cpu@100 {
 			i-cache-size = <0x8000>;
 			i-cache-sets = <32>;
 			next-level-cache = <&l2_cache_l>;
+			#cooling-cells = <2>;
 		};
 
 		cpu101: cpu@101 {
@@ -77,6 +78,7 @@ cpu101: cpu@101 {
 			i-cache-size = <0x8000>;
 			i-cache-sets = <32>;
 			next-level-cache = <&l2_cache_l>;
+			#cooling-cells = <2>;
 		};
 
 		cpu102: cpu@102 {
@@ -91,6 +93,7 @@ cpu102: cpu@102 {
 			i-cache-size = <0x8000>;
 			i-cache-sets = <32>;
 			next-level-cache = <&l2_cache_l>;
+			#cooling-cells = <2>;
 		};
 
 		cpu103: cpu@103 {
@@ -105,6 +108,7 @@ cpu103: cpu@103 {
 			i-cache-size = <0x8000>;
 			i-cache-sets = <32>;
 			next-level-cache = <&l2_cache_l>;
+			#cooling-cells = <2>;
 		};
 
 		cpu0: cpu@0 {
@@ -119,6 +123,7 @@ cpu0: cpu@0 {
 			i-cache-size = <0x10000>;
 			i-cache-sets = <64>;
 			next-level-cache = <&l2_cache_b>;
+			#cooling-cells = <2>;
 		};
 
 		cpu1: cpu@1 {
@@ -133,6 +138,7 @@ cpu1: cpu@1 {
 			i-cache-size = <0x10000>;
 			i-cache-sets = <64>;
 			next-level-cache = <&l2_cache_b>;
+			#cooling-cells = <2>;
 		};
 
 		cpu2: cpu@2 {
@@ -147,6 +153,7 @@ cpu2: cpu@2 {
 			i-cache-size = <0x10000>;
 			i-cache-sets = <64>;
 			next-level-cache = <&l2_cache_b>;
+			#cooling-cells = <2>;
 		};
 
 		cpu3: cpu@3 {
@@ -161,6 +168,7 @@ cpu3: cpu@3 {
 			i-cache-size = <0x10000>;
 			i-cache-sets = <64>;
 			next-level-cache = <&l2_cache_b>;
+			#cooling-cells = <2>;
 		};
 
 		l2_cache_l: l2-cache-cluster0 {

-- 
2.49.0




^ permalink raw reply related

* [PATCH v4 4/8] thermal: amlogic: Add support for secure monitor calibration readout
From: Ronald Claveau via B4 Relay @ 2026-04-23 16:07 UTC (permalink / raw)
  To: Guillaume La Roque, Rafael J. Wysocki, Daniel Lezcano, Zhang Rui,
	Lukasz Luba, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Neil Armstrong, Kevin Hilman, Jerome Brunet, Martin Blumenstingl
  Cc: linux-pm, linux-amlogic, devicetree, linux-kernel,
	linux-arm-kernel, Ronald Claveau
In-Reply-To: <20260423-add-thermal-t7-vim4-v4-0-d4c1528d5044@aliel.fr>

From: Ronald Claveau <linux-kernel-dev@aliel.fr>

Some SoCs (e.g. T7) expose thermal calibration data through the secure
monitor rather than a directly accessible eFuse register. Add a use_sm
flag to amlogic_thermal_data to select this path, and retrieve the
firmware handle and tsensor_id from the "amlogic,secure-monitor" DT
phandle with one fixed argument.

Also introduce the amlogic,t7-thermal compatible using this new path.

While refactoring, fix a pre-existing bug where
amlogic_thermal_initialize() was called after
devm_thermal_of_zone_register(), causing the thermal framework to
read an uninitialized trim_info on zone registration.

Signed-off-by: Ronald Claveau <linux-kernel-dev@aliel.fr>
---
 drivers/thermal/amlogic_thermal.c | 115 ++++++++++++++++++++++++++++----------
 1 file changed, 85 insertions(+), 30 deletions(-)

diff --git a/drivers/thermal/amlogic_thermal.c b/drivers/thermal/amlogic_thermal.c
index 5448d772db12a..0d0c01e57b85e 100644
--- a/drivers/thermal/amlogic_thermal.c
+++ b/drivers/thermal/amlogic_thermal.c
@@ -25,6 +25,7 @@
 #include <linux/platform_device.h>
 #include <linux/regmap.h>
 #include <linux/thermal.h>
+#include <linux/firmware/meson/meson_sm.h>
 
 #include "thermal_hwmon.h"
 
@@ -84,12 +85,14 @@ struct amlogic_thermal_soc_calib_data {
  * @u_efuse_off: register offset to read fused calibration value
  * @calibration_parameters: calibration parameters structure pointer
  * @regmap_config: regmap config for the device
+ * @use_sm: read data from secure monitor instead of efuse
  * This structure is required for configuration of amlogic thermal driver.
  */
 struct amlogic_thermal_data {
 	int u_efuse_off;
 	const struct amlogic_thermal_soc_calib_data *calibration_parameters;
 	const struct regmap_config *regmap_config;
+	bool use_sm;
 };
 
 struct amlogic_thermal {
@@ -100,6 +103,8 @@ struct amlogic_thermal {
 	struct clk *clk;
 	struct thermal_zone_device *tzd;
 	u32 trim_info;
+	struct meson_sm_firmware *sm_fw;
+	u32 tsensor_id;
 };
 
 /*
@@ -133,26 +138,6 @@ static int amlogic_thermal_code_to_millicelsius(struct amlogic_thermal *pdata,
 	return temp;
 }
 
-static int amlogic_thermal_initialize(struct amlogic_thermal *pdata)
-{
-	int ret = 0;
-	int ver;
-
-	regmap_read(pdata->sec_ao_map, pdata->data->u_efuse_off,
-		    &pdata->trim_info);
-
-	ver = TSENSOR_TRIM_VERSION(pdata->trim_info);
-
-	if ((ver & TSENSOR_TRIM_CALIB_VALID_MASK) == 0) {
-		ret = -EINVAL;
-		dev_err(&pdata->pdev->dev,
-			"tsensor thermal calibration not supported: 0x%x!\n",
-			ver);
-	}
-
-	return ret;
-}
-
 static int amlogic_thermal_enable(struct amlogic_thermal *data)
 {
 	int ret;
@@ -190,6 +175,70 @@ static int amlogic_thermal_get_temp(struct thermal_zone_device *tz, int *temp)
 	return 0;
 }
 
+static int amlogic_thermal_probe_sm(struct platform_device *pdev,
+				    struct amlogic_thermal *pdata)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *sm_np;
+	struct of_phandle_args ph_args;
+	int ret;
+
+	ret = of_parse_phandle_with_fixed_args(pdev->dev.of_node,
+					       "amlogic,secure-monitor",
+					       1, 0, &ph_args);
+	if (ret)
+		return ret;
+
+	sm_np = ph_args.np;
+	if (!sm_np) {
+		dev_err(dev,
+			"Failed to parse secure monitor phandle\n");
+		return -ENODEV;
+	}
+
+	pdata->sm_fw = meson_sm_get(sm_np);
+	of_node_put(sm_np);
+	if (!pdata->sm_fw) {
+		dev_err(dev, "Failed to get secure monitor firmware\n");
+		return -EPROBE_DEFER;
+	}
+
+	pdata->tsensor_id = ph_args.args[0];
+
+	return meson_sm_get_thermal_calib(pdata->sm_fw,
+					  &pdata->trim_info,
+					  pdata->tsensor_id);
+}
+
+static int amlogic_thermal_probe_syscon(struct platform_device *pdev,
+					struct amlogic_thermal *pdata)
+{
+	struct device *dev = &pdev->dev;
+	int ret = 0;
+	int ver;
+
+	pdata->sec_ao_map = syscon_regmap_lookup_by_phandle
+		(pdev->dev.of_node, "amlogic,ao-secure");
+	if (IS_ERR(pdata->sec_ao_map)) {
+		dev_err(dev, "syscon regmap lookup failed.\n");
+		return PTR_ERR(pdata->sec_ao_map);
+	}
+
+	regmap_read(pdata->sec_ao_map, pdata->data->u_efuse_off,
+		    &pdata->trim_info);
+
+	ver = TSENSOR_TRIM_VERSION(pdata->trim_info);
+
+	if ((ver & TSENSOR_TRIM_CALIB_VALID_MASK) == 0) {
+		ret = -EINVAL;
+		dev_err(&pdata->pdev->dev,
+			"tsensor thermal calibration not supported: 0x%x!\n",
+			ver);
+	}
+
+	return ret;
+}
+
 static const struct thermal_zone_device_ops amlogic_thermal_ops = {
 	.get_temp	= amlogic_thermal_get_temp,
 };
@@ -226,6 +275,12 @@ static const struct amlogic_thermal_data amlogic_thermal_a1_cpu_param = {
 	.regmap_config = &amlogic_thermal_regmap_config_g12a,
 };
 
+static const struct amlogic_thermal_data amlogic_thermal_t7_param = {
+	.use_sm			= true,
+	.calibration_parameters	= &amlogic_thermal_g12a,
+	.regmap_config		= &amlogic_thermal_regmap_config_g12a,
+};
+
 static const struct of_device_id of_amlogic_thermal_match[] = {
 	{
 		.compatible = "amlogic,g12a-ddr-thermal",
@@ -239,6 +294,10 @@ static const struct of_device_id of_amlogic_thermal_match[] = {
 		.compatible = "amlogic,a1-cpu-thermal",
 		.data = &amlogic_thermal_a1_cpu_param,
 	},
+	{
+		.compatible = "amlogic,t7-thermal",
+		.data = &amlogic_thermal_t7_param,
+	},
 	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, of_amlogic_thermal_match);
@@ -271,12 +330,12 @@ static int amlogic_thermal_probe(struct platform_device *pdev)
 	if (IS_ERR(pdata->clk))
 		return dev_err_probe(dev, PTR_ERR(pdata->clk), "failed to get clock\n");
 
-	pdata->sec_ao_map = syscon_regmap_lookup_by_phandle
-		(pdev->dev.of_node, "amlogic,ao-secure");
-	if (IS_ERR(pdata->sec_ao_map)) {
-		dev_err(dev, "syscon regmap lookup failed.\n");
-		return PTR_ERR(pdata->sec_ao_map);
-	}
+	if (pdata->data->use_sm)
+		ret = amlogic_thermal_probe_sm(pdev, pdata);
+	else
+		ret = amlogic_thermal_probe_syscon(pdev, pdata);
+	if (ret)
+		return ret;
 
 	pdata->tzd = devm_thermal_of_zone_register(&pdev->dev,
 						   0,
@@ -290,10 +349,6 @@ static int amlogic_thermal_probe(struct platform_device *pdev)
 
 	devm_thermal_add_hwmon_sysfs(&pdev->dev, pdata->tzd);
 
-	ret = amlogic_thermal_initialize(pdata);
-	if (ret)
-		return ret;
-
 	ret = amlogic_thermal_enable(pdata);
 
 	return ret;

-- 
2.49.0




^ permalink raw reply related

* [PATCH v4 8/8] arm64: dts: amlogic: t7: khadas-vim4: Add fan cooling to thermal zones
From: Ronald Claveau via B4 Relay @ 2026-04-23 16:07 UTC (permalink / raw)
  To: Guillaume La Roque, Rafael J. Wysocki, Daniel Lezcano, Zhang Rui,
	Lukasz Luba, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Neil Armstrong, Kevin Hilman, Jerome Brunet, Martin Blumenstingl
  Cc: linux-pm, linux-amlogic, devicetree, linux-kernel,
	linux-arm-kernel, Ronald Claveau
In-Reply-To: <20260423-add-thermal-t7-vim4-v4-0-d4c1528d5044@aliel.fr>

From: Ronald Claveau <linux-kernel-dev@aliel.fr>

Add an active trip at 50°C to all six thermal zones and map it to the
khadas_mcu fan controller, using cooling states 30 to 100.

Signed-off-by: Ronald Claveau <linux-kernel-dev@aliel.fr>
---
 .../dts/amlogic/amlogic-t7-a311d2-khadas-vim4.dts  | 102 +++++++++++++++++++++
 1 file changed, 102 insertions(+)

diff --git a/arch/arm64/boot/dts/amlogic/amlogic-t7-a311d2-khadas-vim4.dts b/arch/arm64/boot/dts/amlogic/amlogic-t7-a311d2-khadas-vim4.dts
index 5d7f5390f3a66..ba9219073dd0a 100644
--- a/arch/arm64/boot/dts/amlogic/amlogic-t7-a311d2-khadas-vim4.dts
+++ b/arch/arm64/boot/dts/amlogic/amlogic-t7-a311d2-khadas-vim4.dts
@@ -157,6 +157,74 @@ wifi32k: wifi32k {
 	};
 };
 
+&a53_thermal {
+	trips {
+		a53_active: a53-active {
+			temperature = <50000>; /* millicelsius */
+			hysteresis = <2000>; /* millicelsius */
+			type = "active";
+		};
+	};
+
+	cooling-maps {
+		map {
+			trip = <&a53_active>;
+			cooling-device = <&khadas_mcu 30 100>;
+		};
+	};
+};
+
+&a73_thermal {
+	trips {
+		a73_active: a73-active {
+			temperature = <50000>; /* millicelsius */
+			hysteresis = <2000>; /* millicelsius */
+			type = "active";
+		};
+	};
+
+	cooling-maps {
+		map {
+			trip = <&a73_active>;
+			cooling-device = <&khadas_mcu 30 100>;
+		};
+	};
+};
+
+&gpu_thermal {
+	trips {
+		gpu_active: gpu-active {
+			temperature = <50000>; /* millicelsius */
+			hysteresis = <2000>; /* millicelsius */
+			type = "active";
+		};
+	};
+
+	cooling-maps {
+		map {
+			trip = <&gpu_active>;
+			cooling-device = <&khadas_mcu 30 100>;
+		};
+	};
+};
+
+&hevc_thermal {
+	trips {
+		hevc_active: hevc-active {
+			temperature = <50000>; /* millicelsius */
+			hysteresis = <2000>; /* millicelsius */
+			type = "active";
+		};
+	};
+
+	cooling-maps {
+		map {
+			trip = <&hevc_active>;
+			cooling-device = <&khadas_mcu 30 100>;
+		};
+	};
+};
+
 &i2c_m_ao_a {
 	status = "okay";
 	pinctrl-0 = <&i2c0_ao_d_pins>;
@@ -170,6 +238,23 @@ khadas_mcu: system-controller@18 {
 	};
 };
 
+&nna_thermal {
+	trips {
+		nna_active: nna-active {
+			temperature = <50000>; /* millicelsius */
+			hysteresis = <2000>; /* millicelsius */
+			type = "active";
+		};
+	};
+
+	cooling-maps {
+		map {
+			trip = <&nna_active>;
+			cooling-device = <&khadas_mcu 30 100>;
+		};
+	};
+};
+
 &pwm_ab {
 	status = "okay";
 	pinctrl-0 = <&pwm_a_pins>;
@@ -266,3 +351,20 @@ &uart_a {
 	clocks = <&xtal>, <&xtal>, <&xtal>;
 	clock-names = "xtal", "pclk", "baud";
 };
+
+&vpu_thermal {
+	trips {
+		vpu_active: vpu-active {
+			temperature = <50000>; /* millicelsius */
+			hysteresis = <2000>; /* millicelsius */
+			type = "active";
+		};
+	};
+
+	cooling-maps {
+		map {
+			trip = <&vpu_active>;
+			cooling-device = <&khadas_mcu 30 100>;
+		};
+	};
+};

-- 
2.49.0




^ permalink raw reply related

* Re: [GIT PULL] soc: late changes for 7.1
From: pr-tracker-bot @ 2026-04-23 16:18 UTC (permalink / raw)
  To: Arnd Bergmann; +Cc: Linus Torvalds, soc, linux-kernel, linux-arm-kernel
In-Reply-To: <61d255e9-84eb-460e-afc3-0405c9363524@app.fastmail.com>

The pull request you sent on Thu, 23 Apr 2026 14:00:43 +0200:

> https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git soc-late-7.1

has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/507bd4b66c85d5b65696150cc16d31ac0b2ab151

Thank you!

-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/prtracker.html


^ permalink raw reply

* [PATCH] KVM: arm64: Wake-up from WFI when iqrchip is in userspace
From: Marc Zyngier @ 2026-04-23 16:36 UTC (permalink / raw)
  To: kvmarm, kvm, linux-arm-kernel
  Cc: Joey Gouly, Suzuki K Poulose, Oliver Upton, Zenghui Yu

It appears that there is nothing in the wake-up path that
evaluates whether the in-kernel interrupts are pending unless
we have a vgic.

This means that the userspace irqchip support has been broken for
about four years, and nobody noticed. It was also broken before
as we wouldn't wake-up on a PMU interrupt, but hey, who cares...

It is probably time to remove the feature altogether, because it
was a terrible idea 10 years ago, and it still is.

Fixes: b57de4ffd7c6d ("KVM: arm64: Simplify kvm_cpu_has_pending_timer()")
Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 arch/arm64/kvm/arm.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index 176cbe8baad30..8bb2c7422cc8b 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -824,6 +824,10 @@ int kvm_arch_vcpu_runnable(struct kvm_vcpu *v)
 {
 	bool irq_lines = *vcpu_hcr(v) & (HCR_VI | HCR_VF | HCR_VSE);
 
+	irq_lines |= (!irqchip_in_kernel(v->kvm) &&
+		      (kvm_timer_should_notify_user(v) ||
+		       kvm_pmu_should_notify_user(v)));
+
 	return ((irq_lines || kvm_vgic_vcpu_pending_irq(v))
 		&& !kvm_arm_vcpu_stopped(v) && !v->arch.pause);
 }
-- 
2.47.3



^ permalink raw reply related

* Re: [PATCH v2] arm64/irqflags: __always_inline the arch_local_irq_*() helpers
From: Breno Leitao @ 2026-04-23 16:45 UTC (permalink / raw)
  To: Catalin Marinas, Will Deacon, mark.rutland
  Cc: leo.bras, leo.yan, linux-arm-kernel, linux-kernel, palmer,
	paulmck, puranjay, usama.arif, rmikey, kernel-team
In-Reply-To: <20260421-arm64_always_inline-v2-1-c59d1400514d@debian.org>

On Tue, Apr 21, 2026 at 08:58:57AM -0700, Breno Leitao wrote:
> The arch_local_irq_*() wrappers in <asm/irqflags.h> dispatch between two
> underlying primitives: the __daif_* path on most systems, and the
> __pmr_* path on builds that use GIC PMR-based masking (Pseudo-NMI). The
> leaf primitives are already __always_inline, but the wrappers themselves
> are plain "static inline".
> 
> That is unsafe for noinstr callers: nothing prevents the compiler from
> emitting an out-of-line copy of e.g. arch_local_irq_disable(), and an
> out-of-line copy can be instrumented (ftrace, kcov, sanitizers), which
> breaks the noinstr contract on the entry/idle paths that rely on these
> helpers.
> 
> x86 hit and fixed exactly this class of bug in commit 7a745be1cc90
> ("x86/entry: __always_inline irqflags for noinstr").
> 
> Force-inline all of the arch_local_irq_*() wrappers so they cannot be
> emitted out-of-line:
> 
>   - arch_local_irq_enable()
>   - arch_local_irq_disable()
>   - arch_local_save_flags()
>   - arch_irqs_disabled_flags()
>   - arch_irqs_disabled()
>   - arch_local_irq_save()
>   - arch_local_irq_restore()
> 
> The primary motivation is noinstr safety. There is a useful side effect
> for fleet-wide profiling: when the wrapper is emitted out-of-line,
> samples taken inside it during the post-WFI IRQ unmask in
> default_idle_call() are attributed to arch_local_irq_enable rather than
> default_idle_call(), and the FP-unwinder loses default_idle_call() from
> the chain.

FWIW I run scripts/bloat-o-meter on the kernel with and without the
patch, and the the code size is mostly the same. here is the result:

	add/remove: 4/12 grow/shrink: 40/0 up/down: 1684/-652 (1032)
	Function                                     old     new   delta
	__schedule                                  8892    9024    +132
	irqentry_exit                                816     892     +76
	lockdep_hardirqs_off                         396     452     +56
	lock_is_held_type                            412     468     +56
	ct_idle_exit                                  76     132     +56
	cpu_idle_poll                                304     360     +56
	arch_stack_walk_reliable                    1152    1196     +44
	arch_stack_walk                             1184    1228     +44
	arch_bpf_stack_walk                          996    1040     +44
	lockdep_hardirqs_on                          464     504     +40
	el0_watchpt                                  576     616     +40
	el0_undef                                    560     600     +40
	el0_sys                                      560     600     +40
	el0_sve_acc                                  560     600     +40
	el0_svc                                      600     640     +40
	el0_sp                                       564     604     +40
	el0_softstp                                  728     768     +40
	el0_sme_acc                                  560     600     +40
	el0_pc                                       740     780     +40
	el0_mops                                     560     600     +40
	el0_inv                                      564     604     +40
	el0_interrupt                                656     696     +40
	el0_ia                                       716     756     +40
	el0_gcs                                      560     600     +40
	el0_fpsimd_exc                               560     600     +40
	el0_fpsimd_acc                               560     600     +40
	el0_fpac                                     560     600     +40
	el0_da                                       568     608     +40
	el0_bti                                      552     592     +40
	el0_brk64                                    560     600     +40
	el0_breakpt                                  720     760     +40
	asm_exit_to_user_mode                        416     456     +40
	__el0_error_handler_common                   592     632     +40
	cpuidle_enter_state                         1220    1248     +28
	check_preemption_disabled                    228     252     +24
	default_idle_call                            252     272     +20
	ct_kernel_enter                              388     404     +16
	ct_idle_enter                                 52      68     +16
	look_up_lock_class                           364     376     +12
	check_flags                                  492     504     +12
	__CortexA53843419_FFFF800081146000             -       8      +8
	__CortexA53843419_FFFF8000809C3004             -       8      +8
	__CortexA53843419_FFFF8000809AE000             -       8      +8
	__CortexA53843419_FFFF800080248004             -       8      +8
	__CortexA53843419_FFFF80008100C000             8       -      -8
	__CortexA53843419_FFFF8000809A9000             8       -      -8
	__CortexA53843419_FFFF8000809A8004             8       -      -8
	__CortexA53843419_FFFF800080448008             8       -      -8
	__CortexA53843419_FFFF8000801EE000             8       -      -8
	arch_local_irq_restore                        48       -     -48
	arch_local_save_flags                         80       -     -80
	arch_local_irq_save                           80       -     -80
	arch_local_irq_enable                         84       -     -84
	arch_local_irq_disable                        96       -     -96
	arch_irqs_disabled_flags                      96       -     -96
	arch_irqs_disabled                           128       -    -128
	Total: Before=163062863, After=163063895, chg +0.00%








^ permalink raw reply

* Re: [RFC PATCH v2 1/4] security: ima: call ima_init() again at late_initcall_sync for defered TPM
From: Jonathan McDowell @ 2026-04-23 17:02 UTC (permalink / raw)
  To: Mimi Zohar
  Cc: Yeoreum Yun, linux-security-module, linux-kernel, linux-integrity,
	linux-arm-kernel, kvmarm, paul, jmorris, serge, roberto.sassu,
	dmitry.kasatkin, eric.snowberg, jarkko, jgg, sudeep.holla, maz,
	oupton, joey.gouly, suzuki.poulose, yuzenghui, catalin.marinas,
	will, noodles, sebastianene
In-Reply-To: <2866f7679fe6933de667ce74ae68bd4ea9198e2a.camel@linux.ibm.com>

On Thu, Apr 23, 2026 at 10:48:49AM -0400, Mimi Zohar wrote:
>On Thu, 2026-04-23 at 15:03 +0100, Jonathan McDowell wrote:
>> On Thu, Apr 23, 2026 at 02:55:14PM +0100, Yeoreum Yun wrote:
>> > > On Thu, 2026-04-23 at 13:53 +0100, Jonathan McDowell wrote:
>> > > > On Thu, Apr 23, 2026 at 01:34:13PM +0100, Yeoreum Yun wrote:
>> > > > > > > On Thu, 2026-04-23 at 06:55 +0100, Yeoreum Yun wrote:
>> > > > > > > > > On Wed, 2026-04-22 at 20:41 +0100, Yeoreum Yun wrote:
>> > > > > > > > > > > Hi Mimi,
>> > > > > > > > > > >
>> > > > > > > > > > > > On Wed, 2026-04-22 at 17:24 +0100, Yeoreum Yun wrote:
>> > > > > > > > > > > > > To generate the boot_aggregate log in the IMA subsystem with TPM PCR values,
>> > > > > > > > > > > > > the TPM driver must be built as built-in and
>> > > > > > > > > > > > > must be probed before the IMA subsystem is initialized.
>> > > > > > > > > > > > >
>> > > > > > > > > > > > > However, when the TPM device operates over the FF-A protocol using
>> > > > > > > > > > > > > the CRB interface, probing fails and returns -EPROBE_DEFER if
>> > > > > > > > > > > > > the tpm_crb_ffa device — an FF-A device that provides the communication
>> > > > > > > > > > > > > interface to the tpm_crb driver — has not yet been probed.
>> > > > > > > > > > > > >
>> > > > > > > > > > > > > To ensure the TPM device operating over the FF-A protocol with
>> > > > > > > > > > > > > the CRB interface is probed before IMA initialization,
>> > > > > > > > > > > > > the following conditions must be met:
>> > > > > > > > > > > > >
>> > > > > > > > > > > > >    1. The corresponding ffa_device must be registered,
>> > > > > > > > > > > > >       which is done via ffa_init().
>> > > > > > > > > > > > >
>> > > > > > > > > > > > >    2. The tpm_crb_driver must successfully probe this device via
>> > > > > > > > > > > > >       tpm_crb_ffa_init().
>> > > > > > > > > > > > >
>> > > > > > > > > > > > >    3. The tpm_crb driver using CRB over FF-A can then
>> > > > > > > > > > > > >       be probed successfully. (See crb_acpi_add() and
>> > > > > > > > > > > > >       tpm_crb_ffa_init() for reference.)
>> > > > > > > > > > > > >
>> > > > > > > > > > > > > Unfortunately, ffa_init(), tpm_crb_ffa_init(), and crb_acpi_driver_init() are
>> > > > > > > > > > > > > all registered with device_initcall, which means crb_acpi_driver_init() may
>> > > > > > > > > > > > > be invoked before ffa_init() and tpm_crb_ffa_init() are completed.
>> > > > > > > > > > > > >
>> > > > > > > > > > > > > When this occurs, probing the TPM device is deferred.
>> > > > > > > > > > > > > However, the deferred probe can happen after the IMA subsystem
>> > > > > > > > > > > > > has already been initialized, since IMA initialization is performed
>> > > > > > > > > > > > > during late_initcall, and deferred_probe_initcall() is performed
>> > > > > > > > > > > > > at the same level.
>> > > > > > > > > > > > >
>> > > > > > > > > > > > > To resolve this, call ima_init() again at late_inicall_sync level
>> > > > > > > > > > > > > so that let IMA not miss TPM PCR value when generating boot_aggregate
>> > > > > > > > > > > > > log though TPM device presents in the system.
>> > > > > > > > > > > > >
>> > > > > > > > > > > > > Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com>
>> > > > > > > > > > > >
>> > > > > > > > > > > > A lot of change for just detecting whether ima_init() is being called on
>> > > > > > > > > > > > late_initcall or late_initcall_sync(), without any explanation for all the other
>> > > > > > > > > > > > changes (e.g. ima_init_core).
>> > > > > > > > > > > >
>> > > > > > > > > > > > Please just limit the change to just calling ima_init() twice.
>> > > > > > > > > > >
>> > > > > > > > > > > My concern is that ima_update_policy_flags() will be called
>> > > > > > > > > > > when ima_init() is deferred -- not initialised anything.
>> > > > > > > > > > > though functionally, it might be okay however,
>> > > > > > > > > > > I think ima_update_policy_flags() and notifier should work after ima_init()
>> > > > > > > > > > > works logically.
>> > > > > > > > > > >
>> > > > > > > > > > > This change I think not much quite a lot. just wrapper ima_init() with
>> > > > > > > > > > > ima_init_core() with some error handling.
>> > > > > > > > > > >
>> > > > > > > > > > > Am I missing something?
>> > > > > > > > > >
>> > > > > > > > > > Also, if we handle in ima_init() only, but it failed with other reason,
>> > > > > > > > > > we shouldn't call again ima_init() in the late_initcall_sync.
>> > > > > > > > > >
>> > > > > > > > > > To handle this, It wouldn't do in the ima_init() but we need to handle
>> > > > > > > > > > it by caller of ima_init().
>> > > > > > > > >
>> > > > > > > > > Only tpm_default_chip() is being called to set the ima_tpm_chip.  On failure,
>> > > > > > > > > instead of going into TPM-bypass mode, return immediately.  There are no calls
>> > > > > > > > > to anything else.  Just call ima_init() a second time.
>> > > > > > > >
>> > > > > > > > I’m not fully convinced this is sufficient.
>> > > > > > > >
>> > > > > > > > What I meant is the case where ima_init() fails due to other
>> > > > > > > > initialisation steps, not only tpm_default_chip() (e.g. ima_fs_init()).
>> > > > > > >
>> > > > > > > The purpose of THIS patch is to add late_initcall_sync, when the TPM is not
>> > > > > > > available at late_initcall.  This would be classified as a bug fix and would be
>> > > > > > > backported.  No other changes should be included in this patch.
>> > > > > >
>> > > > > > Okay.
>> > > > > >
>> > > > > > > >
>> > > > > > > > I’d also like to ask again whether it is fine to call
>> > > > > > > > ima_update_policy_flags() and keep the notifier registered in the
>> > > > > > > > deferred TPM case. While this may be functionally acceptable, it seems
>> > > > > > > > logically questionable to do so when ima_init() has not completed.
>> > > > > > >
>> > > > > > > Other than extending the TPM, IMA should behave exactly the same whether there
>> > > > > > > is a TPM or goes into TPM-bypass mode.
>> > > > > > >
>> > > > > > > >
>> > > > > > > > There is also a possibility that a deferred case ultimately fails (e.g.
>> > > > > > > > deferred at late_initcall, but then failing at late_initcall_sync
>> > > > > > > > for another reason, even while entering TPM bypass mode). In that case,
>> > > > > > > > it seems more appropriate to handle this state in the caller of
>> > > > > > > > ima_init(), rather than inside ima_init() itself.
>> > > > > > >
>> > > > > > > If the TPM isn't found at late_initcall_sync(), then IMA should go into TPM-
>> > > > > > > bypass mode.  Please don't make any other changes to the existing IMA behavior
>> > > > > > > and hide it here behind the late_initcall_sync change.
>> > > > > >
>> > > > > > Okay. you're talking called ima_update_policy_flags() at late_initcall
>> > > > > > wouldn't be not a problem even in case of late_initcall_sync's ima_init()
>> > > > > > get failed with "TPM-bypass mode".
>> > > > > >
>> > > > > > I see then, I'll make a patch simpler then.
>> > > > >
>> > > > > But I think in case of below situation:
>> > > > >  - late_initcall's first ima_init() is deferred.
>> > > > >  - late_initcall_sync try again but failed and try again with
>> > > > >    CONFIG_IMA_DEFAULT_HASH.
>> > > > >
>> > > > > I would like to sustain init_ima_core to reduce the same code repeat
>> > > > > in late_initcall_sync.
>> > > >
>> > > > I think what Mimi's proposing is:
>> > > >
>> > > > If we're in late_initcall, and the TPM isn't available, return
>> > > > immediately with an error (the EPROBE_DEFER?), don't do any init.
>> > > >
>> > > > If we're in late_initcall_sync, either we're already initialised, so do
>> > > > return and nothing, or run through the entire flow, even if the TPM
>> > > > isn't unavailable.
>> > > >
>> > > > So ima_init() just needs to know a) if it's in the sync or non-sync mode
>> > > > and b) for the sync mode, if we've already done the init at
>> > > > non-sync.
>> > >
>> > > Thanks, Jonathan.  That is exactly what I'm suggesting.  Any other changes
>> > > should not be included in this patch.  Since Yeoreum is not hearing me, feel
>> > > free to post a patch.
>> >
>> > I see. so what you need to is this only
>> > If it looks good to you. I'll send it at v3.
>>
>> FWIW, I pulled the tpm_default_chip check out a level to account for the
>> extra init you mentioned, and have the following (completely untested or
>> compiled, but gives the approach):
>
>Thanks, Jonathan!  It looks good.  Similarly untested/compiled.

FWIW, it does compile.

>Emitting a message on failure to initialize IMA at late_initcall is good, but
>the attestation service won't know.  Could you somehow differentiate between the
>late_initcall and late_initcall_sync boot_aggregate records?

Are you thinking "boot_aggregate" and "boot_aggregate_late" or similar 
as the "filename" on the entries, just so it's clear when we did the 
init in the log, or something else?

J.

-- 
/-\                             | 101 things you can't have too much
|@/  Debian GNU/Linux Developer |      of : 39 - silver bullets.
\-                              |


^ permalink raw reply

* Re: [PATCH] iommu/arm-smmu-v3: Allow disabling Stage 1 translation
From: Will Deacon @ 2026-04-23 17:07 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: Evangelos Petrongonas, Robin Murphy, Joerg Roedel, Nicolin Chen,
	Pranjal Shrivastava, Lu Baolu, linux-arm-kernel, iommu,
	linux-kernel, nh-open-source, Zeev Zilberman
In-Reply-To: <20260423142326.GP3611611@ziepe.ca>

On Thu, Apr 23, 2026 at 11:23:26AM -0300, Jason Gunthorpe wrote:
> On Thu, Apr 23, 2026 at 10:47:49AM +0100, Will Deacon wrote:
> > > Does iommu-pages provide a mechanism to map the memory as non-cacheable
> > > if the SMMU isn't coherent? 
> 
> No, it has to use CMOs today.
> 
> It looks like all the stuff dma_alloc_coherent does to make a
> non-cached mapping are pretty arch specific. I don't know if there is
> a way we could make more general code get a struct page into an
> uncached KVA and meet all the arch rules?
> 
> I also think dma_alloc_coherent is far to complex, with pools and
> more, to support KHO.

I wonder if there's scope for supporting just some subset of it?

> > > I really don't want to entertain CMOs for > the queues.
> > 
> > Sorry, I said "queues" here but I was really referring to any of the
> > current dma_alloc_coherent() allocations and it's the CDs that matter
> > in this thread.
> 
> queues shouldn't change they are too performance sensitive
> 
> > The rationale being that:
> > 
> > 1. A cacheable mapping is going to pollute the cache unnecessarily.
> > 2. Reasoning about atomicity and ordering is a lot more subtle with CMOs.
> 
> The page table suffers from all of these draw backs, and the STE/CD is
> touched alot less frequently. It is kind of odd to focus on these
> issues with STE/CD when page table is a much bigger problem.

I don't think it's that odd given that the STE/CD entries are bigger
than PTEs and the SMMU permits a lot more relaxations about how they are
accessed and cached compared to the PTW.

Having said that, the page-table code looks broken to me even in the
coherent case:

	ptep[i] = pte | paddr_to_iopte(paddr + i * sz, data);

as the compiler can theoretically make a right mess of that.

The non-coherent case looks more fragile, because I don't _think_ the
architecture provides any ordering or atomicity guarantees about cache
cleaning to the PoC. Presumably, the correct sequence would be to write
the PTE with the valid bit clear, do the CMO (with completion barrier),
*then* write the bottom byte with the valid bit set and do another CMO.
Sounds great!

> STE/CD is pretty simple now, there is only one place to put the CMO
> and the ordering is all handled with that shared code. We no longer
> care about ordering beyond all the writes must be visible to HW before
> issuing the CMDQ invalidation command - which is the same environment
> as the pagetable.

You presumably rely on 64-bit single-copy atomicity for hitless updates,
no?

> > 3. It seems like a pretty invasive driver change to support live update,
> >    which isn't relevant for a lot of systems.
> 
> That's sort of the whole story of live update.. Trying to keep it
> small means using the abstractions that support it like iommu-pages.
> 
> IMHO live update is OK to require coherent only, so at worst it could
> use iommu-pages on coherent systems and keep using the
> dma_alloc_coherent() for others.

That would be unfortunate, but if we can wrap the two allocators in
some common helpers then it's probably fine.

> I also don't like this "lot of systems thing". I don't want these
> powerful capabilities locked up in some giant CSP's proprietary
> kernel.  I want all the companies in the cloud market to have access
> to the same feature set. That's what open source is supposed to be
> driving toward. I have several interesting use cases for this
> functionality already.

Sorry, the point here was definitely _not_ about keeping this out of
tree, nor was I trying to say that this stuff isn't important. But the
mobile world doesn't give a hoot about KHO and _does_ tend to care about
the impact of CMO, so we have to find a way to balance the two worlds.

> It will run probably $50-100B of AI cloud servers at least, I think
> that is enough justification.

I wasn't asking for justification but I honestly don't care about the
money involved :) People need this, so we should find a way to support
it -- it just needs to fit in with everything else.

Will


^ permalink raw reply

* [PATCH 2/4] ARM: OMAP2: use sysfs_emit() in type_show
From: Thorsten Blum @ 2026-04-23 17:10 UTC (permalink / raw)
  To: Aaro Koskinen, Andreas Kemnade, Kevin Hilman, Roger Quadros,
	Tony Lindgren, Russell King
  Cc: Thorsten Blum, linux-omap, linux-arm-kernel, linux-kernel
In-Reply-To: <20260423171016.275157-5-thorsten.blum@linux.dev>

Replace unbounded sprintf() with sysfs_emit() in type_show().

Signed-off-by: Thorsten Blum <thorsten.blum@linux.dev>
---
 arch/arm/mach-omap2/id.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c
index 44d7471666a8..25ded74e4b01 100644
--- a/arch/arm/mach-omap2/id.c
+++ b/arch/arm/mach-omap2/id.c
@@ -18,6 +18,7 @@
 #include <linux/random.h>
 #include <linux/slab.h>
 #include <linux/string.h>
+#include <linux/sysfs.h>
 
 #ifdef CONFIG_SOC_BUS
 #include <linux/sys_soc.h>
@@ -771,7 +772,7 @@ static const char * __init omap_get_family(void)
 static ssize_t
 type_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
-	return sprintf(buf, "%s\n", omap_types[omap_type()]);
+	return sysfs_emit(buf, "%s\n", omap_types[omap_type()]);
 }
 
 static DEVICE_ATTR_RO(type);


^ permalink raw reply related

* [PATCH 4/4] ARM: OMAP2: zero-initialize local buffer in omap3_cpuinfo
From: Thorsten Blum @ 2026-04-23 17:10 UTC (permalink / raw)
  To: Aaro Koskinen, Andreas Kemnade, Kevin Hilman, Roger Quadros,
	Tony Lindgren, Russell King
  Cc: Thorsten Blum, linux-arm-kernel, linux-omap, linux-kernel
In-Reply-To: <20260423171016.275157-5-thorsten.blum@linux.dev>

Remove memset(0) and zero-initialize the local buffer instead.

Signed-off-by: Thorsten Blum <thorsten.blum@linux.dev>
---
 arch/arm/mach-omap2/id.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c
index 126ffd87f572..9a10e96e65e3 100644
--- a/arch/arm/mach-omap2/id.c
+++ b/arch/arm/mach-omap2/id.c
@@ -209,11 +209,9 @@ void __init omap2xxx_check_revision(void)
 static void __init omap3_cpuinfo(void)
 {
 	const char *cpu_name;
-	char buf[64];
+	char buf[64] = { 0 };
 	int n = 0;
 
-	memset(buf, 0, sizeof(buf));
-
 	/*
 	 * OMAP3430 and OMAP3530 are assumed to be same.
 	 *


^ permalink raw reply related

* [PATCH 3/4] ARM: OMAP2: clean up string copying and formatting in omap3_cpuinfo
From: Thorsten Blum @ 2026-04-23 17:10 UTC (permalink / raw)
  To: Aaro Koskinen, Andreas Kemnade, Kevin Hilman, Roger Quadros,
	Tony Lindgren, Russell King
  Cc: Thorsten Blum, linux-arm-kernel, linux-omap, linux-kernel
In-Reply-To: <20260423171016.275157-5-thorsten.blum@linux.dev>

Replace scnprintf("%s") with the faster and more direct strscpy().

Remove unnecessary and inconsistent 'n' arithmetic when 'n = 0', and
when 'n' is no longer used at the end of the function.

Signed-off-by: Thorsten Blum <thorsten.blum@linux.dev>
---
 arch/arm/mach-omap2/id.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c
index 25ded74e4b01..126ffd87f572 100644
--- a/arch/arm/mach-omap2/id.c
+++ b/arch/arm/mach-omap2/id.c
@@ -255,7 +255,7 @@ static void __init omap3_cpuinfo(void)
 	strscpy(soc_name, cpu_name);
 
 	/* Print verbose information */
-	n += scnprintf(buf, sizeof(buf) - n, "%s %s (", soc_name, soc_rev);
+	n += scnprintf(buf, sizeof(buf), "%s %s (", soc_name, soc_rev);
 
 	OMAP3_SHOW_FEATURE(l2cache);
 	OMAP3_SHOW_FEATURE(iva);
@@ -265,7 +265,7 @@ static void __init omap3_cpuinfo(void)
 	OMAP3_SHOW_FEATURE(192mhz_clk);
 	if (*(buf + n - 1) == ' ')
 		n--;
-	n += scnprintf(buf + n, sizeof(buf) - n, ")\n");
+	scnprintf(buf + n, sizeof(buf) - n, ")\n");
 	pr_info("%s", buf);
 }
 


^ permalink raw reply related

* [PATCH 1/4] ARM: OMAP2: use snprintf() in multiple check revision functions
From: Thorsten Blum @ 2026-04-23 17:10 UTC (permalink / raw)
  To: Aaro Koskinen, Andreas Kemnade, Kevin Hilman, Roger Quadros,
	Tony Lindgren, Russell King
  Cc: Thorsten Blum, linux-arm-kernel, linux-omap, linux-kernel

Replace unbounded sprintf() calls with the safer snprintf() in multiple
*_check_revision() functions.

Signed-off-by: Thorsten Blum <thorsten.blum@linux.dev>
---
 arch/arm/mach-omap2/id.c | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c
index cf2bfb447ee2..44d7471666a8 100644
--- a/arch/arm/mach-omap2/id.c
+++ b/arch/arm/mach-omap2/id.c
@@ -192,8 +192,8 @@ void __init omap2xxx_check_revision(void)
 		j = i;
 	}
 
-	sprintf(soc_name, "OMAP%04x", omap_rev() >> 16);
-	sprintf(soc_rev, "ES%x", (omap_rev() >> 12) & 0xf);
+	snprintf(soc_name, sizeof(soc_name), "OMAP%04x", omap_rev() >> 16);
+	snprintf(soc_rev, sizeof(soc_rev), "ES%x", (omap_rev() >> 12) & 0xf);
 
 	pr_info("%s", soc_name);
 	if ((omap_rev() >> 8) & 0x0f)
@@ -519,7 +519,7 @@ void __init omap3xxx_check_revision(void)
 		pr_warn("Warning: unknown chip type: hawkeye %04x, assuming OMAP3630ES1.2\n",
 			hawkeye);
 	}
-	sprintf(soc_rev, "ES%s", cpu_rev);
+	snprintf(soc_rev, sizeof(soc_rev), "ES%s", cpu_rev);
 }
 
 void __init omap4xxx_check_revision(void)
@@ -594,9 +594,9 @@ void __init omap4xxx_check_revision(void)
 		omap_revision = OMAP4430_REV_ES2_3;
 	}
 
-	sprintf(soc_name, "OMAP%04x", omap_rev() >> 16);
-	sprintf(soc_rev, "ES%d.%d", (omap_rev() >> 12) & 0xf,
-						(omap_rev() >> 8) & 0xf);
+	snprintf(soc_name, sizeof(soc_name), "OMAP%04x", omap_rev() >> 16);
+	snprintf(soc_rev, sizeof(soc_rev), "ES%d.%d", (omap_rev() >> 12) & 0xf,
+		 (omap_rev() >> 8) & 0xf);
 	pr_info("%s %s\n", soc_name, soc_rev);
 }
 
@@ -637,8 +637,8 @@ void __init omap5xxx_check_revision(void)
 		omap_revision = OMAP5430_REV_ES2_0;
 	}
 
-	sprintf(soc_name, "OMAP%04x", omap_rev() >> 16);
-	sprintf(soc_rev, "ES%d.0", (omap_rev() >> 12) & 0xf);
+	snprintf(soc_name, sizeof(soc_name), "OMAP%04x", omap_rev() >> 16);
+	snprintf(soc_rev, sizeof(soc_rev), "ES%d.0", (omap_rev() >> 12) & 0xf);
 
 	pr_info("%s %s\n", soc_name, soc_rev);
 }
@@ -712,9 +712,9 @@ void __init dra7xxx_check_revision(void)
 		omap_revision = DRA752_REV_ES2_0;
 	}
 
-	sprintf(soc_name, "DRA%03x", omap_rev() >> 16);
-	sprintf(soc_rev, "ES%d.%d", (omap_rev() >> 12) & 0xf,
-		(omap_rev() >> 8) & 0xf);
+	snprintf(soc_name, sizeof(soc_name), "DRA%03x", omap_rev() >> 16);
+	snprintf(soc_rev, sizeof(soc_rev), "ES%d.%d", (omap_rev() >> 12) & 0xf,
+		 (omap_rev() >> 8) & 0xf);
 
 	pr_info("%s %s\n", soc_name, soc_rev);
 }


^ permalink raw reply related

* Re: [RFC PATCH v2 1/4] security: ima: call ima_init() again at late_initcall_sync for defered TPM
From: Mimi Zohar @ 2026-04-23 17:13 UTC (permalink / raw)
  To: Jonathan McDowell
  Cc: Yeoreum Yun, linux-security-module, linux-kernel, linux-integrity,
	linux-arm-kernel, kvmarm, paul, jmorris, serge, roberto.sassu,
	dmitry.kasatkin, eric.snowberg, jarkko, jgg, sudeep.holla, maz,
	oupton, joey.gouly, suzuki.poulose, yuzenghui, catalin.marinas,
	will, noodles, sebastianene
In-Reply-To: <aepQwcY523aukAvw@earth.li>

On Thu, 2026-04-23 at 18:02 +0100, Jonathan McDowell wrote:
> > > > > > 
> > > > > > I think what Mimi's proposing is:
> > > > > > 
> > > > > > If we're in late_initcall, and the TPM isn't available, return
> > > > > > immediately with an error (the EPROBE_DEFER?), don't do any init.
> > > > > > 
> > > > > > If we're in late_initcall_sync, either we're already initialised, so do
> > > > > > return and nothing, or run through the entire flow, even if the TPM
> > > > > > isn't unavailable.
> > > > > > 
> > > > > > So ima_init() just needs to know a) if it's in the sync or non-sync mode
> > > > > > and b) for the sync mode, if we've already done the init at
> > > > > > non-sync.
> > > > > 
> > > > > Thanks, Jonathan.  That is exactly what I'm suggesting.  Any other changes
> > > > > should not be included in this patch.  Since Yeoreum is not hearing me, feel
> > > > > free to post a patch.
> > > > 
> > > > I see. so what you need to is this only
> > > > If it looks good to you. I'll send it at v3.
> > > 
> > > FWIW, I pulled the tpm_default_chip check out a level to account for the
> > > extra init you mentioned, and have the following (completely untested or
> > > compiled, but gives the approach):
> > 
> > Thanks, Jonathan!  It looks good.  Similarly untested/compiled.
> 
> FWIW, it does compile.
> 
> > Emitting a message on failure to initialize IMA at late_initcall is good, but
> > the attestation service won't know.  Could you somehow differentiate between the
> > late_initcall and late_initcall_sync boot_aggregate records?
> 
> Are you thinking "boot_aggregate" and "boot_aggregate_late" or similar 
> as the "filename" on the entries, just so it's clear when we did the 
> init in the log, or something else?

Perfect!

Mimi


^ permalink raw reply

* Re: [PATCH v11 00/14] barrier: Add smp_cond_load_{relaxed,acquire}_timeout()
From: Andrew Morton @ 2026-04-23 17:16 UTC (permalink / raw)
  To: Ankur Arora
  Cc: linux-kernel, linux-arch, linux-arm-kernel, linux-pm, bpf, arnd,
	catalin.marinas, will, peterz, mark.rutland, harisokn, cl, ast,
	rafael, daniel.lezcano, memxor, zhenglifeng1, xueshuai, rdunlap,
	david.laight.linux, joao.m.martins, boris.ostrovsky, konrad.wilk,
	ashok.bhat
In-Reply-To: <20260408122538.3610871-1-ankur.a.arora@oracle.com>

On Wed,  8 Apr 2026 17:55:24 +0530 Ankur Arora <ankur.a.arora@oracle.com> wrote:

> The core kernel often uses smp_cond_load_{relaxed,acquire}() to spin
> on condition variables with architectural primitives used to avoid
> hammering the relevant cachelines.
> 
> ...
> 
> Accordingly add two interfaces (with their generic and arm64 specific
> implementations):
> 
>    smp_cond_load_relaxed_timeout(ptr, cond_expr, time_expr, timeout)
>    smp_cond_load_acquire_timeout(ptr, cond_expr, time_expr, timeout)
> 
> Also add tif_need_resched_relaxed_wait() which wraps the polling
> pattern and its scheduler specific details in poll_idle().
> In addition add atomic_cond_read_*_timeout(),

Thanks, I'll add this to mm.git's mm-new branch today.

This isn't am MM patchset, but mm-new isn't included in linux-next, and
linux-next isn't presently open for 7.1 material.

After -rc1 I'll move the series into mm.git's mm-nonmm-unstable branch,
where it will get linux-next exposure.

I see that further review/comment has been requested - hopefully this
will happen over the next couple of months, but please do continue to
chase this down if you feel the need.

> Haris Okanovic also saw improvement in real workloads due to the
> cpuidle changes: "observed 4-6% improvements in memcahed, cassandra,
> mysql, and postgresql under certain loads. Other applications likely
> benefit too." [12]

Those are significant improvements.   Three years :(


^ permalink raw reply

* Re: [PATCH v3 0/3] Add i.MX94 remoteproc support and reset vector handling improvements
From: Mathieu Poirier @ 2026-04-23 17:17 UTC (permalink / raw)
  To: Peng Fan (OSS)
  Cc: Bjorn Andersson, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Frank Li, Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
	Daniel Baluta, linux-remoteproc, devicetree, imx,
	linux-arm-kernel, linux-kernel, Peng Fan
In-Reply-To: <20260415-imx943-rproc-v3-0-9fa7528db8ca@nxp.com>

On Wed, Apr 15, 2026 at 03:50:37PM +0800, Peng Fan (OSS) wrote:
> This series adds remoteproc support for the i.MX94 family, including the
> CM70, CM71, and CM33S cores, and derive the hardware reset vector for
> Cortex‑M processors whose ELF entry point does not directly correspond to
> the actual reset address.
> 
> Background:
> Cortex‑M processors fetch their initial SP and PC from a fixed reset vector
> table. While ELF images embed the entry point (e_entry), this value is
> not always aligned to the hardware reset address. On platforms such as
> i.MX94 CM33S, masking is required to compute the correct reset vector
> address before programming the SoC reset registers.
> 
> Similarly, on i.MX95, the existing implementation always programs a reset
> vector of 0x0, which only works when executing entirely from TCM. When
> firmware is loaded into DDR, the driver must pass the correct reset vector
> to the SM CPU/LMM interfaces.
> 
> Summary of patches:
> [1]dt-bindings: remoteproc: imx-rproc: Introduce fsl,reset-vector-mask
> Adds a new DT property allowing SoCs to specify a mask for deriving the
> hardware reset vector from the ELF entry point.
> 
> [2]remoteproc: imx_rproc: Program non-zero SM CPU/LMM reset vector
> Ensures the correct reset vector is passed to SM APIs by introducing a
> helper (imx_rproc_sm_get_reset_vector()) that applies the reset‑vector
> mask.
> 
> [3]remoteproc: imx_rproc: Add support for i.MX94 remoteproc
> Adds address translation tables and configuration data for CM70, CM71,
> and CM33S, enabling full remoteproc operation on i.MX94.
> 
> Signed-off-by: Peng Fan <peng.fan@nxp.com>
> ---
> Changes in v3:
> - Patch 2: 
>   Drop R-b because of changes in V3
> 
>   Following suggestion from Mathieu that apply reset vector in
>   scmi_imx_[cpu,lmm]_reset_vector_set(), not change the meaning of
>   rproc->bootaddr, add helper imx_rproc_sm_get_reset_vector() to get reset
>   vector and use the hlper in scmi_imx_[cpu,lmm]_reset_vector_set().
> 
>   Add reset-vector-mask for i.MX95 CM7 to avoid breaking i.MX95 CM7
>   boot.
> 
> - Link to v2: https://lore.kernel.org/r/20260327-imx943-rproc-v2-0-a547a3588730@nxp.com
> 
> Changes in v2:
> - Drop fsl,reset-vector-mask by using fixed value in driver for per device
> - Add R-b for i.MX94 dt-binding
> - Update commit log to include dev addr and sys addr
> - Link to v1: https://lore.kernel.org/r/20260312-imx943-rproc-v1-0-3e66596592a8@nxp.com
> 
> ---
> Peng Fan (3):
>       dt-bindings: remoteproc: imx-rproc: Support i.MX94
>       remoteproc: imx_rproc: Program non-zero SM CPU/LMM reset vector
>       remoteproc: imx_rproc: Add support for i.MX94
> 
>  .../bindings/remoteproc/fsl,imx-rproc.yaml         |  3 +
>  drivers/remoteproc/imx_rproc.c                     | 98 +++++++++++++++++++++-
>  drivers/remoteproc/imx_rproc.h                     |  2 +
>  3 files changed, 101 insertions(+), 2 deletions(-)

Much better - I'll pick this up when 7.1-rc1 comes out.

Thanks,
Mathieu

> ---
> base-commit: 724699d8d0523909da51fda8d1e10c1ff867b280
> change-id: 20260311-imx943-rproc-2050e00b65f7
> 
> Best regards,
> -- 
> Peng Fan <peng.fan@nxp.com>
> 


^ permalink raw reply


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