Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 2/5] remoteproc: switch exact-match drivers to wc-ioremap callbacks
From: Ben Levinsky @ 2026-05-14 16:21 UTC (permalink / raw)
  To: andersson, mathieu.poirier, linux-remoteproc
  Cc: Frank.Li, s.hauer, kernel, festevam, geert+renesas, magnus.damm,
	patrice.chotard, mcoquelin.stm32, alexandre.torgue,
	arnaud.pouliquen, daniel.baluta, tanmay.shah, imx,
	linux-arm-kernel, linux-kernel, linux-renesas-soc, linux-stm32
In-Reply-To: <20260514162129.1504162-1-ben.levinsky@amd.com>

Replace the exact-match carveout map and unmap callbacks in the
existing remoteproc drivers with the common wc-ioremap helpers. This
covers xlnx_r5_remoteproc, rcar_rproc, st_remoteproc, stm32_rproc,
imx_rproc, and imx_dsp_rproc.

Leave the zynqmp R5 TCM callbacks alone because they also clear the
mapped memory and are therefore not exact matches for the shared
helpers.

Signed-off-by: Ben Levinsky <ben.levinsky@amd.com>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be> # renesas
---
 drivers/remoteproc/imx_dsp_rproc.c      | 36 ++++---------------
 drivers/remoteproc/imx_rproc.c          | 32 ++---------------
 drivers/remoteproc/rcar_rproc.c         | 33 ++---------------
 drivers/remoteproc/st_remoteproc.c      | 31 ++--------------
 drivers/remoteproc/stm32_rproc.c        | 34 ++----------------
 drivers/remoteproc/xlnx_r5_remoteproc.c | 47 +++----------------------
 6 files changed, 18 insertions(+), 195 deletions(-)

diff --git a/drivers/remoteproc/imx_dsp_rproc.c b/drivers/remoteproc/imx_dsp_rproc.c
index 008741af9f11..2d9f14fbef1d 100644
--- a/drivers/remoteproc/imx_dsp_rproc.c
+++ b/drivers/remoteproc/imx_dsp_rproc.c
@@ -644,32 +644,6 @@ static void imx_dsp_rproc_free_mbox(struct imx_dsp_rproc *priv)
 	mbox_free_channel(priv->rxdb_ch);
 }
 
-static int imx_dsp_rproc_mem_alloc(struct rproc *rproc,
-				   struct rproc_mem_entry *mem)
-{
-	struct device *dev = rproc->dev.parent;
-	void *va;
-
-	va = ioremap_wc(mem->dma, mem->len);
-	if (!va) {
-		dev_err(dev, "Unable to map memory region: %pa+%zx\n",
-			&mem->dma, mem->len);
-		return -ENOMEM;
-	}
-
-	mem->va = va;
-
-	return 0;
-}
-
-static int imx_dsp_rproc_mem_release(struct rproc *rproc,
-				     struct rproc_mem_entry *mem)
-{
-	iounmap(mem->va);
-
-	return 0;
-}
-
 /**
  * imx_dsp_rproc_add_carveout() - request mailbox channels
  * @priv: private data pointer
@@ -700,8 +674,10 @@ static int imx_dsp_rproc_add_carveout(struct imx_dsp_rproc *priv)
 
 		/* Register memory region */
 		mem = rproc_mem_entry_init(dev, NULL, (dma_addr_t)att->sa,
-					   att->size, da, imx_dsp_rproc_mem_alloc,
-					   imx_dsp_rproc_mem_release, "dsp_mem");
+					   att->size, da,
+					   rproc_mem_entry_ioremap_wc,
+					   rproc_mem_entry_iounmap,
+					   "dsp_mem");
 
 		if (mem)
 			rproc_coredump_add_segment(rproc, da, att->size);
@@ -732,8 +708,8 @@ static int imx_dsp_rproc_add_carveout(struct imx_dsp_rproc *priv)
 		/* Register memory region */
 		mem = rproc_mem_entry_init(dev, NULL, (dma_addr_t)res.start,
 					   resource_size(&res), da,
-					    imx_dsp_rproc_mem_alloc,
-					    imx_dsp_rproc_mem_release,
+					   rproc_mem_entry_ioremap_wc,
+					   rproc_mem_entry_iounmap,
 					   "%.*s", strchrnul(res.name, '@') - res.name, res.name);
 		if (!mem)
 			return -ENOMEM;
diff --git a/drivers/remoteproc/imx_rproc.c b/drivers/remoteproc/imx_rproc.c
index 7f54322244ac..6249815b54d8 100644
--- a/drivers/remoteproc/imx_rproc.c
+++ b/drivers/remoteproc/imx_rproc.c
@@ -600,35 +600,6 @@ static void *imx_rproc_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *i
 	return va;
 }
 
-static int imx_rproc_mem_alloc(struct rproc *rproc,
-			       struct rproc_mem_entry *mem)
-{
-	struct device *dev = rproc->dev.parent;
-	void *va;
-
-	dev_dbg(dev, "map memory: %p+%zx\n", &mem->dma, mem->len);
-	va = ioremap_wc(mem->dma, mem->len);
-	if (IS_ERR_OR_NULL(va)) {
-		dev_err(dev, "Unable to map memory region: %p+%zx\n",
-			&mem->dma, mem->len);
-		return -ENOMEM;
-	}
-
-	/* Update memory entry va */
-	mem->va = va;
-
-	return 0;
-}
-
-static int imx_rproc_mem_release(struct rproc *rproc,
-				 struct rproc_mem_entry *mem)
-{
-	dev_dbg(rproc->dev.parent, "unmap memory: %pa\n", &mem->dma);
-	iounmap(mem->va);
-
-	return 0;
-}
-
 static int imx_rproc_sm_lmm_prepare(struct rproc *rproc)
 {
 	struct imx_rproc *priv = rproc->priv;
@@ -692,7 +663,8 @@ static int imx_rproc_prepare(struct rproc *rproc)
 		/* Register memory region */
 		mem = rproc_mem_entry_init(priv->dev, NULL, (dma_addr_t)res.start,
 					   resource_size(&res), da,
-					   imx_rproc_mem_alloc, imx_rproc_mem_release,
+					   rproc_mem_entry_ioremap_wc,
+					   rproc_mem_entry_iounmap,
 					   "%.*s", strchrnul(res.name, '@') - res.name,
 					   res.name);
 		if (!mem)
diff --git a/drivers/remoteproc/rcar_rproc.c b/drivers/remoteproc/rcar_rproc.c
index 3c25625f966d..e3121fadd292 100644
--- a/drivers/remoteproc/rcar_rproc.c
+++ b/drivers/remoteproc/rcar_rproc.c
@@ -19,35 +19,6 @@ struct rcar_rproc {
 	struct reset_control *rst;
 };
 
-static int rcar_rproc_mem_alloc(struct rproc *rproc,
-				 struct rproc_mem_entry *mem)
-{
-	struct device *dev = &rproc->dev;
-	void *va;
-
-	dev_dbg(dev, "map memory: %pa+%zx\n", &mem->dma, mem->len);
-	va = ioremap_wc(mem->dma, mem->len);
-	if (!va) {
-		dev_err(dev, "Unable to map memory region: %pa+%zx\n",
-			&mem->dma, mem->len);
-		return -ENOMEM;
-	}
-
-	/* Update memory entry va */
-	mem->va = va;
-
-	return 0;
-}
-
-static int rcar_rproc_mem_release(struct rproc *rproc,
-				   struct rproc_mem_entry *mem)
-{
-	dev_dbg(&rproc->dev, "unmap memory: %pa\n", &mem->dma);
-	iounmap(mem->va);
-
-	return 0;
-}
-
 static int rcar_rproc_prepare(struct rproc *rproc)
 {
 	struct device *dev = rproc->dev.parent;
@@ -73,8 +44,8 @@ static int rcar_rproc_prepare(struct rproc *rproc)
 		mem = rproc_mem_entry_init(dev, NULL,
 					   res.start,
 					   resource_size(&res), da,
-					   rcar_rproc_mem_alloc,
-					   rcar_rproc_mem_release,
+					   rproc_mem_entry_ioremap_wc,
+					   rproc_mem_entry_iounmap,
 					   res.name);
 
 		if (!mem)
diff --git a/drivers/remoteproc/st_remoteproc.c b/drivers/remoteproc/st_remoteproc.c
index a07edf7217d2..486180cdccb4 100644
--- a/drivers/remoteproc/st_remoteproc.c
+++ b/drivers/remoteproc/st_remoteproc.c
@@ -88,33 +88,6 @@ static void st_rproc_kick(struct rproc *rproc, int vqid)
 		dev_err(dev, "failed to send message via mbox: %d\n", ret);
 }
 
-static int st_rproc_mem_alloc(struct rproc *rproc,
-			      struct rproc_mem_entry *mem)
-{
-	struct device *dev = rproc->dev.parent;
-	void *va;
-
-	va = ioremap_wc(mem->dma, mem->len);
-	if (!va) {
-		dev_err(dev, "Unable to map memory region: %pa+%zx\n",
-			&mem->dma, mem->len);
-		return -ENOMEM;
-	}
-
-	/* Update memory entry va */
-	mem->va = va;
-
-	return 0;
-}
-
-static int st_rproc_mem_release(struct rproc *rproc,
-				struct rproc_mem_entry *mem)
-{
-	iounmap(mem->va);
-
-	return 0;
-}
-
 static int st_rproc_parse_fw(struct rproc *rproc, const struct firmware *fw)
 {
 	struct device *dev = rproc->dev.parent;
@@ -138,8 +111,8 @@ static int st_rproc_parse_fw(struct rproc *rproc, const struct firmware *fw)
 			mem = rproc_mem_entry_init(dev, NULL,
 						   (dma_addr_t)res.start,
 						   resource_size(&res), res.start,
-						   st_rproc_mem_alloc,
-						   st_rproc_mem_release,
+						   rproc_mem_entry_ioremap_wc,
+						   rproc_mem_entry_iounmap,
 						   "%.*s",
 						   strchrnul(res.name, '@') - res.name,
 						   res.name);
diff --git a/drivers/remoteproc/stm32_rproc.c b/drivers/remoteproc/stm32_rproc.c
index 632614013dc6..7ac8265b60ac 100644
--- a/drivers/remoteproc/stm32_rproc.c
+++ b/drivers/remoteproc/stm32_rproc.c
@@ -113,35 +113,6 @@ static int stm32_rproc_pa_to_da(struct rproc *rproc, phys_addr_t pa, u64 *da)
 	return -EINVAL;
 }
 
-static int stm32_rproc_mem_alloc(struct rproc *rproc,
-				 struct rproc_mem_entry *mem)
-{
-	struct device *dev = rproc->dev.parent;
-	void *va;
-
-	dev_dbg(dev, "map memory: %pad+%zx\n", &mem->dma, mem->len);
-	va = (__force void *)ioremap_wc(mem->dma, mem->len);
-	if (IS_ERR_OR_NULL(va)) {
-		dev_err(dev, "Unable to map memory region: %pad+0x%zx\n",
-			&mem->dma, mem->len);
-		return -ENOMEM;
-	}
-
-	/* Update memory entry va */
-	mem->va = va;
-
-	return 0;
-}
-
-static int stm32_rproc_mem_release(struct rproc *rproc,
-				   struct rproc_mem_entry *mem)
-{
-	dev_dbg(rproc->dev.parent, "unmap memory: %pa\n", &mem->dma);
-	iounmap((__force __iomem void *)mem->va);
-
-	return 0;
-}
-
 static int stm32_rproc_of_memory_translations(struct platform_device *pdev,
 					      struct stm32_rproc *ddata)
 {
@@ -237,8 +208,8 @@ static int stm32_rproc_prepare(struct rproc *rproc)
 			mem = rproc_mem_entry_init(dev, NULL,
 						   (dma_addr_t)res.start,
 						   resource_size(&res), da,
-						   stm32_rproc_mem_alloc,
-						   stm32_rproc_mem_release,
+						   rproc_mem_entry_ioremap_wc,
+						   rproc_mem_entry_iounmap,
 						   "%.*s", strchrnul(res.name, '@') - res.name,
 						   res.name);
 			if (mem)
@@ -957,4 +928,3 @@ MODULE_DESCRIPTION("STM32 Remote Processor Control Driver");
 MODULE_AUTHOR("Ludovic Barre <ludovic.barre@st.com>");
 MODULE_AUTHOR("Fabien Dessenne <fabien.dessenne@st.com>");
 MODULE_LICENSE("GPL v2");
-
diff --git a/drivers/remoteproc/xlnx_r5_remoteproc.c b/drivers/remoteproc/xlnx_r5_remoteproc.c
index 45a62cb98072..e5d1903c9636 100644
--- a/drivers/remoteproc/xlnx_r5_remoteproc.c
+++ b/drivers/remoteproc/xlnx_r5_remoteproc.c
@@ -447,45 +447,6 @@ static int zynqmp_r5_rproc_stop(struct rproc *rproc)
 	return ret;
 }
 
-/*
- * zynqmp_r5_mem_region_map()
- * @rproc: single R5 core's corresponding rproc instance
- * @mem: mem descriptor to map reserved memory-regions
- *
- * Callback to map va for memory-region's carveout.
- *
- * return 0 on success, otherwise non-zero value on failure
- */
-static int zynqmp_r5_mem_region_map(struct rproc *rproc,
-				    struct rproc_mem_entry *mem)
-{
-	void __iomem *va;
-
-	va = ioremap_wc(mem->dma, mem->len);
-	if (IS_ERR_OR_NULL(va))
-		return -ENOMEM;
-
-	mem->va = (void *)va;
-
-	return 0;
-}
-
-/*
- * zynqmp_r5_rproc_mem_unmap
- * @rproc: single R5 core's corresponding rproc instance
- * @mem: mem entry to unmap
- *
- * Unmap memory-region carveout
- *
- * return: always returns 0
- */
-static int zynqmp_r5_mem_region_unmap(struct rproc *rproc,
-				      struct rproc_mem_entry *mem)
-{
-	iounmap((void __iomem *)mem->va);
-	return 0;
-}
-
 /*
  * add_mem_regions_carveout()
  * @rproc: single R5 core's corresponding rproc instance
@@ -522,8 +483,8 @@ static int add_mem_regions_carveout(struct rproc *rproc)
 			rproc_mem = rproc_mem_entry_init(&rproc->dev, NULL,
 							 (dma_addr_t)res.start,
 							 resource_size(&res), res.start,
-							 zynqmp_r5_mem_region_map,
-							 zynqmp_r5_mem_region_unmap,
+							 rproc_mem_entry_ioremap_wc,
+							 rproc_mem_entry_iounmap,
 							 "%.*s",
 							 strchrnul(res.name, '@') - res.name,
 							 res.name);
@@ -560,8 +521,8 @@ static int add_sram_carveouts(struct rproc *rproc)
 		rproc_mem = rproc_mem_entry_init(&rproc->dev, NULL,
 						 dma_addr,
 						 len, da,
-						 zynqmp_r5_mem_region_map,
-						 zynqmp_r5_mem_region_unmap,
+						 rproc_mem_entry_ioremap_wc,
+						 rproc_mem_entry_iounmap,
 						 sram->sram_res.name);
 		if (!rproc_mem) {
 			dev_err(&rproc->dev, "failed to add sram %s da=0x%x, size=0x%lx",
-- 
2.34.1



^ permalink raw reply related

* [PATCH v2 4/5] remoteproc: add helper for optional ELF resource tables
From: Ben Levinsky @ 2026-05-14 16:21 UTC (permalink / raw)
  To: andersson, mathieu.poirier, linux-remoteproc
  Cc: Frank.Li, s.hauer, kernel, festevam, geert+renesas, magnus.damm,
	patrice.chotard, mcoquelin.stm32, alexandre.torgue,
	arnaud.pouliquen, daniel.baluta, tanmay.shah, imx,
	linux-arm-kernel, linux-kernel, linux-renesas-soc, linux-stm32
In-Reply-To: <20260514162129.1504162-1-ben.levinsky@amd.com>

Add a small helper around rproc_elf_load_rsc_table() for remoteproc
drivers that treat a missing ELF resource table as optional. The helper
returns success on -EINVAL and propagates other failures unchanged.

Keep logging policy out of the helper so platform drivers can decide
whether a missing resource table should be reported and at what log
level.

Signed-off-by: Ben Levinsky <ben.levinsky@amd.com>
---
 drivers/remoteproc/remoteproc_internal.h | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/remoteproc/remoteproc_internal.h b/drivers/remoteproc/remoteproc_internal.h
index 9955e512f073..565b35256945 100644
--- a/drivers/remoteproc/remoteproc_internal.h
+++ b/drivers/remoteproc/remoteproc_internal.h
@@ -149,6 +149,15 @@ static inline int rproc_mem_entry_iounmap(struct rproc *rproc,
 	return 0;
 }
 
+static inline int rproc_elf_load_rsc_table_optional(struct rproc *rproc,
+						    const struct firmware *fw)
+{
+	int ret;
+
+	ret = rproc_elf_load_rsc_table(rproc, fw);
+	return ret == -EINVAL ? 0 : ret;
+}
+
 static inline int rproc_prepare_device(struct rproc *rproc)
 {
 	if (rproc->ops->prepare)
-- 
2.34.1



^ permalink raw reply related

* [PATCH v2 0/5] remoteproc: cleanup shared carveout and resource-table helpers
From: Ben Levinsky @ 2026-05-14 16:21 UTC (permalink / raw)
  To: andersson, mathieu.poirier, linux-remoteproc
  Cc: Frank.Li, s.hauer, kernel, festevam, geert+renesas, magnus.damm,
	patrice.chotard, mcoquelin.stm32, alexandre.torgue,
	arnaud.pouliquen, daniel.baluta, tanmay.shah, imx,
	linux-arm-kernel, linux-kernel, linux-renesas-soc, linux-stm32

This series is a preparatory remoteproc cleanup split out from review of
the AMD BRAM-based remoteproc series.

During review, there was a request to move the duplicated plain
ioremap_wc()/iounmap() carveout callbacks into common code and to
factor the "missing resource table is OK" ELF parsing path into a
common helper as well. There was also a request to send that cleanup as
its own patchset first, with the AMD BRAM series respun afterwards on
top once this cleanup is merged.

This version keeps the same overall cleanup goals as v1, but reworks
the series based on review:

  - keep the shared wc-ioremap callback addition behavior-neutral
  - add the common ioremap failure message in the shared helper
  - split mem->is_iomem handling into its own follow-up patch with
    framework-level justification
  - keep logging policy out of the optional resource-table helper
  - retain thin driver-local parse_fw() wrappers so each platform keeps
    control over whether the missing-table case is logged and at what
    level

This series now does that in five patches:

  1. add common subsystem-private callbacks for the exact-match
     wc-ioremap carveout case
  2. switch the in-tree exact-match users over to those callbacks
  3. mark carveouts mapped through the shared wc-ioremap helper as
     iomem so the framework uses the proper I/O accessors
  4. add a common helper for drivers that treat a missing ELF resource
     table as optional, returning success on -EINVAL and propagating
     other errors unchanged
  5. switch the matching in-tree drivers over to that helper while
     keeping per-driver logging decisions local

For the carveout map/unmap cleanup, this series covers the exact-match
users called out in review: xlnx_r5_remoteproc, rcar_rproc,
st_remoteproc, stm32_rproc, imx_rproc, and imx_dsp_rproc. The zynqmp R5
TCM mapping path is left alone because it also clears the mapped memory
and is not an exact match.

For the optional resource-table handling, this series converts
xlnx_r5_remoteproc, rcar_rproc, stm32_rproc, imx_rproc, and
imx_dsp_rproc. st_remoteproc is intentionally left unchanged because its
parse_fw() callback also builds carveouts and is therefore not a direct
match for the helper introduced here.

Changes in v2:
  - split the mem->is_iomem change out into a separate patch
  - add a common error message on ioremap_wc() failure
  - drop logging from the optional resource-table helper
  - keep driver-local parse_fw() wrappers to preserve per-platform
    missing-resource-table logging policy

Ben Levinsky (5):
  remoteproc: add common wc-ioremap carveout callbacks
  remoteproc: switch exact-match drivers to wc-ioremap callbacks
  remoteproc: mark wc-ioremap carveouts as iomem
  remoteproc: add helper for optional ELF resource tables
  remoteproc: switch drivers to optional resource-table helper

 drivers/remoteproc/imx_dsp_rproc.c       | 60 ++++++----------
 drivers/remoteproc/imx_rproc.c           | 57 +++++----------
 drivers/remoteproc/rcar_rproc.c          | 58 +++++-----------
 drivers/remoteproc/remoteproc_internal.h | 38 +++++++++-
 drivers/remoteproc/st_remoteproc.c       | 31 +--------
 drivers/remoteproc/stm32_rproc.c         | 57 +++++----------
 drivers/remoteproc/xlnx_r5_remoteproc.c  | 88 +++++-------------------
 7 files changed, 128 insertions(+), 261 deletions(-)

-- 
2.34.1


^ permalink raw reply

* [PATCH v2 1/5] remoteproc: add common wc-ioremap carveout callbacks
From: Ben Levinsky @ 2026-05-14 16:21 UTC (permalink / raw)
  To: andersson, mathieu.poirier, linux-remoteproc
  Cc: Frank.Li, s.hauer, kernel, festevam, geert+renesas, magnus.damm,
	patrice.chotard, mcoquelin.stm32, alexandre.torgue,
	arnaud.pouliquen, daniel.baluta, tanmay.shah, imx,
	linux-arm-kernel, linux-kernel, linux-renesas-soc, linux-stm32
In-Reply-To: <20260514162129.1504162-1-ben.levinsky@amd.com>

Several remoteproc drivers open-code the same ioremap_wc() and
iounmap() callbacks for carveout mappings. Add subsystem-private
helpers in remoteproc_internal.h so those drivers can share the same
implementation.

Keep this change behavior-neutral. The helper now emits a common error
message on ioremap_wc() failure, but leaves mem->is_iomem handling to a
follow-on patch so that the behavioral change can be justified
separately.

Signed-off-by: Ben Levinsky <ben.levinsky@amd.com>
---
 drivers/remoteproc/remoteproc_internal.h | 28 +++++++++++++++++++++++-
 1 file changed, 27 insertions(+), 1 deletion(-)

diff --git a/drivers/remoteproc/remoteproc_internal.h b/drivers/remoteproc/remoteproc_internal.h
index 0a5e15744b1d..f5b34aabed5b 100644
--- a/drivers/remoteproc/remoteproc_internal.h
+++ b/drivers/remoteproc/remoteproc_internal.h
@@ -12,8 +12,9 @@
 #ifndef REMOTEPROC_INTERNAL_H
 #define REMOTEPROC_INTERNAL_H
 
-#include <linux/irqreturn.h>
 #include <linux/firmware.h>
+#include <linux/io.h>
+#include <linux/irqreturn.h>
 
 struct rproc;
 
@@ -122,6 +123,31 @@ rproc_find_carveout_by_name(struct rproc *rproc, const char *name, ...);
 void rproc_add_rvdev(struct rproc *rproc, struct rproc_vdev *rvdev);
 void rproc_remove_rvdev(struct rproc_vdev *rvdev);
 
+static inline int rproc_mem_entry_ioremap_wc(struct rproc *rproc,
+					     struct rproc_mem_entry *mem)
+{
+	void __iomem *va;
+
+	va = ioremap_wc(mem->dma, mem->len);
+	if (!va) {
+		dev_err(&rproc->dev, "Unable to map memory region: %pa+%zx\n",
+			&mem->dma, mem->len);
+		return -ENOMEM;
+	}
+
+	mem->va = (__force void *)va;
+
+	return 0;
+}
+
+static inline int rproc_mem_entry_iounmap(struct rproc *rproc,
+					  struct rproc_mem_entry *mem)
+{
+	iounmap((__force __iomem void *)mem->va);
+
+	return 0;
+}
+
 static inline int rproc_prepare_device(struct rproc *rproc)
 {
 	if (rproc->ops->prepare)
-- 
2.34.1



^ permalink raw reply related

* Re: [PATCH] phy: mediatek: xsphy: reduce main allocation
From: Vinod Koul @ 2026-05-14 16:18 UTC (permalink / raw)
  To: linux-phy, Rosen Penev
  Cc: Chunfeng Yun, Neil Armstrong, Matthias Brugger,
	AngeloGioacchino Del Regno, Kees Cook, Gustavo A. R. Silva,
	linux-arm-kernel, linux-mediatek, linux-kernel, linux-hardening
In-Reply-To: <20260304043420.14151-1-rosenp@gmail.com>


On Tue, 03 Mar 2026 20:34:20 -0800, Rosen Penev wrote:
> Instead of kzalloc and kcalloc, we can use a flex array to reduce to a
> single allocation.
> 
> Also added __counted_by() for extra possible analysis.
> 
> 

Applied, thanks!

[1/1] phy: mediatek: xsphy: reduce main allocation
      commit: fd6cd05ceabdf67635a4cef5145f79d1217bf11b

Best regards,
-- 
~Vinod




^ permalink raw reply

* Re: [PATCH v2 0/5] rockchip: Add USB 2.0 support for RK3528
From: Vinod Koul @ 2026-05-14 16:17 UTC (permalink / raw)
  To: Heiko Stuebner
  Cc: neil.armstrong, robh, krzk+dt, conor+dt, linux-phy, devicetree,
	linux-arm-kernel, linux-rockchip, linux-kernel, jonas
In-Reply-To: <20260505170410.3265305-1-heiko@sntech.de>


On Tue, 05 May 2026 19:04:05 +0200, Heiko Stuebner wrote:
> This series adds support for USB 2.0 on Rockchip RK3528 to the
> Innosilicon usbphy driver.
> 
> The usb3 support has already been merge for the naneng combophy
> last year.
> 
> Changes in v2:
> - rebase on top of v7.1-rc1
> - split off dwc3 compatible and dts changes
> - add error handling to regmap_write (Vinod)
> - v1 is here
>   https://lore.kernel.org/linux-rockchip/20250723122323.2344916-1-jonas@kwiboo.se/
> 
> [...]

Applied, thanks!

[1/5] dt-bindings: phy: rockchip,inno-usb2phy: Require GRF for RK3568/RV1108
      commit: a896852613136e6babe6036567ab0989fb322a57
[2/5] phy: rockchip: inno-usb2: Simplify rockchip,usbgrf handling
      commit: be29cd958f5393004a24cd7b5b1da88dd90a651b
[3/5] dt-bindings: phy: rockchip,inno-usb2phy: Add compatible for RK3528
      commit: c430f042f4ba2c5abd592b6924f028d3bb09d4cf
[4/5] phy: rockchip: inno-usb2: Add clkout_ctl_phy support
      commit: 2775541de0580ab1cd077dfef710e6316563d567
[5/5] phy: rockchip: inno-usb2: Add support for RK3528
      commit: 864b3617df827865a95a06f06f09a8d57a795b91

Best regards,
-- 
~Vinod




^ permalink raw reply

* Re: [PATCH v2 4/5] phy: rockchip: inno-usb2: Add clkout_ctl_phy support
From: Vinod Koul @ 2026-05-14 16:17 UTC (permalink / raw)
  To: Heiko Stuebner
  Cc: neil.armstrong, robh, krzk+dt, conor+dt, linux-phy, devicetree,
	linux-arm-kernel, linux-rockchip, linux-kernel, jonas
In-Reply-To: <20260505170410.3265305-5-heiko@sntech.de>

On 05-05-26, 19:04, Heiko Stuebner wrote:
> From: Jonas Karlman <jonas@kwiboo.se>
> 
> The 480m clk is controlled using regs in the PHY address space and not
> in the USB GRF address space on e.g. RK3528 and RK3506.
> 
> Add a clkout_ctl_phy usb2phy_reg to handle enable/disable of the 480m
> clk on these SoCs.
> 
> Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
> Signed-off-by: Heiko Stuebner <heiko@sntech.de>
> ---
>  drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 47 +++++++++++++++----
>  1 file changed, 38 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
> index 7cec45192393..d8879fcd4291 100644
> --- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
> +++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
> @@ -179,6 +179,7 @@ struct rockchip_usb2phy_cfg {
>  	unsigned int	num_ports;
>  	int (*phy_tuning)(struct rockchip_usb2phy *rphy);
>  	struct usb2phy_reg	clkout_ctl;
> +	struct usb2phy_reg	clkout_ctl_phy;

This gives a kernel-doc warning. I have applied please send fix for this

-- 
~Vinod


^ permalink raw reply

* Re: [PATCH 03/10] dt-bindings: clock: Add Amlogic A9 peripherals clock controller
From: Jerome Brunet @ 2026-05-14 16:15 UTC (permalink / raw)
  To: Jian Hu via B4 Relay
  Cc: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Neil Armstrong, Xianwei Zhao, Kevin Hilman,
	Martin Blumenstingl, jian.hu, linux-kernel, linux-clk, devicetree,
	linux-amlogic, linux-arm-kernel
In-Reply-To: <20260511-b4-a9_clk-v1-3-41cb4071b7c9@amlogic.com>

On lun. 11 mai 2026 at 20:47, Jian Hu via B4 Relay <devnull+jian.hu.amlogic.com@kernel.org> wrote:

> From: Jian Hu <jian.hu@amlogic.com>
>
> Add the peripherals clock controller dt-bindings for the Amlogic A9
> SoC family.
>
> Signed-off-by: Jian Hu <jian.hu@amlogic.com>
> ---
>  .../clock/amlogic,a9-peripherals-clkc.yaml         | 150 +++++++++
>  .../clock/amlogic,a9-peripherals-clkc.h            | 352 +++++++++++++++++++++
>  2 files changed, 502 insertions(+)
>
> diff --git
> a/Documentation/devicetree/bindings/clock/amlogic,a9-peripherals-clkc.yaml
> b/Documentation/devicetree/bindings/clock/amlogic,a9-peripherals-clkc.yaml
> new file mode 100644
> index 000000000000..97e2c44d8630
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/amlogic,a9-peripherals-clkc.yaml
> @@ -0,0 +1,150 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +# Copyright (C) 2026 Amlogic, Inc. All rights reserved
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/clock/amlogic,a9-peripherals-clkc.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Amlogic A9 Series Peripherals Clock Controller
> +
> +maintainers:
> +  - Neil Armstrong <neil.armstrong@linaro.org>
> +  - Jerome Brunet <jbrunet@baylibre.com>
> +  - Jian Hu <jian.hu@amlogic.com>
> +  - Xianwei Zhao <xianwei.zhao@amlogic.com>
> +
> +properties:
> +  compatible:
> +    const: amlogic,a9-peripherals-clkc
> +
> +  reg:
> +    maxItems: 1
> +
> +  '#clock-cells':
> +    const: 1
> +
> +  clocks:
> +    minItems: 20
> +    items:
> +      - description: input oscillator
> +      - description: input fclk div 2
> +      - description: input fclk div 3
> +      - description: input fclk div 4
> +      - description: input fclk div 5
> +      - description: input fclk div 7
> +      - description: input fclk div 2p5
> +      - description: input sys clk
> +      - description: input gp1 pll
> +      - description: input gp2 pll
> +      - description: input sys pll div 16
> +      - description: input cpu clk div 16
> +      - description: input a78 clk div 16
> +      - description: input dsu clk div 16
> +      - description: input rtc clk
> +      - description: input gp0 pll
> +      - description: input hifi0 pll
> +      - description: input hifi1 pll
> +      - description: input mclk0 pll
> +      - description: input mclk1 pll
> +      - description: input video1 pll (optional)
> +      - description: input video2 pll (optional)
> +      - description: input hdmi out2 clk (optional)
> +      - description: input hdmi pixel clk (optional)
> +      - description: input pixel0 pll (optional)
> +      - description: input pixel1 pll (optional)
> +      - description: input usb2 drd clk (optional)

Why are those optional ? they seem internal to the SoC.
If so, they don't have a reason to be optional

> +      - description: external input rmii oscillator (optional)
> +
> +  clock-names:
> +    minItems: 20
> +    items:
> +      - const: xtal
> +      - const: fdiv2
> +      - const: fdiv3
> +      - const: fdiv4
> +      - const: fdiv5
> +      - const: fdiv7
> +      - const: fdiv2p5
> +      - const: sys
> +      - const: gp1
> +      - const: gp2
> +      - const: sysplldiv16
> +      - const: cpudiv16
> +      - const: a78div16
> +      - const: dsudiv16
> +      - const: rtc
> +      - const: gp0
> +      - const: hifi0
> +      - const: hifi1
> +      - const: mclk0
> +      - const: mclk1
> +      - const: vid1
> +      - const: vid2
> +      - const: hdmiout2
> +      - const: hdmipix
> +      - const: pix0
> +      - const: pix1
> +      - const: u2drd
> +      - const: ext_rmii
> +
> +required:
> +  - compatible
> +  - reg
> +  - '#clock-cells'
> +  - clocks
> +  - clock-names
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    apb4 {
> +        #address-cells = <2>;
> +        #size-cells = <2>;
> +
> +        clock-controller@200 {
> +            compatible = "amlogic,a9-peripherals-clkc";
> +            reg = <0x0 0x200 0x0 0x2f8>;
> +            #clock-cells = <1>;
> +            clocks = <&xtal>,
> +                     <&scmi_clk 10>,
> +                     <&scmi_clk 12>,
> +                     <&scmi_clk 14>,
> +                     <&scmi_clk 16>,
> +                     <&scmi_clk 18>,
> +                     <&scmi_clk 20>,
> +                     <&scmi_clk 21>,
> +                     <&scmi_clk 33>,
> +                     <&scmi_clk 34>,
> +                     <&scmi_clk 35>,
> +                     <&scmi_clk 36>,
> +                     <&scmi_clk 37>,
> +                     <&scmi_clk 38>,
> +                     <&scmi_clk 40>,
> +                     <&gp0 3>,
> +                     <&hifi0 3>,
> +                     <&hifi1 3>,
> +                     <&mclk0 3>,
> +                     <&mclk1 3>;
> +            clock-names = "xtal",
> +                          "fdiv2",
> +                          "fdiv3",
> +                          "fdiv4",
> +                          "fdiv5",
> +                          "fdiv7",
> +                          "fdiv2p5",
> +                          "sys",
> +                          "gp1",
> +                          "gp2",
> +                          "sysplldiv16",
> +                          "cpudiv16",
> +                          "a78div16",
> +                          "dsudiv16",
> +                          "rtc",
> +                          "gp0",
> +                          "hifi0",
> +                          "hifi1",
> +                          "mclk0",
> +                          "mclk1";
> +        };
> +    };
> diff --git a/include/dt-bindings/clock/amlogic,a9-peripherals-clkc.h b/include/dt-bindings/clock/amlogic,a9-peripherals-clkc.h
> new file mode 100644
> index 000000000000..bca69771d728
> --- /dev/null
> +++ b/include/dt-bindings/clock/amlogic,a9-peripherals-clkc.h
> @@ -0,0 +1,352 @@
> +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
> +/*
> + * Copyright (C) 2026 Amlogic, Inc. All rights reserved.
> + */
> +
> +#ifndef __AMLOGIC_A9_PERIPHERALS_CLKC_H
> +#define __AMLOGIC_A9_PERIPHERALS_CLKC_H
> +
> +#define CLKID_SYS_AM_AXI			0
> +#define CLKID_SYS_DOS				1
> +#define CLKID_SYS_MIPI_DSI			2
> +#define CLKID_SYS_ETH_PHY			3
> +#define CLKID_SYS_AMFC				4
> +#define CLKID_SYS_MALI				5
> +#define CLKID_SYS_NNA				6
> +#define CLKID_SYS_ETH_AXI			7
> +#define CLKID_SYS_DP_APB			8
> +#define CLKID_SYS_EDPTX_APB			9
> +#define CLKID_SYS_U3HSG				10
> +#define CLKID_SYS_AUCPU				11
> +#define CLKID_SYS_GLB				12
> +#define CLKID_SYS_COMBO_DPHY_APB		13
> +#define CLKID_SYS_HDMIRX_APB			14
> +#define CLKID_SYS_HDMIRX_PCLK			15
> +#define CLKID_SYS_MIPI_DSI_PHY			16
> +#define CLKID_SYS_CAN0				17
> +#define CLKID_SYS_CAN1				18
> +#define CLKID_SYS_SD_EMMC_A			19
> +#define CLKID_SYS_SD_EMMC_B			20
> +#define CLKID_SYS_SD_EMMC_C			21
> +#define CLKID_SYS_SC				22
> +#define CLKID_SYS_ACODEC			23
> +#define CLKID_SYS_MIPI_ISP			24
> +#define CLKID_SYS_MSR				25
> +#define CLKID_SYS_AUDIO				26
> +#define CLKID_SYS_MIPI_DSI_B			27
> +#define CLKID_SYS_MIPI_DSI1_PHY			28
> +#define CLKID_SYS_ETH				29
> +#define CLKID_SYS_ETH_1G_MAC			30
> +#define CLKID_SYS_UART_A			31
> +#define CLKID_SYS_UART_F			32
> +#define CLKID_SYS_TS_A55			33
> +#define CLKID_SYS_ETH_1G_AXI			34
> +#define CLKID_SYS_TS_DOS			35
> +#define CLKID_SYS_U3DRD_B			36
> +#define CLKID_SYS_TS_CORE			37
> +#define CLKID_SYS_TS_PLL			38
> +#define CLKID_SYS_CSI_DIG_CLKIN			39
> +#define CLKID_SYS_CVE				40
> +#define CLKID_SYS_GE2D				41
> +#define CLKID_SYS_SPISG				42
> +#define CLKID_SYS_U3DRD_1			43
> +#define CLKID_SYS_U2H				44
> +#define CLKID_SYS_PCIE_MAC_A			45
> +#define CLKID_SYS_U3DRD_A			46
> +#define CLKID_SYS_U2DRD				47
> +#define CLKID_SYS_PCIE_PHY			48
> +#define CLKID_SYS_PCIE_MAC_B			49
> +#define CLKID_SYS_PERIPH			50
> +#define CLKID_SYS_PIO				51
> +#define CLKID_SYS_I3C				52
> +#define CLKID_SYS_I2C_M_E			53
> +#define CLKID_SYS_I2C_M_F			54
> +#define CLKID_SYS_HDMITX_APB			55
> +#define CLKID_SYS_I2C_M_I			56
> +#define CLKID_SYS_I2C_M_G			57
> +#define CLKID_SYS_I2C_M_H			58
> +#define CLKID_SYS_HDMI20_AES			59
> +#define CLKID_SYS_CSI2_HOST			60
> +#define CLKID_SYS_CSI2_ADAPT			61
> +#define CLKID_SYS_DSPA				62
> +#define CLKID_SYS_PP_DMA			63
> +#define CLKID_SYS_PP_WRAPPER			64
> +#define CLKID_SYS_VPU_INTR			65
> +#define CLKID_SYS_CSI2_PHY			66
> +#define CLKID_SYS_SARADC			67
> +#define CLKID_SYS_PWM_J				68
> +#define CLKID_SYS_PWM_I				69
> +#define CLKID_SYS_PWM_H				70
> +#define CLKID_SYS_PWM_N				71
> +#define CLKID_SYS_PWM_M				72
> +#define CLKID_SYS_PWM_L				73
> +#define CLKID_SYS_PWM_K				74
> +#define CLKID_SD_EMMC_A_SEL			75
> +#define CLKID_SD_EMMC_A_DIV			76
> +#define CLKID_SD_EMMC_A				77
> +#define CLKID_SD_EMMC_B_SEL			78
> +#define CLKID_SD_EMMC_B_DIV			79
> +#define CLKID_SD_EMMC_B				80
> +#define CLKID_SD_EMMC_C_SEL			81
> +#define CLKID_SD_EMMC_C_DIV			82
> +#define CLKID_SD_EMMC_C				83
> +#define CLKID_PWM_H_SEL				84
> +#define CLKID_PWM_H_DIV				85
> +#define CLKID_PWM_H				86
> +#define CLKID_PWM_I_SEL				87
> +#define CLKID_PWM_I_DIV				88
> +#define CLKID_PWM_I				89
> +#define CLKID_PWM_J_SEL				90
> +#define CLKID_PWM_J_DIV				91
> +#define CLKID_PWM_J				92
> +#define CLKID_PWM_K_SEL				93
> +#define CLKID_PWM_K_DIV				94
> +#define CLKID_PWM_K				95
> +#define CLKID_PWM_L_SEL				96
> +#define CLKID_PWM_L_DIV				97
> +#define CLKID_PWM_L				98
> +#define CLKID_PWM_M_SEL				99
> +#define CLKID_PWM_M_DIV				100
> +#define CLKID_PWM_M				101
> +#define CLKID_PWM_N_SEL				102
> +#define CLKID_PWM_N_DIV				103
> +#define CLKID_PWM_N				104
> +#define CLKID_SPISG_SEL				105
> +#define CLKID_SPISG_DIV				106
> +#define CLKID_SPISG				107
> +#define CLKID_SPISG1_SEL			108
> +#define CLKID_SPISG1_DIV			109
> +#define CLKID_SPISG1				110
> +#define CLKID_SPISG2_SEL			111
> +#define CLKID_SPISG2_DIV			112
> +#define CLKID_SPISG2				113
> +#define CLKID_SARADC_SEL			114
> +#define CLKID_SARADC_DIV			115
> +#define CLKID_SARADC				116
> +#define CLKID_AMFC_SEL				117
> +#define CLKID_AMFC_DIV				118
> +#define CLKID_AMFC				119
> +#define CLKID_NNA_SEL				120
> +#define CLKID_NNA_DIV				121
> +#define CLKID_NNA				122
> +#define CLKID_USB_250M_SEL			123
> +#define CLKID_USB_250M_DIV			124
> +#define CLKID_USB_250M				125
> +#define CLKID_USB_48M_PRE_SEL			126
> +#define CLKID_USB_48M_PRE_DIV			127
> +#define CLKID_USB_48M_PRE			128
> +#define CLKID_PCIE_TL_SEL			129
> +#define CLKID_PCIE_TL_DIV			130
> +#define CLKID_PCIE_TL				131
> +#define CLKID_PCIE1_TL_SEL			132
> +#define CLKID_PCIE1_TL_DIV			133
> +#define CLKID_PCIE1_TL				134
> +#define CLKID_CMPR_SEL				135
> +#define CLKID_CMPR_DIV				136
> +#define CLKID_CMPR				137
> +#define CLKID_DEWARPA_SEL			138
> +#define CLKID_DEWARPA_DIV			139
> +#define CLKID_DEWARPA				140
> +#define CLKID_SC_PRE_SEL			141
> +#define CLKID_SC_PRE_DIV			142
> +#define CLKID_SC_PRE				143
> +#define CLKID_SC				144
> +#define CLKID_DPTX_APB2_SEL			145
> +#define CLKID_DPTX_APB2_DIV			146
> +#define CLKID_DPTX_APB2				147
> +#define CLKID_DPTX_AUD_SEL			148
> +#define CLKID_DPTX_AUD_DIV			149
> +#define CLKID_DPTX_AUD				150
> +#define CLKID_ISP_SEL				151
> +#define CLKID_ISP_DIV				152
> +#define CLKID_ISP				153
> +#define CLKID_CVE_SEL				154
> +#define CLKID_CVE_DIV				155
> +#define CLKID_CVE				156
> +#define CLKID_VGE_SEL				157
> +#define CLKID_VGE_DIV				158
> +#define CLKID_VGE				159
> +#define CLKID_PP_SEL				160
> +#define CLKID_PP_DIV				161
> +#define CLKID_PP				162
> +#define CLKID_GLB_SEL				163
> +#define CLKID_GLB_DIV				164
> +#define CLKID_GLB				165
> +#define CLKID_USB_48M_DUALDIV_IN		166
> +#define CLKID_USB_48M_DUALDIV_DIV		167
> +#define CLKID_USB_48M_DUALDIV_SEL		168
> +#define CLKID_USB_48M_DUALDIV			169
> +#define CLKID_USB_48M				170
> +#define CLKID_CAN_PE_SEL			171
> +#define CLKID_CAN_PE_DIV			172
> +#define CLKID_CAN_PE				173
> +#define CLKID_CAN1_PE_SEL			174
> +#define CLKID_CAN1_PE_DIV			175
> +#define CLKID_CAN1_PE				176
> +#define CLKID_CAN_FILTER_SEL			177
> +#define CLKID_CAN_FILTER_DIV			178
> +#define CLKID_CAN_FILTER			179
> +#define CLKID_CAN1_FILTER_SEL			180
> +#define CLKID_CAN1_FILTER_DIV			181
> +#define CLKID_CAN1_FILTER			182
> +#define CLKID_I3C_SEL				183
> +#define CLKID_I3C_DIV				184
> +#define CLKID_I3C				185
> +#define CLKID_TS_DIV				186
> +#define CLKID_TS				187
> +#define CLKID_ETH_125M_DIV			188
> +#define CLKID_ETH_125M				189
> +#define CLKID_ETH_RMII_SEL			190
> +#define CLKID_ETH_RMII_DIV			191
> +#define CLKID_ETH_RMII				192
> +#define CLKID_GEN_SEL				193
> +#define CLKID_GEN_DIV				194
> +#define CLKID_GEN				195
> +#define CLKID_CLK24M_IN				196
> +#define CLKID_CLK12_24M				197
> +#define CLKID_MALI_0_SEL			198
> +#define CLKID_MALI_0_DIV			199
> +#define CLKID_MALI_0				200
> +#define CLKID_MALI_1_SEL			201
> +#define CLKID_MALI_1_DIV			202
> +#define CLKID_MALI_1				203
> +#define CLKID_MALI				204
> +#define CLKID_MALI_STACK_0_SEL			205
> +#define CLKID_MALI_STACK_0_DIV			206
> +#define CLKID_MALI_STACK_0			207
> +#define CLKID_MALI_STACK_1_SEL			208
> +#define CLKID_MALI_STACK_1_DIV			209
> +#define CLKID_MALI_STACK_1			210
> +#define CLKID_MALI_STACK			211
> +#define CLKID_DSPA_0_SEL			212
> +#define CLKID_DSPA_0_DIV			213
> +#define CLKID_DSPA_0				214
> +#define CLKID_DSPA_1_SEL			215
> +#define CLKID_DSPA_1_DIV			216
> +#define CLKID_DSPA_1				217
> +#define CLKID_DSPA				218
> +#define CLKID_HEVCF_0_SEL			219
> +#define CLKID_HEVCF_0_DIV			220
> +#define CLKID_HEVCF_0				221
> +#define CLKID_HEVCF_1_SEL			222
> +#define CLKID_HEVCF_1_DIV			223
> +#define CLKID_HEVCF_1				224
> +#define CLKID_HEVCF				225
> +#define CLKID_HCODEC_0_SEL			226
> +#define CLKID_HCODEC_0_DIV			227
> +#define CLKID_HCODEC_0				228
> +#define CLKID_HCODEC_1_SEL			229
> +#define CLKID_HCODEC_1_DIV			230
> +#define CLKID_HCODEC_1				231
> +#define CLKID_HCODEC				232
> +#define CLKID_VPU_0_SEL				233
> +#define CLKID_VPU_0_DIV				234
> +#define CLKID_VPU_0				235
> +#define CLKID_VPU_1_SEL				236
> +#define CLKID_VPU_1_DIV				237
> +#define CLKID_VPU_1				238
> +#define CLKID_VPU				239
> +#define CLKID_VAPB_0_SEL			240
> +#define CLKID_VAPB_0_DIV			241
> +#define CLKID_VAPB_0				242
> +#define CLKID_VAPB_1_SEL			243
> +#define CLKID_VAPB_1_DIV			244
> +#define CLKID_VAPB_1				245
> +#define CLKID_VAPB				246
> +#define CLKID_GE2D				247
> +#define CLKID_VPU_CLKB_TMP_SEL			248
> +#define CLKID_VPU_CLKB_TMP_DIV			249
> +#define CLKID_VPU_CLKB_TMP			250
> +#define CLKID_VPU_CLKB_DIV			251
> +#define CLKID_VPU_CLKB				252
> +#define CLKID_HDMITX_SYS_SEL			253
> +#define CLKID_HDMITX_SYS_DIV			254
> +#define CLKID_HDMITX_SYS			255
> +#define CLKID_HDMITX_PRIF_SEL			256
> +#define CLKID_HDMITX_PRIF_DIV			257
> +#define CLKID_HDMITX_PRIF			258
> +#define CLKID_HDMITX_200M_SEL			259
> +#define CLKID_HDMITX_200M_DIV			260
> +#define CLKID_HDMITX_200M			261
> +#define CLKID_HDMITX_AUD_SEL			262
> +#define CLKID_HDMITX_AUD_DIV			263
> +#define CLKID_HDMITX_AUD			264
> +#define CLKID_HDMIRX_5M_SEL			265
> +#define CLKID_HDMIRX_5M_DIV			266
> +#define CLKID_HDMIRX_5M				267
> +#define CLKID_HDMIRX_2M_SEL			268
> +#define CLKID_HDMIRX_2M_DIV			269
> +#define CLKID_HDMIRX_2M				270
> +#define CLKID_HDMIRX_CFG_SEL			271
> +#define CLKID_HDMIRX_CFG_DIV			272
> +#define CLKID_HDMIRX_CFG			273
> +#define CLKID_HDMIRX_HDCP2X_SEL			274
> +#define CLKID_HDMIRX_HDCP2X_DIV			275
> +#define CLKID_HDMIRX_HDCP2X			276
> +#define CLKID_HDMIRX_ACR_REF_SEL		277
> +#define CLKID_HDMIRX_ACR_REF_DIV		278
> +#define CLKID_HDMIRX_ACR_REF			279
> +#define CLKID_HDMIRX_METER_SEL			280
> +#define CLKID_HDMIRX_METER_DIV			281
> +#define CLKID_HDMIRX_METER			282
> +#define CLKID_VID_LOCK_SEL			283
> +#define CLKID_VID_LOCK_DIV			284
> +#define CLKID_VID_LOCK				285
> +#define CLKID_VDIN_MEAS_SEL			286
> +#define CLKID_VDIN_MEAS_DIV			287
> +#define CLKID_VDIN_MEAS				288
> +#define CLKID_VID_PLL_DIV			289
> +#define CLKID_VID_PLL_SEL			290
> +#define CLKID_VID_PLL				291
> +#define CLKID_VID_PLL_VCLK			292
> +#define CLKID_VCLK_SEL				293
> +#define CLKID_VCLK_IN				294
> +#define CLKID_VCLK_DIV				295
> +#define CLKID_VCLK				296
> +#define CLKID_VCLK_DIV1_EN			297
> +#define CLKID_VCLK_DIV2_EN			298
> +#define CLKID_VCLK_DIV2				299
> +#define CLKID_VCLK_DIV4_EN			300
> +#define CLKID_VCLK_DIV4				301
> +#define CLKID_VCLK_DIV6_EN			302
> +#define CLKID_VCLK_DIV6				303
> +#define CLKID_VCLK_DIV12_EN			304
> +#define CLKID_VCLK_DIV12			305
> +#define CLKID_VCLK2_SEL				306
> +#define CLKID_VCLK2_IN				307
> +#define CLKID_VCLK2_DIV				308
> +#define CLKID_VCLK2				309
> +#define CLKID_VCLK2_DIV1_EN			310
> +#define CLKID_VCLK2_DIV2_EN			311
> +#define CLKID_VCLK2_DIV2			312
> +#define CLKID_VCLK2_DIV4_EN			313
> +#define CLKID_VCLK2_DIV4			314
> +#define CLKID_VCLK2_DIV6_EN			315
> +#define CLKID_VCLK2_DIV6			316
> +#define CLKID_VCLK2_DIV12_EN			317
> +#define CLKID_VCLK2_DIV12			318
> +#define CLKID_VDAC_SEL				319
> +#define CLKID_VDAC				320
> +#define CLKID_ENC_SEL				321
> +#define CLKID_ENC				322
> +#define CLKID_ENC1_SEL				323
> +#define CLKID_ENC1				324
> +#define CLKID_HDMITX_PIXEL_SEL			325
> +#define CLKID_HDMITX_PIXEL			326
> +#define CLKID_HDMITX_FE_SEL			327
> +#define CLKID_HDMITX_FE				328
> +#define CLKID_HDMITX1_PIXEL_SEL			329
> +#define CLKID_HDMITX1_PIXEL			330
> +#define CLKID_HDMITX1_FE_SEL			331
> +#define CLKID_HDMITX1_FE			332
> +#define CLKID_CSI_PHY_SEL			333
> +#define CLKID_CSI_PHY_DIV			334
> +#define CLKID_CSI_PHY				335
> +#define CLKID_DSI_MEAS_SEL			336
> +#define CLKID_DSI_MEAS_DIV			337
> +#define CLKID_DSI_MEAS				338
> +#define CLKID_DSI_B_MEAS_SEL			339
> +#define CLKID_DSI_B_MEAS_DIV			340
> +#define CLKID_DSI_B_MEAS			341
> +
> +#endif  /* __AMLOGIC_A9_PERIPHERALS_CLKC_H */

-- 
Jerome


^ permalink raw reply

* Re: [PATCH 08/10] clk: amlogic: Add A9 PLL clock controller driver
From: Jerome Brunet @ 2026-05-14 16:12 UTC (permalink / raw)
  To: Jian Hu via B4 Relay
  Cc: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Neil Armstrong, Xianwei Zhao, Kevin Hilman,
	Martin Blumenstingl, jian.hu, linux-kernel, linux-clk, devicetree,
	linux-amlogic, linux-arm-kernel
In-Reply-To: <20260511-b4-a9_clk-v1-8-41cb4071b7c9@amlogic.com>

On lun. 11 mai 2026 at 20:47, Jian Hu via B4 Relay <devnull+jian.hu.amlogic.com@kernel.org> wrote:

> From: Jian Hu <jian.hu@amlogic.com>
>
> Add the PLL clock controller driver for the Amlogic A9 SoC family.
>
> Signed-off-by: Jian Hu <jian.hu@amlogic.com>
> ---
>  drivers/clk/meson/Kconfig  |  13 +
>  drivers/clk/meson/Makefile |   1 +
>  drivers/clk/meson/a9-pll.c | 831 +++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 845 insertions(+)
>
> diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
> index cf8cf3f9e4ee..3549e67d6988 100644
> --- a/drivers/clk/meson/Kconfig
> +++ b/drivers/clk/meson/Kconfig
> @@ -132,6 +132,19 @@ config COMMON_CLK_A1_PERIPHERALS
>  	  device, A1 SoC Family. Say Y if you want A1 Peripherals clock
>  	  controller to work.
>  
> +config COMMON_CLK_A9_PLL
> +	tristate "Amlogic A9 SoC PLL controller support"
> +	depends on ARM64
> +	default ARCH_MESON
> +	select COMMON_CLK_MESON_REGMAP
> +	select COMMON_CLK_MESON_CLKC_UTILS
> +	select COMMON_CLK_MESON_PLL
> +	imply COMMON_CLK_SCMI
> +	help
> +	  Support for the PLL clock controller on Amlogic A311Y3 based
> +	  device, AKA A9. PLLs are required by most peripheral to operate.
> +	  Say Y if you want A9 PLL clock controller to work.
> +
>  config COMMON_CLK_C3_PLL
>  	tristate "Amlogic C3 PLL clock controller"
>  	depends on ARM64
> diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile
> index c6719694a242..77636033061f 100644
> --- a/drivers/clk/meson/Makefile
> +++ b/drivers/clk/meson/Makefile
> @@ -19,6 +19,7 @@ obj-$(CONFIG_COMMON_CLK_AXG) += axg.o axg-aoclk.o
>  obj-$(CONFIG_COMMON_CLK_AXG_AUDIO) += axg-audio.o
>  obj-$(CONFIG_COMMON_CLK_A1_PLL) += a1-pll.o
>  obj-$(CONFIG_COMMON_CLK_A1_PERIPHERALS) += a1-peripherals.o
> +obj-$(CONFIG_COMMON_CLK_A9_PLL) += a9-pll.o
>  obj-$(CONFIG_COMMON_CLK_C3_PLL) += c3-pll.o
>  obj-$(CONFIG_COMMON_CLK_C3_PERIPHERALS) += c3-peripherals.o
>  obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o gxbb-aoclk.o
> diff --git a/drivers/clk/meson/a9-pll.c b/drivers/clk/meson/a9-pll.c
> new file mode 100644
> index 000000000000..84b591c3afff
> --- /dev/null
> +++ b/drivers/clk/meson/a9-pll.c
> @@ -0,0 +1,831 @@
> +// SPDX-License-Identifier: (GPL-2.0-only OR MIT)
> +/*
> + * Copyright (C) 2026 Amlogic, Inc. All rights reserved
> + */
> +
> +#include <linux/clk-provider.h>
> +#include <linux/platform_device.h>
> +#include <dt-bindings/clock/amlogic,a9-pll-clkc.h>
> +#include "clk-regmap.h"
> +#include "clk-pll.h"
> +#include "meson-clkc-utils.h"
> +
> +#define GP0PLL_CTRL0			0x00
> +#define GP0PLL_CTRL1			0x04
> +#define GP0PLL_CTRL2			0x08
> +#define GP0PLL_CTRL3			0x0c
> +#define GP0PLL_CTRL4			0x10
> +
> +/* HIFI0 and HIFI1 share the same IP and register offset layout. */
> +#define HIFIPLL_CTRL0			0x00
> +#define HIFIPLL_CTRL1			0x04
> +#define HIFIPLL_CTRL2			0x08
> +#define HIFIPLL_CTRL3			0x0c
> +#define HIFIPLL_CTRL4			0x10
> +
> +/* MCLK0 and MCLK1 share the same IP and register offset layout. */
> +#define MCLKPLL_CTRL0			0x00
> +#define MCLKPLL_CTRL1			0x04
> +#define MCLKPLL_CTRL2			0x08
> +#define MCLKPLL_CTRL3			0x0c
> +#define MCLKPLL_CTRL4			0x10
> +
> +#define A9_COMP_SEL(_name, _reg, _shift, _mask, _pdata) \
> +	MESON_COMP_SEL(a9_, _name, _reg, _shift, _mask, _pdata, NULL, 0, 0)
> +
> +#define A9_COMP_DIV(_name, _reg, _shift, _width) \
> +	MESON_COMP_DIV(a9_, _name, _reg, _shift, _width, 0, CLK_SET_RATE_PARENT)
> +
> +#define A9_COMP_GATE(_name, _reg, _bit) \
> +	MESON_COMP_GATE(a9_, _name, _reg, _bit, CLK_SET_RATE_PARENT)
> +
> +/*
> + * Compared with previous SoC PLLs, the A9 PLL input path has an inherent
> + * 2-divider. The N pre-divider follows the same calculation rule as OD,
> + * where the pre-divider ratio equals 2^N.
> + *
> + * A9 PLL is composed as follows:
> + *
> + *                      PLL
> + *         +---------------------------------+
> + *         |                                 |
> + *         |             +--+                |
> + *  in/2 >>---[ /2^N ]-->|  |      +-----+   |
> + *         |             |  |------| DCO |----->> out
> + *         |  +--------->|  |      +--v--+   |
> + *         |  |          +--+         |      |
> + *         |  |                       |      |
> + *         |  +--[ *(M + (F/Fmax) ]<--+      |
> + *         |                                 |
> + *         +---------------------------------+
> + *
> + * out = in / 2  * (m + frac / frac_max) / 2^n
> + */
> +
> +static struct clk_fixed_factor a9_gp0_in_div2_div = {
> +	.mult = 1,
> +	.div = 2,
> +	.hw.init = &(struct clk_init_data){
> +		.name = "gp0_in_div2_div",
> +		.ops = &clk_fixed_factor_ops,
> +		.parent_data = &(const struct clk_parent_data) {
> +			.fw_name = "in0",
> +		},
> +		.num_parents = 1,
> +	},
> +};
> +
> +static struct clk_regmap a9_gp0_in_div2 = {
> +	.data = &(struct clk_regmap_gate_data) {
> +		.offset = GP0PLL_CTRL0,
> +		.bit_idx = 27,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "gp0_in_div2",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&a9_gp0_in_div2_div.hw
> +		},
> +		.num_parents = 1,
> +	},
> +};

When document something, be sure it matches what you are doing
afterward. It is confusing otherwise. Your comments above clearly miss
this gate.

A fixed 2 divider followed by a power of 2 divider ? Is it actually how
the HW works or your modelisation power of 2 that's shifted by 1,
mapping :
 * 0 -> 2
 * 1 -> 4
 * etc ...

?

> +
> +/* The output frequency range of the A9 PLL_DCO is 1.4 GHz to 2.8 GHz. */
> +static const struct pll_mult_range a9_pll_mult_range = {
> +	.min = 117,
> +	.max = 233,
> +};

If PLL restriction is actually the DCO output rate, and only the reason
to keep the pre-devider in the range above, I would definitely welcome a
rework to express the constraints properly and split the pre-divider out.

> +
> +static const struct reg_sequence a9_gp0_pll_init_regs[] = {
> +	{ .reg = GP0PLL_CTRL0, .def = 0x00010000 },
> +	{ .reg = GP0PLL_CTRL1, .def = 0x11480000 },
> +	{ .reg = GP0PLL_CTRL2, .def = 0x1219b010 },
> +	{ .reg = GP0PLL_CTRL3, .def = 0x00008010 }
> +};
> +
> +static struct clk_regmap a9_gp0_pll_dco = {
> +	.data = &(struct meson_clk_pll_data) {
> +		.en = {
> +			.reg_off = GP0PLL_CTRL0,
> +			.shift   = 28,
> +			.width   = 1,
> +		},
> +		.m = {
> +			.reg_off = GP0PLL_CTRL0,
> +			.shift   = 0,
> +			.width   = 9,
> +		},
> +		.n = {
> +			.reg_off = GP0PLL_CTRL0,
> +			.shift   = 12,
> +			.width   = 3,
> +		},
> +		.frac = {
> +			.reg_off = GP0PLL_CTRL1,
> +			.shift   = 0,
> +			.width   = 17,
> +		},
> +		.l = {
> +			.reg_off = GP0PLL_CTRL0,
> +			.shift   = 31,
> +			.width   = 1,
> +		},
> +		.rst = {
> +			.reg_off = GP0PLL_CTRL0,
> +			.shift   = 29,
> +			.width   = 1,
> +		},
> +		.l_detect = {
> +			.reg_off = GP0PLL_CTRL0,
> +			.shift   = 30,
> +			.width   = 1,
> +		},
> +		.range = &a9_pll_mult_range,
> +		.init_regs = a9_gp0_pll_init_regs,
> +		.init_count = ARRAY_SIZE(a9_gp0_pll_init_regs),
> +		.flags = CLK_MESON_PLL_RST_ACTIVE_LOW |
> +			 CLK_MESON_PLL_N_POWER_OF_TWO |
> +			 CLK_MESON_PLL_L_DETECT_ACTIVE_HIGH,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "gp0_pll_dco",
> +		.ops = &meson_clk_pll_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&a9_gp0_in_div2.hw
> +		},
> +		.num_parents = 1,
> +	},
> +};
> +
> +/* For gp0, hifi and mclk pll, the maximum value of od is 4. */
> +static const struct clk_div_table a9_pll_od_table[] = {
> +	{ 0,  1 },
> +	{ 1,  2 },
> +	{ 2,  4 },
> +	{ 3,  8 },
> +	{ 4,  16 },
> +	{ /* sentinel */ }
> +};
> +
> +static struct clk_regmap a9_gp0_pll = {
> +	.data = &(struct clk_regmap_div_data) {
> +		.offset = GP0PLL_CTRL0,
> +		.shift = 20,
> +		.width = 3,
> +		.table = a9_pll_od_table,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "gp0_pll",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&a9_gp0_pll_dco.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_fixed_factor a9_hifi0_in_div2_div = {
> +	.mult = 1,
> +	.div = 2,
> +	.hw.init = &(struct clk_init_data){
> +		.name = "hifi0_in_div2_div",
> +		.ops = &clk_fixed_factor_ops,
> +		.parent_data = &(const struct clk_parent_data) {
> +			.fw_name = "in0",
> +		},
> +		.num_parents = 1,
> +	},
> +};
> +
> +static struct clk_regmap a9_hifi0_in_div2 = {
> +	.data = &(struct clk_regmap_gate_data) {
> +		.offset = HIFIPLL_CTRL0,
> +		.bit_idx = 27,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "hifi0_in_div2",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&a9_hifi0_in_div2_div.hw
> +		},
> +		.num_parents = 1,
> +	},
> +};
> +
> +static const struct reg_sequence a9_hifi0_pll_init_regs[] = {
> +	{ .reg = HIFIPLL_CTRL0, .def = 0x00010000 },
> +	{ .reg = HIFIPLL_CTRL1, .def = 0x11480000 },
> +	{ .reg = HIFIPLL_CTRL2, .def = 0x1219b010 },
> +	{ .reg = HIFIPLL_CTRL3, .def = 0x00008010 }
> +};

It look like GP0 and HIFI PLL are exactly the same IP, you've even
documented it as such. Yet all the code is duplicated. That's not OK.

I understand that way we statically declared the clocks so far pushed
you in that direction. That's something I'd like to fix properly
someday.

In the meantime, you could at least duplicate the memory at runtime to
avoid copy/pasting the code. A minor change to clkc utils as suggested
at the end of this message could help you do so.

Same probably applies to mclks.

> +
> +static struct clk_regmap a9_hifi0_pll_dco = {
> +	.data = &(struct meson_clk_pll_data) {
> +		.en = {
> +			.reg_off = HIFIPLL_CTRL0,
> +			.shift   = 28,
> +			.width   = 1,
> +		},
> +		.m = {
> +			.reg_off = HIFIPLL_CTRL0,
> +			.shift   = 0,
> +			.width   = 9,
> +		},
> +		.n = {
> +			.reg_off = HIFIPLL_CTRL0,
> +			.shift   = 12,
> +			.width   = 3,
> +		},
> +		.frac = {
> +			.reg_off = HIFIPLL_CTRL1,
> +			.shift   = 0,
> +			.width   = 17,
> +		},
> +		.l = {
> +			.reg_off = HIFIPLL_CTRL0,
> +			.shift   = 31,
> +			.width   = 1,
> +		},
> +		.rst = {
> +			.reg_off = HIFIPLL_CTRL0,
> +			.shift   = 29,
> +			.width   = 1,
> +		},
> +		.l_detect = {
> +			.reg_off = HIFIPLL_CTRL0,
> +			.shift   = 30,
> +			.width   = 1,
> +		},
> +		.range = &a9_pll_mult_range,
> +		.init_regs = a9_hifi0_pll_init_regs,
> +		.init_count = ARRAY_SIZE(a9_hifi0_pll_init_regs),
> +		.frac_max = 100000,
> +		.flags = CLK_MESON_PLL_RST_ACTIVE_LOW |
> +			 CLK_MESON_PLL_N_POWER_OF_TWO |
> +			 CLK_MESON_PLL_L_DETECT_ACTIVE_HIGH,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "hifi0_pll_dco",
> +		.ops = &meson_clk_pll_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&a9_hifi0_in_div2.hw
> +		},
> +		.num_parents = 1,
> +	},
> +};
> +
> +static struct clk_regmap a9_hifi0_pll = {
> +	.data = &(struct clk_regmap_div_data) {
> +		.offset = HIFIPLL_CTRL0,
> +		.shift = 20,
> +		.width = 3,
> +		.table = a9_pll_od_table,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "hifi0_pll",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&a9_hifi0_pll_dco.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static struct clk_fixed_factor a9_hifi1_in_div2_div = {
> +	.mult = 1,
> +	.div = 2,
> +	.hw.init = &(struct clk_init_data){
> +		.name = "hifi1_in_div2_div",
> +		.ops = &clk_fixed_factor_ops,
> +		.parent_data = &(const struct clk_parent_data) {
> +			.fw_name = "in0",
> +		},
> +		.num_parents = 1,
> +	},
> +};
> +
> +static struct clk_regmap a9_hifi1_in_div2 = {
> +	.data = &(struct clk_regmap_gate_data) {
> +		.offset = HIFIPLL_CTRL0,
> +		.bit_idx = 27,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "hifi1_in_div2",
> +		.ops = &clk_regmap_gate_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&a9_hifi1_in_div2_div.hw
> +		},
> +		.num_parents = 1,
> +	},
> +};
> +
> +static const struct reg_sequence a9_hifi1_pll_init_regs[] = {
> +	{ .reg = HIFIPLL_CTRL0, .def = 0x00010000 },
> +	{ .reg = HIFIPLL_CTRL1, .def = 0x11480000 },
> +	{ .reg = HIFIPLL_CTRL2, .def = 0x1219b011 },
> +	{ .reg = HIFIPLL_CTRL3, .def = 0x00008010 }
> +};
> +
> +static struct clk_regmap a9_hifi1_pll_dco = {
> +	.data = &(struct meson_clk_pll_data) {
> +		.en = {
> +			.reg_off = HIFIPLL_CTRL0,
> +			.shift   = 28,
> +			.width   = 1,
> +		},
> +		.m = {
> +			.reg_off = HIFIPLL_CTRL0,
> +			.shift   = 0,
> +			.width   = 9,
> +		},
> +		.n = {
> +			.reg_off = HIFIPLL_CTRL0,
> +			.shift   = 12,
> +			.width   = 3,
> +		},
> +		.frac = {
> +			.reg_off = HIFIPLL_CTRL1,
> +			.shift   = 0,
> +			.width   = 17,
> +		},
> +		.l = {
> +			.reg_off = HIFIPLL_CTRL0,
> +			.shift   = 31,
> +			.width   = 1,
> +		},
> +		.rst = {
> +			.reg_off = HIFIPLL_CTRL0,
> +			.shift   = 29,
> +			.width   = 1,
> +		},
> +		.l_detect = {
> +			.reg_off = HIFIPLL_CTRL0,
> +			.shift   = 30,
> +			.width   = 1,
> +		},
> +		.range = &a9_pll_mult_range,
> +		.init_regs = a9_hifi1_pll_init_regs,
> +		.init_count = ARRAY_SIZE(a9_hifi1_pll_init_regs),
> +		.frac_max = 100000,
> +		.flags = CLK_MESON_PLL_RST_ACTIVE_LOW |
> +			 CLK_MESON_PLL_N_POWER_OF_TWO |
> +			 CLK_MESON_PLL_L_DETECT_ACTIVE_HIGH,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "hifi1_pll_dco",
> +		.ops = &meson_clk_pll_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&a9_hifi1_in_div2.hw
> +		},
> +		.num_parents = 1,
> +	},
> +};
> +
> +static struct clk_regmap a9_hifi1_pll = {
> +	.data = &(struct clk_regmap_div_data) {
> +		.offset = HIFIPLL_CTRL0,
> +		.shift = 20,
> +		.width = 3,
> +		.table = a9_pll_od_table,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "hifi1_pll",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&a9_hifi1_pll_dco.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +/*
> + * Unlike GP0 and HIFI PLLs, the input divider 2 of MCLK PLL is
> + * enabled by default and has no enable control bit.
> + */
> +static struct clk_fixed_factor a9_mclk0_in_div2 = {
> +	.mult = 1,
> +	.div = 2,
> +	.hw.init = &(struct clk_init_data){
> +		.name = "mclk0_in_div2_div",
> +		.ops = &clk_fixed_factor_ops,
> +		.parent_data = &(const struct clk_parent_data) {
> +			.fw_name = "in0",
> +		},
> +		.num_parents = 1,
> +	},
> +};
> +
> +static const struct reg_sequence a9_mclk0_pll_init_regs[] = {
> +	{ .reg = MCLKPLL_CTRL1, .def = 0x00422000 },
> +	{ .reg = MCLKPLL_CTRL2, .def = 0x60000100 },
> +	{ .reg = MCLKPLL_CTRL3, .def = 0x02000200 },
> +	{ .reg = MCLKPLL_CTRL4, .def = 0xd616d616 }
> +};
> +
> +static struct clk_regmap a9_mclk0_pll_dco = {
> +	.data = &(struct meson_clk_pll_data) {
> +		.en = {
> +			.reg_off = MCLKPLL_CTRL0,
> +			.shift   = 28,
> +			.width   = 1,
> +		},
> +		.m = {
> +			.reg_off = MCLKPLL_CTRL0,
> +			.shift   = 0,
> +			.width   = 9,
> +		},
> +		.n = {
> +			.reg_off = MCLKPLL_CTRL0,
> +			.shift   = 12,
> +			.width   = 3,
> +		},
> +		.l = {
> +			.reg_off = MCLKPLL_CTRL0,
> +			.shift   = 31,
> +			.width   = 1,
> +		},
> +		.rst = {
> +			.reg_off = MCLKPLL_CTRL0,
> +			.shift   = 29,
> +			.width   = 1,
> +		},
> +		.l_detect = {
> +			.reg_off = MCLKPLL_CTRL0,
> +			.shift   = 30,
> +			.width   = 1,
> +		},
> +		.range = &a9_pll_mult_range,
> +		.init_regs = a9_mclk0_pll_init_regs,
> +		.init_count = ARRAY_SIZE(a9_mclk0_pll_init_regs),
> +		.flags = CLK_MESON_PLL_RST_ACTIVE_LOW |
> +			 CLK_MESON_PLL_N_POWER_OF_TWO |
> +			 CLK_MESON_PLL_L_DETECT_ACTIVE_HIGH,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "mclk0_pll_dco",
> +		.ops = &meson_clk_pll_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&a9_mclk0_in_div2.hw
> +		},
> +		.num_parents = 1,
> +	},
> +};
> +
> +static struct clk_regmap a9_mclk0_0_pll = {
> +	.data = &(struct clk_regmap_div_data) {
> +		.offset = MCLKPLL_CTRL3,
> +		.shift = 0,
> +		.width = 3,
> +		.table = a9_pll_od_table,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "mclk0_0_pll",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&a9_mclk0_pll_dco.hw
> +		},
> +		.num_parents = 1,
> +	},
> +};
> +
> +static struct clk_regmap a9_mclk0_0_pre = {
> +	.data = &(struct clk_regmap_div_data) {
> +		.offset = MCLKPLL_CTRL3,
> +		.shift = 3,
> +		.width = 5,
> +		.flags = CLK_DIVIDER_MAX_AT_ZERO,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "mclk0_0_pre",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&a9_mclk0_0_pll.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static const struct clk_parent_data a9_mclk0_0_parents[] = {
> +	{ .hw = &a9_mclk0_0_pre.hw },
> +	{ .fw_name = "in0" },
> +	{ .fw_name = "in1" },
> +	{ .fw_name = "in2" }
> +};
> +
> +static A9_COMP_SEL(mclk0_0, MCLKPLL_CTRL3, 12, 0x3, a9_mclk0_0_parents);
> +static A9_COMP_DIV(mclk0_0, MCLKPLL_CTRL3, 10, 1);
> +static A9_COMP_GATE(mclk0_0, MCLKPLL_CTRL3, 8);
> +
> +static struct clk_regmap a9_mclk0_1_pll = {
> +	.data = &(struct clk_regmap_div_data) {
> +		.offset = MCLKPLL_CTRL3,
> +		.shift = 16,
> +		.width = 3,
> +		.table = a9_pll_od_table,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "mclk0_1_pll",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&a9_mclk0_pll_dco.hw
> +		},
> +		.num_parents = 1,
> +	},
> +};
> +
> +static struct clk_regmap a9_mclk0_1_pre = {
> +	.data = &(struct clk_regmap_div_data) {
> +		.offset = MCLKPLL_CTRL3,
> +		.shift = 19,
> +		.width = 5,
> +		.flags = CLK_DIVIDER_MAX_AT_ZERO,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "mclk0_1_pre",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&a9_mclk0_1_pll.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static const struct clk_parent_data a9_mclk0_1_parents[] = {
> +	{ .hw = &a9_mclk0_1_pre.hw },
> +	{ .fw_name = "in0" },
> +	{ .fw_name = "in1" },
> +	{ .fw_name = "in2" }
> +};
> +
> +static A9_COMP_SEL(mclk0_1, MCLKPLL_CTRL3, 28, 0x3, a9_mclk0_1_parents);
> +static A9_COMP_DIV(mclk0_1, MCLKPLL_CTRL3, 26, 1);
> +static A9_COMP_GATE(mclk0_1, MCLKPLL_CTRL3, 24);
> +
> +static struct clk_fixed_factor a9_mclk1_in_div2 = {
> +	.mult = 1,
> +	.div = 2,
> +	.hw.init = &(struct clk_init_data){
> +		.name = "mclk1_in_div2",
> +		.ops = &clk_fixed_factor_ops,
> +		.parent_data = &(const struct clk_parent_data) {
> +			.fw_name = "in0",
> +		},
> +		.num_parents = 1,
> +	},
> +};
> +
> +static struct clk_regmap a9_mclk1_pll_dco = {
> +	.data = &(struct meson_clk_pll_data) {
> +		.en = {
> +			.reg_off = MCLKPLL_CTRL0,
> +			.shift   = 28,
> +			.width   = 1,
> +		},
> +		.m = {
> +			.reg_off = MCLKPLL_CTRL0,
> +			.shift   = 0,
> +			.width   = 9,
> +		},
> +		.n = {
> +			.reg_off = MCLKPLL_CTRL0,
> +			.shift   = 12,
> +			.width   = 3,
> +		},
> +		.l = {
> +			.reg_off = MCLKPLL_CTRL0,
> +			.shift   = 31,
> +			.width   = 1,
> +		},
> +		.rst = {
> +			.reg_off = MCLKPLL_CTRL0,
> +			.shift   = 29,
> +			.width   = 1,
> +		},
> +		.l_detect = {
> +			.reg_off = MCLKPLL_CTRL0,
> +			.shift   = 30,
> +			.width   = 1,
> +		},
> +		.range = &a9_pll_mult_range,
> +		.init_regs = a9_mclk0_pll_init_regs,
> +		.init_count = ARRAY_SIZE(a9_mclk0_pll_init_regs),
> +		.flags = CLK_MESON_PLL_RST_ACTIVE_LOW |
> +			 CLK_MESON_PLL_N_POWER_OF_TWO |
> +			 CLK_MESON_PLL_L_DETECT_ACTIVE_HIGH,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "mclk1_pll_dco",
> +		.ops = &meson_clk_pll_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&a9_mclk1_in_div2.hw
> +		},
> +		.num_parents = 1,
> +	},
> +};
> +
> +static struct clk_regmap a9_mclk1_0_pll = {
> +	.data = &(struct clk_regmap_div_data) {
> +		.offset = MCLKPLL_CTRL3,
> +		.shift = 0,
> +		.width = 3,
> +		.table = a9_pll_od_table,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "mclk1_0_pll",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&a9_mclk1_pll_dco.hw
> +		},
> +		.num_parents = 1,
> +	},
> +};
> +
> +static struct clk_regmap a9_mclk1_0_pre = {
> +	.data = &(struct clk_regmap_div_data) {
> +		.offset = MCLKPLL_CTRL3,
> +		.shift = 3,
> +		.width = 5,
> +		.flags = CLK_DIVIDER_MAX_AT_ZERO,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "mclk1_0_pre",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&a9_mclk1_0_pll.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static const struct clk_parent_data a9_mclk1_0_parents[] = {
> +	{ .hw = &a9_mclk1_0_pre.hw },
> +	{ .fw_name = "in0" },
> +	{ .fw_name = "in1" },
> +	{ .fw_name = "in2" }
> +};
> +
> +static A9_COMP_SEL(mclk1_0, MCLKPLL_CTRL3, 12, 0x3, a9_mclk1_0_parents);
> +static A9_COMP_DIV(mclk1_0, MCLKPLL_CTRL3, 10, 1);
> +static A9_COMP_GATE(mclk1_0, MCLKPLL_CTRL3, 8);
> +
> +static struct clk_regmap a9_mclk1_1_pll = {
> +	.data = &(struct clk_regmap_div_data) {
> +		.offset = MCLKPLL_CTRL3,
> +		.shift = 16,
> +		.width = 3,
> +		.table = a9_pll_od_table,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "mclk1_1_pll",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&a9_mclk1_pll_dco.hw
> +		},
> +		.num_parents = 1,
> +	},
> +};
> +
> +static struct clk_regmap a9_mclk1_1_pre = {
> +	.data = &(struct clk_regmap_div_data) {
> +		.offset = MCLKPLL_CTRL3,
> +		.shift = 19,
> +		.width = 5,
> +		.flags = CLK_DIVIDER_MAX_AT_ZERO,
> +	},
> +	.hw.init = &(struct clk_init_data) {
> +		.name = "mclk1_1_pre",
> +		.ops = &clk_regmap_divider_ops,
> +		.parent_hws = (const struct clk_hw *[]) {
> +			&a9_mclk1_1_pll.hw
> +		},
> +		.num_parents = 1,
> +		.flags = CLK_SET_RATE_PARENT,
> +	},
> +};
> +
> +static const struct clk_parent_data a9_mclk1_1_parents[] = {
> +	{ .hw = &a9_mclk1_1_pre.hw },
> +	{ .fw_name = "in0" },
> +	{ .fw_name = "in1" },
> +	{ .fw_name = "in2" }
> +};
> +
> +static A9_COMP_SEL(mclk1_1, MCLKPLL_CTRL3, 28, 0x3, a9_mclk1_1_parents);
> +static A9_COMP_DIV(mclk1_1, MCLKPLL_CTRL3, 26, 1);
> +static A9_COMP_GATE(mclk1_1, MCLKPLL_CTRL3, 24);
> +
> +static struct clk_hw *a9_gp0_hw_clks[] = {
> +	[CLKID_GP0_IN_DIV2_DIV]		= &a9_gp0_in_div2_div.hw,
> +	[CLKID_GP0_IN_DIV2]		= &a9_gp0_in_div2.hw,
> +	[CLKID_GP0_PLL_DCO]		= &a9_gp0_pll_dco.hw,
> +	[CLKID_GP0_PLL]			= &a9_gp0_pll.hw,
> +};
> +
> +static struct clk_hw *a9_hifi0_hw_clks[] = {
> +	[CLKID_HIFI0_IN_DIV2_DIV]	= &a9_hifi0_in_div2_div.hw,
> +	[CLKID_HIFI0_IN_DIV2]		= &a9_hifi0_in_div2.hw,
> +	[CLKID_HIFI0_PLL_DCO]		= &a9_hifi0_pll_dco.hw,
> +	[CLKID_HIFI0_PLL]		= &a9_hifi0_pll.hw,
> +};
> +
> +static struct clk_hw *a9_hifi1_hw_clks[] = {
> +	[CLKID_HIFI1_IN_DIV2_DIV]	= &a9_hifi1_in_div2_div.hw,
> +	[CLKID_HIFI1_IN_DIV2]		= &a9_hifi1_in_div2.hw,
> +	[CLKID_HIFI1_PLL_DCO]		= &a9_hifi1_pll_dco.hw,
> +	[CLKID_HIFI1_PLL]		= &a9_hifi1_pll.hw,
> +};
> +
> +static struct clk_hw *a9_mclk0_hw_clks[] = {
> +	[CLKID_MCLK0_IN_DIV2]		= &a9_mclk0_in_div2.hw,
> +	[CLKID_MCLK0_PLL_DCO]		= &a9_mclk0_pll_dco.hw,
> +	[CLKID_MCLK0_0_PLL]		= &a9_mclk0_0_pll.hw,
> +	[CLKID_MCLK0_0_PRE]		= &a9_mclk0_0_pre.hw,
> +	[CLKID_MCLK0_0_SEL]		= &a9_mclk0_0_sel.hw,
> +	[CLKID_MCLK0_0_DIV]		= &a9_mclk0_0_div.hw,
> +	[CLKID_MCLK0_0]			= &a9_mclk0_0.hw,
> +	[CLKID_MCLK0_1_PLL]		= &a9_mclk0_1_pll.hw,
> +	[CLKID_MCLK0_1_PRE]		= &a9_mclk0_1_pre.hw,
> +	[CLKID_MCLK0_1_SEL]		= &a9_mclk0_1_sel.hw,
> +	[CLKID_MCLK0_1_DIV]		= &a9_mclk0_1_div.hw,
> +	[CLKID_MCLK0_1]			= &a9_mclk0_1.hw,
> +};
> +
> +static struct clk_hw *a9_mclk1_hw_clks[] = {
> +	[CLKID_MCLK1_IN_DIV2]		= &a9_mclk1_in_div2.hw,
> +	[CLKID_MCLK1_PLL_DCO]		= &a9_mclk1_pll_dco.hw,
> +	[CLKID_MCLK1_0_PLL]		= &a9_mclk1_0_pll.hw,
> +	[CLKID_MCLK1_0_PRE]		= &a9_mclk1_0_pre.hw,
> +	[CLKID_MCLK1_0_SEL]		= &a9_mclk1_0_sel.hw,
> +	[CLKID_MCLK1_0_DIV]		= &a9_mclk1_0_div.hw,
> +	[CLKID_MCLK1_0]			= &a9_mclk1_0.hw,
> +	[CLKID_MCLK1_1_PLL]		= &a9_mclk1_1_pll.hw,
> +	[CLKID_MCLK1_1_PRE]		= &a9_mclk1_1_pre.hw,
> +	[CLKID_MCLK1_1_SEL]		= &a9_mclk1_1_sel.hw,
> +	[CLKID_MCLK1_1_DIV]		= &a9_mclk1_1_div.hw,
> +	[CLKID_MCLK1_1]			= &a9_mclk1_1.hw,
> +};
> +
> +static const struct meson_clkc_data a9_gp0_data = {
> +	.hw_clks = {
> +		.hws = a9_gp0_hw_clks,
> +		.num = ARRAY_SIZE(a9_gp0_hw_clks),
> +	},
> +};
> +
> +static const struct meson_clkc_data a9_hifi0_data = {
> +	.hw_clks = {
> +		.hws = a9_hifi0_hw_clks,
> +		.num = ARRAY_SIZE(a9_hifi0_hw_clks),
> +	},
> +};
> +
> +static const struct meson_clkc_data a9_hifi1_data = {
> +	.hw_clks = {
> +		.hws = a9_hifi1_hw_clks,
> +		.num = ARRAY_SIZE(a9_hifi1_hw_clks),
> +	},
> +};
> +
> +static const struct meson_clkc_data a9_mclk0_data = {
> +	.hw_clks = {
> +		.hws = a9_mclk0_hw_clks,
> +		.num = ARRAY_SIZE(a9_mclk0_hw_clks),
> +	},
> +};
> +
> +static const struct meson_clkc_data a9_mclk1_data = {
> +	.hw_clks = {
> +		.hws = a9_mclk1_hw_clks,
> +		.num = ARRAY_SIZE(a9_mclk1_hw_clks),
> +	},
> +};
> +
> +static const struct of_device_id a9_pll_clkc_match_table[] = {
> +	{ .compatible = "amlogic,a9-gp0-pll",	.data = &a9_gp0_data, },
> +	{ .compatible = "amlogic,a9-hifi0-pll",	.data = &a9_hifi0_data, },
> +	{ .compatible = "amlogic,a9-hifi1-pll",	.data = &a9_hifi1_data, },
> +	{ .compatible = "amlogic,a9-mclk0-pll",	.data = &a9_mclk0_data, },
> +	{ .compatible = "amlogic,a9-mclk1-pll", .data = &a9_mclk1_data, },
> +	{}
> +};
> +MODULE_DEVICE_TABLE(of, a9_pll_clkc_match_table);
> +
> +static struct platform_driver a9_pll_clkc_driver = {
> +	.probe		= meson_clkc_mmio_probe,
> +	.driver		= {
> +		.name	= "a9-pll-clkc",
> +		.of_match_table = a9_pll_clkc_match_table,
> +	},
> +};
> +module_platform_driver(a9_pll_clkc_driver);
> +
> +MODULE_DESCRIPTION("Amlogic A9 PLL Clock Controller Driver");
> +MODULE_AUTHOR("Jian Hu <jian.hu@amlogic.com>");
> +MODULE_LICENSE("GPL");
> +MODULE_IMPORT_NS("CLK_MESON");

-- >8 --
diff --git a/drivers/clk/meson/meson-clkc-utils.c b/drivers/clk/meson/meson-clkc-utils.c
index 870f50548e26..f95a0d9212fa 100644
--- a/drivers/clk/meson/meson-clkc-utils.c
+++ b/drivers/clk/meson/meson-clkc-utils.c
@@ -26,16 +26,12 @@ struct clk_hw *meson_clk_hw_get(struct of_phandle_args *clkspec, void *clk_hw_da
 }
 EXPORT_SYMBOL_NS_GPL(meson_clk_hw_get, "CLK_MESON");
 
-static int meson_clkc_init(struct device *dev, struct regmap *map)
+static int meson_clkc_init(struct device *dev, struct regmap *map,
+	const struct meson_clkc_data *data)
 {
-	const struct meson_clkc_data *data;
 	struct clk_hw *hw;
 	int ret, i;
 
-	data = of_device_get_match_data(dev);
-	if (!data)
-		return -EINVAL;
-
 	if (data->init_count)
 		regmap_multi_reg_write(map, data->init_regs, data->init_count);
 
@@ -59,6 +55,7 @@ static int meson_clkc_init(struct device *dev, struct regmap *map)
 
 int meson_clkc_syscon_probe(struct platform_device *pdev)
 {
+	const struct meson_clkc_data *data;
 	struct device *dev = &pdev->dev;
 	struct device_node *np;
 	struct regmap *map;
@@ -71,7 +68,11 @@ int meson_clkc_syscon_probe(struct platform_device *pdev)
 		return PTR_ERR(map);
 	}
 
-	return meson_clkc_init(dev, map);
+	data = of_device_get_match_data(dev);
+	if (!data)
+		return -EINVAL;
+
+	return meson_clkc_init(dev, map, data);
 }
 EXPORT_SYMBOL_NS_GPL(meson_clkc_syscon_probe, "CLK_MESON");
 
@@ -102,7 +103,7 @@ int meson_clkc_mmio_probe(struct platform_device *pdev)
 	if (IS_ERR(map))
 		return PTR_ERR(map);
 
-	return meson_clkc_init(dev, map);
+	return meson_clkc_init(dev, map, data);
 }
 EXPORT_SYMBOL_NS_GPL(meson_clkc_mmio_probe, "CLK_MESON");


^ permalink raw reply related

* Re: [PATCH v3] phy: apple: atc: Fix typec switch/mux leak on unbind
From: Vinod Koul @ 2026-05-14 16:08 UTC (permalink / raw)
  To: sven, j, neal, neil.armstrong, marcan, p.zabel, David Carlier
  Cc: olteanv, asahi, linux-arm-kernel, linux-phy, linux-kernel
In-Reply-To: <20260508201958.30060-1-devnexen@gmail.com>


On Fri, 08 May 2026 21:19:58 +0100, David Carlier wrote:
> atcphy_probe_switch() and atcphy_probe_mux() discard the pointers
> returned by typec_switch_register() and typec_mux_register(). The
> platform driver has no .remove callback, so when the driver unbinds
> (e.g. via sysfs unbind) neither typec_switch_unregister() nor
> typec_mux_unregister() is called. The framework reference taken in
> typec_switch_register() (device_initialize() + device_add() in
> drivers/usb/typec/mux.c) is therefore never dropped and the
> typec_switch_dev / typec_mux_dev objects stay live forever, with
> their sysfs entries under the typec_mux class also left behind. A
> subsequent rebind cannot recreate them with the same fwnode-derived
> name.
> 
> [...]

Applied, thanks!

[1/1] phy: apple: atc: Fix typec switch/mux leak on unbind
      commit: 1854082fe0ddb81bc93d1f8e8a00554217fd09d1

Best regards,
-- 
~Vinod




^ permalink raw reply

* [PATCH v2 11/17] arm64: dts: mediatek: Add EL2 virtual timer interrupt
From: Marc Zyngier @ 2026-05-14 15:09 UTC (permalink / raw)
  To: linux-arm-kernel, linux-acpi, linux-kernel, devicetree
  Cc: Lorenzo Pieralisi, Hanjun Guo, Sudeep Holla, Catalin Marinas,
	Will Deacon, Rafael J. Wysocki, Mark Rutland, Daniel Lezcano,
	Thomas Gleixner, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Chen-Yu Tsai, Jernej Skrabec, Samuel Holland, Neil Armstrong,
	Kevin Hilman, Jerome Brunet, Martin Blumenstingl, Ge Gordon,
	BST Linux Kernel Upstream Group, Jesper Nilsson, Lars Persson,
	Alim Akhtar, Ivaylo Ivanov, Frank Li, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, Dinh Nguyen,
	Matthias Brugger, AngeloGioacchino Del Regno, Thierry Reding,
	Jonathan Hunter, Bjorn Andersson, Konrad Dybcio,
	Andreas Färber, Heiko Stuebner, Shawn Lin, Orson Zhai,
	Baolin Wang, Michal Simek
In-Reply-To: <20260514150945.3917510-1-maz@kernel.org>

The ARMv8.1+ based CPUs used in a number of Mediatek SoCs are missing
the EL2 virtual timer interrupt. Add it.

Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 arch/arm64/boot/dts/mediatek/mt6779.dtsi | 3 ++-
 arch/arm64/boot/dts/mediatek/mt8186.dtsi | 3 ++-
 arch/arm64/boot/dts/mediatek/mt8188.dtsi | 3 ++-
 arch/arm64/boot/dts/mediatek/mt8192.dtsi | 3 ++-
 arch/arm64/boot/dts/mediatek/mt8195.dtsi | 3 ++-
 5 files changed, 10 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt6779.dtsi b/arch/arm64/boot/dts/mediatek/mt6779.dtsi
index 70f3375916e8c..106df7603d533 100644
--- a/arch/arm64/boot/dts/mediatek/mt6779.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt6779.dtsi
@@ -108,7 +108,8 @@ timer {
 		interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW 0>,
 			     <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW 0>,
 			     <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW 0>,
-			     <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW 0>;
+			     <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW 0>,
+			     <GIC_PPI 12 IRQ_TYPE_LEVEL_LOW 0>;
 	};
 
 	soc {
diff --git a/arch/arm64/boot/dts/mediatek/mt8186.dtsi b/arch/arm64/boot/dts/mediatek/mt8186.dtsi
index b91f88ffae0e8..a4621ce370d8e 100644
--- a/arch/arm64/boot/dts/mediatek/mt8186.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8186.dtsi
@@ -815,7 +815,8 @@ timer {
 		interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW 0>,
 			     <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW 0>,
 			     <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW 0>,
-			     <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW 0>;
+			     <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW 0>,
+			     <GIC_PPI 12 IRQ_TYPE_LEVEL_LOW 0>;
 	};
 
 	soc {
diff --git a/arch/arm64/boot/dts/mediatek/mt8188.dtsi b/arch/arm64/boot/dts/mediatek/mt8188.dtsi
index 75133794cec38..614e75f46c72d 100644
--- a/arch/arm64/boot/dts/mediatek/mt8188.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8188.dtsi
@@ -918,7 +918,8 @@ timer: timer {
 		interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_HIGH 0>,
 			     <GIC_PPI 14 IRQ_TYPE_LEVEL_HIGH 0>,
 			     <GIC_PPI 11 IRQ_TYPE_LEVEL_HIGH 0>,
-			     <GIC_PPI 10 IRQ_TYPE_LEVEL_HIGH 0>;
+			     <GIC_PPI 10 IRQ_TYPE_LEVEL_HIGH 0>,
+			     <GIC_PPI 12 IRQ_TYPE_LEVEL_HIGH 0>;
 		clock-frequency = <13000000>;
 	};
 
diff --git a/arch/arm64/boot/dts/mediatek/mt8192.dtsi b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
index 9f8f115edd4cc..873c4fae6afc9 100644
--- a/arch/arm64/boot/dts/mediatek/mt8192.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
@@ -328,7 +328,8 @@ timer: timer {
 		interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_HIGH 0>,
 			     <GIC_PPI 14 IRQ_TYPE_LEVEL_HIGH 0>,
 			     <GIC_PPI 11 IRQ_TYPE_LEVEL_HIGH 0>,
-			     <GIC_PPI 10 IRQ_TYPE_LEVEL_HIGH 0>;
+			     <GIC_PPI 10 IRQ_TYPE_LEVEL_HIGH 0>,
+			     <GIC_PPI 12 IRQ_TYPE_LEVEL_HIGH 0>;
 		clock-frequency = <13000000>;
 	};
 
diff --git a/arch/arm64/boot/dts/mediatek/mt8195.dtsi b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
index c72e34c57629d..3c9a7a08612b9 100644
--- a/arch/arm64/boot/dts/mediatek/mt8195.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
@@ -451,7 +451,8 @@ timer: timer {
 		interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_HIGH 0>,
 			     <GIC_PPI 14 IRQ_TYPE_LEVEL_HIGH 0>,
 			     <GIC_PPI 11 IRQ_TYPE_LEVEL_HIGH 0>,
-			     <GIC_PPI 10 IRQ_TYPE_LEVEL_HIGH 0>;
+			     <GIC_PPI 10 IRQ_TYPE_LEVEL_HIGH 0>,
+			     <GIC_PPI 12 IRQ_TYPE_LEVEL_HIGH 0>;
 	};
 
 	soc {
-- 
2.47.3



^ permalink raw reply related

* [PATCH v2 09/17] arm64: dts: freescale: Add EL2 virtual timer interrupt
From: Marc Zyngier @ 2026-05-14 15:09 UTC (permalink / raw)
  To: linux-arm-kernel, linux-acpi, linux-kernel, devicetree
  Cc: Lorenzo Pieralisi, Hanjun Guo, Sudeep Holla, Catalin Marinas,
	Will Deacon, Rafael J. Wysocki, Mark Rutland, Daniel Lezcano,
	Thomas Gleixner, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Chen-Yu Tsai, Jernej Skrabec, Samuel Holland, Neil Armstrong,
	Kevin Hilman, Jerome Brunet, Martin Blumenstingl, Ge Gordon,
	BST Linux Kernel Upstream Group, Jesper Nilsson, Lars Persson,
	Alim Akhtar, Ivaylo Ivanov, Frank Li, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, Dinh Nguyen,
	Matthias Brugger, AngeloGioacchino Del Regno, Thierry Reding,
	Jonathan Hunter, Bjorn Andersson, Konrad Dybcio,
	Andreas Färber, Heiko Stuebner, Shawn Lin, Orson Zhai,
	Baolin Wang, Michal Simek
In-Reply-To: <20260514150945.3917510-1-maz@kernel.org>

The ARMv8.2 based CPUs used in a number of NXP/FSL SoCs are missing
the EL2 virtual timer interrupt. Add it.

Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 arch/arm64/boot/dts/freescale/imx91_93_common.dtsi | 3 ++-
 arch/arm64/boot/dts/freescale/imx94.dtsi           | 3 ++-
 arch/arm64/boot/dts/freescale/imx95.dtsi           | 3 ++-
 arch/arm64/boot/dts/freescale/imx952.dtsi          | 3 ++-
 arch/arm64/boot/dts/freescale/s32n79.dtsi          | 3 ++-
 5 files changed, 10 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/imx91_93_common.dtsi b/arch/arm64/boot/dts/freescale/imx91_93_common.dtsi
index 46a5d2df074d5..679b9a6f7160f 100644
--- a/arch/arm64/boot/dts/freescale/imx91_93_common.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx91_93_common.dtsi
@@ -82,7 +82,8 @@ timer {
 		interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
 			     <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
 			     <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
-			     <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
+			     <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_PPI 12 IRQ_TYPE_LEVEL_LOW>;
 		clock-frequency = <24000000>;
 		arm,no-tick-in-suspend;
 		interrupt-parent = <&gic>;
diff --git a/arch/arm64/boot/dts/freescale/imx94.dtsi b/arch/arm64/boot/dts/freescale/imx94.dtsi
index c460ece6070f8..7431ce293625b 100644
--- a/arch/arm64/boot/dts/freescale/imx94.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx94.dtsi
@@ -147,7 +147,8 @@ timer {
 		interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
 			     <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
 			     <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
-			     <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
+			     <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_PPI 12 IRQ_TYPE_LEVEL_LOW>;
 		clock-frequency = <24000000>;
 		interrupt-parent = <&gic>;
 		arm,no-tick-in-suspend;
diff --git a/arch/arm64/boot/dts/freescale/imx95.dtsi b/arch/arm64/boot/dts/freescale/imx95.dtsi
index 71394871d8dd0..e318048dc755b 100644
--- a/arch/arm64/boot/dts/freescale/imx95.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx95.dtsi
@@ -524,7 +524,8 @@ timer {
 		interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
 			     <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
 			     <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
-			     <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
+			     <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_PPI 12 IRQ_TYPE_LEVEL_LOW>;
 		clock-frequency = <24000000>;
 		arm,no-tick-in-suspend;
 		interrupt-parent = <&gic>;
diff --git a/arch/arm64/boot/dts/freescale/imx952.dtsi b/arch/arm64/boot/dts/freescale/imx952.dtsi
index b30707837f353..7c65956bc72dc 100644
--- a/arch/arm64/boot/dts/freescale/imx952.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx952.dtsi
@@ -298,7 +298,8 @@ timer {
 		interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
 			     <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
 			     <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
-			     <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
+			     <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_PPI 12 IRQ_TYPE_LEVEL_LOW>;
 		clock-frequency = <24000000>;
 		arm,no-tick-in-suspend;
 		interrupt-parent = <&gic>;
diff --git a/arch/arm64/boot/dts/freescale/s32n79.dtsi b/arch/arm64/boot/dts/freescale/s32n79.dtsi
index 94ab58783fdc8..fb40abec4c5cd 100644
--- a/arch/arm64/boot/dts/freescale/s32n79.dtsi
+++ b/arch/arm64/boot/dts/freescale/s32n79.dtsi
@@ -357,6 +357,7 @@ timer: timer {
 		interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
 			     <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
 			     <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
-			     <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
+			     <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_PPI 12 IRQ_TYPE_LEVEL_LOW>;
 	};
 };
-- 
2.47.3



^ permalink raw reply related

* Re: [PATCH v3 1/4] dt-bindings: usb: dwc3-xilinx: Add MMI USB support on Versal Gen2 platform
From: Krzysztof Kozlowski @ 2026-05-14 16:00 UTC (permalink / raw)
  To: Pandey, Radhey Shyam, Radhey Shyam Pandey
  Cc: gregkh, robh, krzk+dt, conor+dt, michal.simek, Thinh.Nguyen,
	p.zabel, linux-usb, devicetree, linux-arm-kernel, linux-kernel,
	git
In-Reply-To: <f9f25ef4-a541-45a2-b98c-4a411239993b@amd.com>

On 07/05/2026 21:01, Pandey, Radhey Shyam wrote:
>> On Wed, Apr 29, 2026 at 11:00:47PM +0530, Radhey Shyam Pandey wrote:
>>>   additionalProperties: false
>>>   
>>>   examples:
>>> @@ -156,3 +193,30 @@ examples:
>>>               };
>>>           };
>>>       };
>>> +  - |
>>> +    #include <dt-bindings/power/xlnx-zynqmp-power.h>
>>> +    #include <dt-bindings/reset/xlnx-zynqmp-resets.h>
>>> +    #include <dt-bindings/phy/phy.h>
>>> +    usb {
>>> +        #address-cells = <1>;
>>> +        #size-cells = <1>;
>> Please follow DTS coding style.
> Thanks for the review. will fix it in next version.
>>> +        compatible = "xlnx,versal2-mmi-dwc3";
>> I really doubt that DWC3 block comes without addressing space
>> (registers), so either you just misrepresented things, like created a
>> fake block and syscon, or forgot to combine DWC3 with the wrapper.
>>
>> And if you built with W=1 your DTS you would see errors. How do you see
>> it now? Where do you place it? Wrapper must be outside of soc, but DWC3
>> child must be inside. Did you read submitting patches and writing
>> bindings documents?
> Apologies for missing the DTS sanity check earlier. I am summarizing the
> problem statement and possible solution. Please review.
> 
> For MMI USB in current implementation it need a parent/child
> representation. However, the parent IP is shared across DP, USB,
> and HDCP, so it cannot have a USB-dedicated parent reg space.
> 
> 1. Versal platform
>    - Parent: USB wrapper IP → has its own I/O space
>    - Child: USB DWC3
> 
> 2. Versal Gen2 platform - MMI USB
>    - Parent subsystem combines DP, USB, and HDCP in a single I/O space
>    - Children:
>      - USB DWC3
>      - DP
>      - HDCP
> 
> To model the Versal Gen2 MMI USB parent register space, I introduced
> xlnx,usb-syscon, allowing the DWC3 driver to access parent registers
> via a syscon handle, addressing the v1 review comment.

Syscon phandle is not to express such relationsship.

> 
> However, making reg optional satisfies schema validation but fails
> DTB checks.
> 
> versal2.dtsi:1: Warning (simple_bus_reg):
> /axi/mmi-usb: missing or empty reg/ranges property

Yep, exactly.

> 
> To fix it i think we can switch from parent/child representation to
> flat DT representation for the Versal Gen2 platform, similar to
> existing implementations in qcom,snps-dwc3 and Google Tensor G5 DWC3
> bindings[1].
> 
> The Google Tensor DWC3 binding uses a syscon phandle to access USB
> configuration registers, which aligns well with the Versal Gen2 MMI

Not true. Just read the binding. If you refer to Tensor, then to access
A FEW configuration registers. If you refer to LGA, then it has address
space.

> USB IP, where wrapper subsystem shares a common register space for
> USB along with other IPs.



> 
> If this approach looks fine , will create binding for MMI USB using
> this flat representation and send out next version.
> 
> usb@fe200000 {
> compatible = "xlnx,versal2-mmi-dwc3";
> reg = <0xfe200000 0x40000>;
> xlnx,usb-syscon = <&udh_slcr 0x005c 0x0070 0x00c4 0x00f8>;
> <snip>
> };

So I am confused. We ask, since long time, to have unified child.
Several platforms were already converted. What are you discussing with
in such case?

Are you going to have unified node or not?


Best regards,
Krzysztof


^ permalink raw reply

* Re: [PATCH 07/10] clk: amlogic: Support POWER_OF_TWO for PLL pre-divider
From: Jerome Brunet @ 2026-05-14 15:11 UTC (permalink / raw)
  To: Jian Hu via B4 Relay
  Cc: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Neil Armstrong, Xianwei Zhao, Kevin Hilman,
	Martin Blumenstingl, jian.hu, linux-kernel, linux-clk, devicetree,
	linux-amlogic, linux-arm-kernel
In-Reply-To: <20260511-b4-a9_clk-v1-7-41cb4071b7c9@amlogic.com>

On lun. 11 mai 2026 at 20:47, Jian Hu via B4 Relay <devnull+jian.hu.amlogic.com@kernel.org> wrote:

> From: Jian Hu <jian.hu@amlogic.com>
>
> The A9 PLL pre-divider uses a division factor of 2^n to ensure a clock
> duty cycle of 50% after predivision.
>
> Add flag 'CLK_MESON_PLL_N_POWER_OF_TWO' to indicate that the PLL
> pre-divider division factor is 2^n.

I understand what you are doing here but I have to ask why this can't be
implemented with independent dividers that already supports power of 2 ?

>
> Signed-off-by: Jian Hu <jian.hu@amlogic.com>
> ---
>  drivers/clk/meson/clk-pll.c | 28 +++++++++++++++++++++++-----
>  drivers/clk/meson/clk-pll.h |  2 ++
>  2 files changed, 25 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/clk/meson/clk-pll.c b/drivers/clk/meson/clk-pll.c
> index 8568ad6ba7b6..49483e431d44 100644
> --- a/drivers/clk/meson/clk-pll.c
> +++ b/drivers/clk/meson/clk-pll.c
> @@ -66,6 +66,9 @@ static unsigned long __pll_params_to_rate(unsigned long parent_rate,
>  		rate += DIV_ROUND_UP_ULL(frac_rate, frac_max);
>  	}
>  
> +	if (pll->flags & CLK_MESON_PLL_N_POWER_OF_TWO)
> +		n = 1 << n;
> +
>  	return DIV_ROUND_UP_ULL(rate, n);
>  }
>  
> @@ -83,7 +86,7 @@ static unsigned long meson_clk_pll_recalc_rate(struct clk_hw *hw,
>  	 * it would result in a division by zero. The rate can't be
>  	 * calculated in this case
>  	 */
> -	if (n == 0)
> +	if (n == 0 && !(pll->flags & CLK_MESON_PLL_N_POWER_OF_TWO))
>  		return 0;
>  
>  	m = meson_parm_read(clk->map, &pll->m);
> @@ -103,7 +106,12 @@ static unsigned int __pll_params_with_frac(unsigned long rate,
>  {
>  	unsigned int frac_max = pll->frac_max ? pll->frac_max :
>  						(1 << pll->frac.width);
> -	u64 val = (u64)rate * n;
> +	u64 val;
> +
> +	if (pll->flags & CLK_MESON_PLL_N_POWER_OF_TWO)
> +		n = 1 << n;
> +
> +	val = (u64)rate * n;
>  
>  	/* Bail out if we are already over the requested rate */
>  	if (rate < parent_rate * m / n)
> @@ -142,7 +150,8 @@ static int meson_clk_get_pll_table_index(unsigned int index,
>  					 unsigned int *n,
>  					 struct meson_clk_pll_data *pll)
>  {
> -	if (!pll->table[index].n)
> +	if (!pll->table[index].n &&
> +	    !(pll->flags & CLK_MESON_PLL_N_POWER_OF_TWO))
>  		return -EINVAL;
>  
>  	*m = pll->table[index].m;
> @@ -156,7 +165,12 @@ static unsigned int meson_clk_get_pll_range_m(unsigned long rate,
>  					      unsigned int n,
>  					      struct meson_clk_pll_data *pll)
>  {
> -	u64 val = (u64)rate * n;
> +	u64 val;
> +
> +	if (pll->flags & CLK_MESON_PLL_N_POWER_OF_TWO)
> +		n = 1 << n;
> +
> +	val = (u64)rate * n;
>  
>  	if (__pll_round_closest_mult(pll))
>  		return DIV_ROUND_CLOSEST_ULL(val, parent_rate);
> @@ -173,11 +187,15 @@ static int meson_clk_get_pll_range_index(unsigned long rate,
>  {
>  	*n = index + 1;
>  
> +	if ((pll->flags & CLK_MESON_PLL_N_POWER_OF_TWO))
> +		*n = index;
> +
>  	/* Check the predivider range */
>  	if (*n >= (1 << pll->n.width))
>  		return -EINVAL;
>  
> -	if (*n == 1) {
> +	if ((*n == 1 && !(pll->flags & CLK_MESON_PLL_N_POWER_OF_TWO)) ||
> +	    (*n == 0 && (pll->flags & CLK_MESON_PLL_N_POWER_OF_TWO))) {
>  		/* Get the boundaries out the way */
>  		if (rate <= pll->range->min * parent_rate) {
>  			*m = pll->range->min;
> diff --git a/drivers/clk/meson/clk-pll.h b/drivers/clk/meson/clk-pll.h
> index 1be7e6e77631..60b2772a54c8 100644
> --- a/drivers/clk/meson/clk-pll.h
> +++ b/drivers/clk/meson/clk-pll.h
> @@ -33,6 +33,8 @@ struct pll_mult_range {
>  #define CLK_MESON_PLL_L_DETECT_ACTIVE_HIGH	BIT(2)
>  /* rst signal is active-low (Power-on reset) */
>  #define CLK_MESON_PLL_RST_ACTIVE_LOW	BIT(3)
> +/* The division factor of the PLL pre-divider is 2^n */
> +#define CLK_MESON_PLL_N_POWER_OF_TWO	BIT(4)
>  
>  struct meson_clk_pll_data {
>  	struct parm en;

-- 
Jerome


^ permalink raw reply

* RE: [PATCH 4/4] perf: nvidia_t410_c2c: handle PERF_EF_UPDATE in stop
From: Besar Wicaksono @ 2026-05-14 16:00 UTC (permalink / raw)
  To: Saurav Sachidanand, Will Deacon
  Cc: Mark Rutland, Ilkka Koskinen, Andi Shyti,
	linux-arm-kernel@lists.infradead.org,
	linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org,
	aghayev@amazon.com, juew@amazon.com
In-Reply-To: <20260514010629.76558-4-sauravsc@amazon.com>



> -----Original Message-----
> From: Saurav Sachidanand <sauravsc@amazon.com>
> Sent: Wednesday, May 13, 2026 8:06 PM
> To: Will Deacon <will@kernel.org>
> Cc: Mark Rutland <mark.rutland@arm.com>; Besar Wicaksono
> <bwicaksono@nvidia.com>; Ilkka Koskinen
> <ilkka@os.amperecomputing.com>; Andi Shyti <andi.shyti@kernel.org>; linux-
> arm-kernel@lists.infradead.org; linux-perf-users@vger.kernel.org; linux-
> kernel@vger.kernel.org; aghayev@amazon.com; juew@amazon.com; Saurav
> Sachidanand <sauravsc@amazon.com>
> Subject: [PATCH 4/4] perf: nvidia_t410_c2c: handle PERF_EF_UPDATE in stop
> 
> External email: Use caution opening links or attachments
> 
> 
> nv_c2c_pmu_stop() does not read the final counter value when called
> with PERF_EF_UPDATE. The last counter delta is lost when perf core
> removes the event.
> 
> Add the standard PMU stop pattern: bail out if already stopped, call
> nv_c2c_pmu_event_update() when PERF_EF_UPDATE is requested, then mark
> the event stopped.
> 
> Fixes: 2f89b7f78c50 ("perf: add NVIDIA Tegra410 C2C PMU")
> Signed-off-by: Saurav Sachidanand <sauravsc@amazon.com>
> ---
>  drivers/perf/nvidia_t410_c2c_pmu.c | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/drivers/perf/nvidia_t410_c2c_pmu.c
> b/drivers/perf/nvidia_t410_c2c_pmu.c
> index 662fa1bc833a5..39d0e661e4c5c 100644
> --- a/drivers/perf/nvidia_t410_c2c_pmu.c
> +++ b/drivers/perf/nvidia_t410_c2c_pmu.c
> @@ -394,6 +394,12 @@ static void nv_c2c_pmu_start(struct perf_event
> *event, int pmu_flags)
> 
>  static void nv_c2c_pmu_stop(struct perf_event *event, int pmu_flags)
>  {
> +       if (event->hw.state & PERF_HES_STOPPED)
> +               return;
> +
> +       if (pmu_flags & PERF_EF_UPDATE)
> +               nv_c2c_pmu_event_update(event);
> +

Hi Saurav,

This call is not needed since the driver called it on pmu_disable callback.
Adding it on stop callback would be redundant.

Regards,
Besar


^ permalink raw reply

* RE: [PATCH 2/4] perf: nvidia_t410_cmem_latency: handle PERF_EF_UPDATE in stop
From: Besar Wicaksono @ 2026-05-14 15:59 UTC (permalink / raw)
  To: Saurav Sachidanand, Will Deacon
  Cc: Mark Rutland, Ilkka Koskinen, Andi Shyti,
	linux-arm-kernel@lists.infradead.org,
	linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org,
	aghayev@amazon.com, juew@amazon.com
In-Reply-To: <20260514010629.76558-2-sauravsc@amazon.com>



> -----Original Message-----
> From: Saurav Sachidanand <sauravsc@amazon.com>
> Sent: Wednesday, May 13, 2026 8:06 PM
> To: Will Deacon <will@kernel.org>
> Cc: Mark Rutland <mark.rutland@arm.com>; Besar Wicaksono
> <bwicaksono@nvidia.com>; Ilkka Koskinen
> <ilkka@os.amperecomputing.com>; Andi Shyti <andi.shyti@kernel.org>; linux-
> arm-kernel@lists.infradead.org; linux-perf-users@vger.kernel.org; linux-
> kernel@vger.kernel.org; aghayev@amazon.com; juew@amazon.com; Saurav
> Sachidanand <sauravsc@amazon.com>
> Subject: [PATCH 2/4] perf: nvidia_t410_cmem_latency: handle
> PERF_EF_UPDATE in stop
> 
> External email: Use caution opening links or attachments
> 
> 
> cmem_lat_pmu_stop() does not read the final counter value when called
> with PERF_EF_UPDATE. When perf core calls pmu->del() -> pmu->stop()
> with PERF_EF_UPDATE, the last counter delta is lost because the event
> is marked stopped without reading hardware.
> 
> Add the standard PMU stop pattern: bail out if already stopped, call
> the event update function when PERF_EF_UPDATE is requested, then mark
> the event stopped.
> 
> Fixes: 429b7638b2df ("perf: add NVIDIA Tegra410 CPU Memory Latency
> PMU")
> Signed-off-by: Saurav Sachidanand <sauravsc@amazon.com>
> ---
>  drivers/perf/nvidia_t410_cmem_latency_pmu.c | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/drivers/perf/nvidia_t410_cmem_latency_pmu.c
> b/drivers/perf/nvidia_t410_cmem_latency_pmu.c
> index e27bf31b2b366..c7fa54c7a7c9e 100644
> --- a/drivers/perf/nvidia_t410_cmem_latency_pmu.c
> +++ b/drivers/perf/nvidia_t410_cmem_latency_pmu.c
> @@ -303,6 +303,12 @@ static void cmem_lat_pmu_start(struct perf_event
> *event, int pmu_flags)
> 
>  static void cmem_lat_pmu_stop(struct perf_event *event, int pmu_flags)
>  {
> +       if (event->hw.state & PERF_HES_STOPPED)
> +               return;
> +
> +       if (pmu_flags & PERF_EF_UPDATE)
> +               cmem_lat_pmu_event_update(event);
> +

Hi Saurav,

This call is not needed since the driver called it on pmu_disable callback.
Adding it on stop callback would be redundant.

Regards,
Besar



^ permalink raw reply

* RE: [PATCH 3/4] perf: nvidia_t410_c2c: fix cpuhp state leak on init failure
From: Besar Wicaksono @ 2026-05-14 15:57 UTC (permalink / raw)
  To: Saurav Sachidanand, Will Deacon
  Cc: Mark Rutland, Ilkka Koskinen, Andi Shyti,
	linux-arm-kernel@lists.infradead.org,
	linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org,
	aghayev@amazon.com, juew@amazon.com
In-Reply-To: <20260514010629.76558-3-sauravsc@amazon.com>



> -----Original Message-----
> From: Saurav Sachidanand <sauravsc@amazon.com>
> Sent: Wednesday, May 13, 2026 8:06 PM
> To: Will Deacon <will@kernel.org>
> Cc: Mark Rutland <mark.rutland@arm.com>; Besar Wicaksono
> <bwicaksono@nvidia.com>; Ilkka Koskinen
> <ilkka@os.amperecomputing.com>; Andi Shyti <andi.shyti@kernel.org>; linux-
> arm-kernel@lists.infradead.org; linux-perf-users@vger.kernel.org; linux-
> kernel@vger.kernel.org; aghayev@amazon.com; juew@amazon.com; Saurav
> Sachidanand <sauravsc@amazon.com>
> Subject: [PATCH 3/4] perf: nvidia_t410_c2c: fix cpuhp state leak on init failure
> 
> External email: Use caution opening links or attachments
> 
> 
> If platform_driver_register() fails, the cpuhp multi-state registered
> by cpuhp_setup_state_multi() is never cleaned up. Add
> cpuhp_remove_multi_state() on the error path, mirroring the cleanup
> in nv_c2c_pmu_exit().
> 
> Fixes: 2f89b7f78c50 ("perf: add NVIDIA Tegra410 C2C PMU")
> Signed-off-by: Saurav Sachidanand <sauravsc@amazon.com>
> ---
>  drivers/perf/nvidia_t410_c2c_pmu.c | 7 ++++++-
>  1 file changed, 6 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/perf/nvidia_t410_c2c_pmu.c
> b/drivers/perf/nvidia_t410_c2c_pmu.c
> index 411987153ff3f..662fa1bc833a5 100644
> --- a/drivers/perf/nvidia_t410_c2c_pmu.c
> +++ b/drivers/perf/nvidia_t410_c2c_pmu.c
> @@ -1034,7 +1034,12 @@ static int __init nv_c2c_pmu_init(void)
>                 return ret;
> 
>         nv_c2c_pmu_cpuhp_state = ret;
> -       return platform_driver_register(&nv_c2c_pmu_driver);
> +
> +       ret = platform_driver_register(&nv_c2c_pmu_driver);
> +       if (ret)
> +               cpuhp_remove_multi_state(nv_c2c_pmu_cpuhp_state);
> +
> +       return ret;
>  }
> 
>  static void __exit nv_c2c_pmu_exit(void)
> --
> 2.47.3

Reviewed-by: Besar Wicaksono <bwicaksono@nvidia.com>



^ permalink raw reply

* RE: [PATCH 1/4] perf: nvidia_t410_cmem_latency: fix cpuhp state leak on init failure
From: Besar Wicaksono @ 2026-05-14 15:55 UTC (permalink / raw)
  To: Saurav Sachidanand, Will Deacon
  Cc: Mark Rutland, Ilkka Koskinen, Andi Shyti,
	linux-arm-kernel@lists.infradead.org,
	linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org,
	aghayev@amazon.com, juew@amazon.com
In-Reply-To: <20260514010629.76558-1-sauravsc@amazon.com>



> -----Original Message-----
> From: Saurav Sachidanand <sauravsc@amazon.com>
> Sent: Wednesday, May 13, 2026 8:06 PM
> To: Will Deacon <will@kernel.org>
> Cc: Mark Rutland <mark.rutland@arm.com>; Besar Wicaksono
> <bwicaksono@nvidia.com>; Ilkka Koskinen
> <ilkka@os.amperecomputing.com>; Andi Shyti <andi.shyti@kernel.org>; linux-
> arm-kernel@lists.infradead.org; linux-perf-users@vger.kernel.org; linux-
> kernel@vger.kernel.org; aghayev@amazon.com; juew@amazon.com; Saurav
> Sachidanand <sauravsc@amazon.com>
> Subject: [PATCH 1/4] perf: nvidia_t410_cmem_latency: fix cpuhp state leak on
> init failure
> 
> External email: Use caution opening links or attachments
> 
> 
> If platform_driver_register() fails, the cpuhp multi-state registered
> by cpuhp_setup_state_multi() is never cleaned up. Add
> cpuhp_remove_multi_state() on the error path, mirroring the cleanup
> in cmem_lat_pmu_exit().
> 
> Fixes: 429b7638b2df ("perf: add NVIDIA Tegra410 CPU Memory Latency
> PMU")
> Signed-off-by: Saurav Sachidanand <sauravsc@amazon.com>
> ---
>  drivers/perf/nvidia_t410_cmem_latency_pmu.c | 6 +++++-
>  1 file changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/perf/nvidia_t410_cmem_latency_pmu.c
> b/drivers/perf/nvidia_t410_cmem_latency_pmu.c
> index acb8f5571522c..e27bf31b2b366 100644
> --- a/drivers/perf/nvidia_t410_cmem_latency_pmu.c
> +++ b/drivers/perf/nvidia_t410_cmem_latency_pmu.c
> @@ -719,7 +719,11 @@ static int __init cmem_lat_pmu_init(void)
> 
>         cmem_lat_pmu_cpuhp_state = ret;
> 
> -       return platform_driver_register(&cmem_lat_pmu_driver);
> +       ret = platform_driver_register(&cmem_lat_pmu_driver);
> +       if (ret)
> +               cpuhp_remove_multi_state(cmem_lat_pmu_cpuhp_state);
> +
> +       return ret;
>  }
> 
>  static void __exit cmem_lat_pmu_exit(void)
> --
> 2.47.3

Reviewed-by: Besar Wicaksono <bwicaksono@nvidia.com>





^ permalink raw reply

* [PATCH v2 03/17] clocksource/drivers/arm_arch_timer: Default to EL2 virtual timer when running VHE
From: Marc Zyngier @ 2026-05-14 15:09 UTC (permalink / raw)
  To: linux-arm-kernel, linux-acpi, linux-kernel, devicetree
  Cc: Lorenzo Pieralisi, Hanjun Guo, Sudeep Holla, Catalin Marinas,
	Will Deacon, Rafael J. Wysocki, Mark Rutland, Daniel Lezcano,
	Thomas Gleixner, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Chen-Yu Tsai, Jernej Skrabec, Samuel Holland, Neil Armstrong,
	Kevin Hilman, Jerome Brunet, Martin Blumenstingl, Ge Gordon,
	BST Linux Kernel Upstream Group, Jesper Nilsson, Lars Persson,
	Alim Akhtar, Ivaylo Ivanov, Frank Li, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, Dinh Nguyen,
	Matthias Brugger, AngeloGioacchino Del Regno, Thierry Reding,
	Jonathan Hunter, Bjorn Andersson, Konrad Dybcio,
	Andreas Färber, Heiko Stuebner, Shawn Lin, Orson Zhai,
	Baolin Wang, Michal Simek
In-Reply-To: <20260514150945.3917510-1-maz@kernel.org>

When running with at EL2 with VHE enabled, the architecture provides
two EL2 timer/counters, dubbed physical and virtual. Apart from their
names, they are strictly identical.

However, they don't get virtualised the same way, specially when
it comes to adding arbitrary offsets to the timers. When running as
a guest, the host CNTVOFF_EL2 does apply to the guest's view of
CNTHV*_El2. This is not true for CNTPOFF_EL2 and CNTHP*_EL2, as
the architecture is broken past the first level of virtualisation
(it lacks some essential mechanisms to be usable, despite what
the ARM ARM pretends).

This means that when running as a L2 guest hypervisor, using the
physical timer results in traps to L0, which are then forwarded to
L1 in order to emulate the offset, leading to even worse performance
due to massive trap amplification (the combination of register and
ERET trapping is absolutely lethal).

Switch the arch timer code to using the virtual timer when running
in VHE by default, only using the physical timer if the interrupt
is not correctly described in the firmware tables (which seems
to be an unfortunately common case). This comes as no impact on
bare-metal, and slightly improves the situation in the virtualised
case.

Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 drivers/clocksource/arm_arch_timer.c | 47 ++++++++++++++++------------
 1 file changed, 27 insertions(+), 20 deletions(-)

diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index 90aeff44a2764..e3eb527650ec7 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -688,6 +688,7 @@ static void __arch_timer_setup(struct clock_event_device *clk)
 	clk->irq = arch_timer_ppi[arch_timer_uses_ppi];
 	switch (arch_timer_uses_ppi) {
 	case ARCH_TIMER_VIRT_PPI:
+	case ARCH_TIMER_HYP_VIRT_PPI:
 		clk->set_state_shutdown = arch_timer_shutdown_virt;
 		clk->set_state_oneshot_stopped = arch_timer_shutdown_virt;
 		sne = erratum_handler(set_next_event_virt);
@@ -879,7 +880,7 @@ static void __init arch_timer_banner(void)
 	pr_info("cp15 timer running at %lu.%02luMHz (%s).\n",
 		(unsigned long)arch_timer_rate / 1000000,
 		(unsigned long)(arch_timer_rate / 10000) % 100,
-		(arch_timer_uses_ppi == ARCH_TIMER_VIRT_PPI) ? "virt" : "phys");
+		arch_timer_ppi_names[arch_timer_uses_ppi]);
 }
 
 u32 arch_timer_get_rate(void)
@@ -912,7 +913,8 @@ static void __init arch_counter_register(void)
 	int width;
 
 	if ((IS_ENABLED(CONFIG_ARM64) && !is_hyp_mode_available()) ||
-	    arch_timer_uses_ppi == ARCH_TIMER_VIRT_PPI) {
+	    arch_timer_uses_ppi == ARCH_TIMER_VIRT_PPI ||
+	    arch_timer_uses_ppi == ARCH_TIMER_HYP_VIRT_PPI) {
 		if (arch_timer_counter_has_wa()) {
 			rd = arch_counter_get_cntvct_stable;
 			scr = raw_counter_get_cntvct_stable;
@@ -1023,6 +1025,7 @@ static int __init arch_timer_register(void)
 	ppi = arch_timer_ppi[arch_timer_uses_ppi];
 	switch (arch_timer_uses_ppi) {
 	case ARCH_TIMER_VIRT_PPI:
+	case ARCH_TIMER_HYP_VIRT_PPI:
 		err = request_percpu_irq(ppi, arch_timer_handler_virt,
 					 "arch_timer", arch_timer_evt);
 		break;
@@ -1090,25 +1093,34 @@ static int __init arch_timer_common_init(void)
 /**
  * arch_timer_select_ppi() - Select suitable PPI for the current system.
  *
- * If HYP mode is available, we know that the physical timer
- * has been configured to be accessible from PL1. Use it, so
- * that a guest can use the virtual timer instead.
+ * On AArch32, if HYP mode is available, we know that the physical
+ * timer has been configured to be accessible from PL1. Use it, so
+ * that a guest can use the virtual timer instead (though KVM host
+ * support has long been removed).
  *
- * On ARMv8.1 with VH extensions, the kernel runs in HYP. VHE
- * accesses to CNTP_*_EL1 registers are silently redirected to
- * their CNTHP_*_EL2 counterparts, and use a different PPI
- * number.
+ * On ARMv8.1 with FEAT_VHE, the kernel runs in EL2. Accesses to
+ * CNTV_*_EL1 registers are silently redirected to their CNTHV_*_EL2
+ * counterparts, and the timer uses a different PPI number. Similar
+ * thing happen when using the EL2 physical timer. Note that a bunch
+ * of DTs out there omit the virtual EL2 timer, so fallback gracefully
+ * on the physical timer.
+ *
+ * Without VHE, if no interrupt provided for virtual timer, we'll have
+ * to stick to the physical timer. It'd better be accessible...
  *
- * If no interrupt provided for virtual timer, we'll have to
- * stick to the physical timer. It'd better be accessible...
  * For arm64 we never use the secure interrupt.
  *
  * Return: a suitable PPI type for the current system.
  */
 static enum arch_timer_ppi_nr __init arch_timer_select_ppi(void)
 {
-	if (is_kernel_in_hyp_mode())
+	if (is_kernel_in_hyp_mode()) {
+		if (arch_timer_ppi[ARCH_TIMER_HYP_VIRT_PPI])
+			return ARCH_TIMER_HYP_VIRT_PPI;
+
+		pr_warn_once(FW_BUG "VHE-capable CPU without EL2 virtual timer interrupt\n");
 		return ARCH_TIMER_HYP_PPI;
+	}
 
 	if (!is_hyp_mode_available() && arch_timer_ppi[ARCH_TIMER_VIRT_PPI])
 		return ARCH_TIMER_VIRT_PPI;
@@ -1200,14 +1212,9 @@ static int __init arch_timer_acpi_init(struct acpi_table_header *table)
 	if (ret)
 		return ret;
 
-	arch_timer_ppi[ARCH_TIMER_PHYS_NONSECURE_PPI] =
-		acpi_gtdt_map_ppi(ARCH_TIMER_PHYS_NONSECURE_PPI);
-
-	arch_timer_ppi[ARCH_TIMER_VIRT_PPI] =
-		acpi_gtdt_map_ppi(ARCH_TIMER_VIRT_PPI);
-
-	arch_timer_ppi[ARCH_TIMER_HYP_PPI] =
-		acpi_gtdt_map_ppi(ARCH_TIMER_HYP_PPI);
+	/* The GTDT parser can't be bothered with the secure timer */
+	for (int i = ARCH_TIMER_PHYS_NONSECURE_PPI; i < ARCH_TIMER_MAX_TIMER_PPI; i++)
+		arch_timer_ppi[i] = acpi_gtdt_map_ppi(i);
 
 	arch_timer_populate_kvm_info();
 
-- 
2.47.3



^ permalink raw reply related

* Re: [PATCH v2 04/16] dt-bindings: mfd: mediatek: mt6397: add mt6323 PMIC thermal
From: Rob Herring (Arm) @ 2026-05-14 15:48 UTC (permalink / raw)
  To: Roman Vivchar
  Cc: AngeloGioacchino Del Regno, Srinivas Kandagatla, Conor Dooley,
	linux-arm-kernel, Andy Shevchenko, linux-iio, devicetree,
	linux-mediatek, Daniel Lezcano, Lukasz Luba, Nuno Sá,
	Zhang Rui, Lee Jones, linux-kernel, Jonathan Cameron, Macpaul Lin,
	Matthias Brugger, Ben Grisdale, Rafael J. Wysocki, David Lechner,
	Sen Chu, Sean Wang, linux-pm, Krzysztof Kozlowski
In-Reply-To: <20260512-mt6323-v2-4-3efcba579e88@protonmail.com>


On Tue, 12 May 2026 08:18:18 +0300, Roman Vivchar wrote:
> The MediaTek mt6323 PMIC temperature can be read using AUXADC channel.
> 
> Add the devicetree binding documentation for the MediaTek mt6323 thermal.
> 
> While mt6323 exposes only a single thermal sensor, newer PMICs like
> mt6358 provide more than one sensor. Therefore define #thermal-sensor-cells
> as 1 to avoid breaking devicetree ABI in the future.
> 
> Signed-off-by: Roman Vivchar <rva333@protonmail.com>
> ---
>  .../devicetree/bindings/mfd/mediatek,mt6397.yaml   | 44 ++++++++++++++++++++++
>  1 file changed, 44 insertions(+)
> 

Reviewed-by: Rob Herring (Arm) <robh@kernel.org>



^ permalink raw reply

* Re: [PATCH v2 0/5] scmi: Log client subsystem entity counts
From: Jonathan Cameron @ 2026-05-14 15:44 UTC (permalink / raw)
  To: Alex Tran
  Cc: Jyoti Bhayana, David Lechner, Nuno Sá, Andy Shevchenko,
	Sudeep Holla, Cristian Marussi, Linus Walleij, Rafael J. Wysocki,
	Philipp Zabel, Viresh Kumar, Guenter Roeck, linux-iio,
	linux-kernel, arm-scmi, linux-arm-kernel, linux-gpio, linux-pm,
	linux-hwmon
In-Reply-To: <20260513-scmi-client-probe-log-v2-0-36607e9dd540@oss.qualcomm.com>

On Wed, 13 May 2026 10:16:53 -0700
Alex Tran <alex.tran@oss.qualcomm.com> wrote:

> SCMI client drivers do not consistently log the number of supported
> entities discovered from firmware. This information is useful during
> debugging because it shows which domains or resources were exposed by
> firmware during probe.
> 
> Add logging of the number of supported entities to the SCMI cpufreq,
> pinctrl, reset, hwmon, and powercap client drivers after a successful
> probe. This aligns these drivers with the existing logging in the SCMI
> power and performance domain drivers.
> 
> Signed-off-by: Alex Tran <alex.tran@oss.qualcomm.com>
Hi Alex,

Just curious but why +CC linux-iio and IIO folk?

May be you had a false suggestion to add them from get maintainers.
If so be sure to check it's suggestions make sense!

Not to worry - we can all hit the delete button ;)

Jonathan


> ---
> Changes in v2:
> - Use dev_dbg instead of dev_info log level
> - Link to v1: https://lore.kernel.org/r/20260513-scmi-client-probe-log-v1-0-00b47b1be009@oss.qualcomm.com
> 
> ---
> Alex Tran (5):
>       powercap: arm_scmi_powercap: Log number of powercap domains
>       cpufreq: scmi-cpufreq: Log number of perf domains
>       hwmon: scmi-hwmon: Log number of sensors
>       reset: reset-scmi: Log number of reset domains
>       pinctrl: pinctrl-scmi: Log number of pins, groups, functions
> 
>  drivers/cpufreq/scmi-cpufreq.c       |  5 ++++-
>  drivers/hwmon/scmi-hwmon.c           |  1 +
>  drivers/pinctrl/pinctrl-scmi.c       | 11 ++++++++++-
>  drivers/powercap/arm_scmi_powercap.c |  1 +
>  drivers/reset/reset-scmi.c           |  8 +++++++-
>  5 files changed, 23 insertions(+), 3 deletions(-)
> ---
> base-commit: 1bfaee9d3351b9b32a99766bbfb1f5baed60ddef
> change-id: 20260509-scmi-client-probe-log-173cf85d5563
> 
> Best regards,



^ permalink raw reply

* [PATCH v2 07/17] arm64: dts: bst: Add EL2 virtual timer interrupt
From: Marc Zyngier @ 2026-05-14 15:09 UTC (permalink / raw)
  To: linux-arm-kernel, linux-acpi, linux-kernel, devicetree
  Cc: Lorenzo Pieralisi, Hanjun Guo, Sudeep Holla, Catalin Marinas,
	Will Deacon, Rafael J. Wysocki, Mark Rutland, Daniel Lezcano,
	Thomas Gleixner, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Chen-Yu Tsai, Jernej Skrabec, Samuel Holland, Neil Armstrong,
	Kevin Hilman, Jerome Brunet, Martin Blumenstingl, Ge Gordon,
	BST Linux Kernel Upstream Group, Jesper Nilsson, Lars Persson,
	Alim Akhtar, Ivaylo Ivanov, Frank Li, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, Dinh Nguyen,
	Matthias Brugger, AngeloGioacchino Del Regno, Thierry Reding,
	Jonathan Hunter, Bjorn Andersson, Konrad Dybcio,
	Andreas Färber, Heiko Stuebner, Shawn Lin, Orson Zhai,
	Baolin Wang, Michal Simek
In-Reply-To: <20260514150945.3917510-1-maz@kernel.org>

The ARMv8.2 based CPUs used in the bst c1200 SoC are missing the EL2
virtual timer interrupt. Add it.

Signed-off-by: Marc Zyngier <maz@kernel.org>
---
 arch/arm64/boot/dts/bst/bstc1200.dtsi | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/bst/bstc1200.dtsi b/arch/arm64/boot/dts/bst/bstc1200.dtsi
index dd13c6bfc3c89..104ecf76ced10 100644
--- a/arch/arm64/boot/dts/bst/bstc1200.dtsi
+++ b/arch/arm64/boot/dts/bst/bstc1200.dtsi
@@ -92,6 +92,7 @@ timer {
 		interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
 			     <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
 			     <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
-			     <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
+			     <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_PPI 12 IRQ_TYPE_LEVEL_LOW>;
 	};
 };
-- 
2.47.3



^ permalink raw reply related

* Re: [PATCH 06/10] clk: amlogic: PLL reset signal supports active-low configuration
From: Jerome Brunet @ 2026-05-14 15:16 UTC (permalink / raw)
  To: Jian Hu via B4 Relay
  Cc: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Neil Armstrong, Xianwei Zhao, Kevin Hilman,
	Martin Blumenstingl, jian.hu, linux-kernel, linux-clk, devicetree,
	linux-amlogic, linux-arm-kernel
In-Reply-To: <20260511-b4-a9_clk-v1-6-41cb4071b7c9@amlogic.com>

On lun. 11 mai 2026 at 20:47, Jian Hu via B4 Relay <devnull+jian.hu.amlogic.com@kernel.org> wrote:

> From: Jian Hu <jian.hu@amlogic.com>
>
> In the A9 design, the PLL reset signal is configured as active-low.
>
> Add the flag 'CLK_MESON_PLL_RST_N' to indicate that the PLL reset signal
> is active-low.
>
> Signed-off-by: Jian Hu <jian.hu@amlogic.com>
> ---
>  drivers/clk/meson/clk-pll.c | 42 +++++++++++++++++++++++++++++++-----------
>  drivers/clk/meson/clk-pll.h |  2 ++
>  2 files changed, 33 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/clk/meson/clk-pll.c b/drivers/clk/meson/clk-pll.c
> index 5a0bd75f85a9..8568ad6ba7b6 100644
> --- a/drivers/clk/meson/clk-pll.c
> +++ b/drivers/clk/meson/clk-pll.c
> @@ -295,10 +295,14 @@ static int meson_clk_pll_is_enabled(struct clk_hw *hw)
>  {
>  	struct clk_regmap *clk = to_clk_regmap(hw);
>  	struct meson_clk_pll_data *pll = meson_clk_pll_data(clk);
> +	unsigned int rst;
>  
> -	if (MESON_PARM_APPLICABLE(&pll->rst) &&
> -	    meson_parm_read(clk->map, &pll->rst))
> -		return 0;
> +	if (MESON_PARM_APPLICABLE(&pll->rst)) {
> +		rst = meson_parm_read(clk->map, &pll->rst);
> +		if ((rst && !(pll->flags & CLK_MESON_PLL_RST_ACTIVE_LOW)) ||
> +		    (!rst && (pll->flags & CLK_MESON_PLL_RST_ACTIVE_LOW)))

Again not a great usage of binary ops. What you've written above is the
verbose version of a XOR.

The code duplication remarks applies to the rest of the patch too

> +			return 0;
> +	}
>  
>  	if (!meson_parm_read(clk->map, &pll->en) ||
>  	    !meson_parm_read(clk->map, &pll->l))
> @@ -326,14 +330,22 @@ static int meson_clk_pll_init(struct clk_hw *hw)
>  		return 0;
>  
>  	if (pll->init_count) {
> -		if (MESON_PARM_APPLICABLE(&pll->rst))
> -			meson_parm_write(clk->map, &pll->rst, 1);
> +		if (MESON_PARM_APPLICABLE(&pll->rst)) {
> +			if (pll->flags & CLK_MESON_PLL_RST_ACTIVE_LOW)
> +				meson_parm_write(clk->map, &pll->rst, 0);
> +			else
> +				meson_parm_write(clk->map, &pll->rst, 1);
> +		}
>  
>  		regmap_multi_reg_write(clk->map, pll->init_regs,
>  				       pll->init_count);
>  
> -		if (MESON_PARM_APPLICABLE(&pll->rst))
> -			meson_parm_write(clk->map, &pll->rst, 0);
> +		if (MESON_PARM_APPLICABLE(&pll->rst)) {
> +			if (pll->flags & CLK_MESON_PLL_RST_ACTIVE_LOW)
> +				meson_parm_write(clk->map, &pll->rst, 1);
> +			else
> +				meson_parm_write(clk->map, &pll->rst, 0);
> +		}
>  	}
>  
>  	return 0;
> @@ -363,15 +375,23 @@ static int meson_clk_pll_enable(struct clk_hw *hw)
>  		return 0;
>  
>  	/* Make sure the pll is in reset */
> -	if (MESON_PARM_APPLICABLE(&pll->rst))
> -		meson_parm_write(clk->map, &pll->rst, 1);
> +	if (MESON_PARM_APPLICABLE(&pll->rst)) {
> +		if (pll->flags & CLK_MESON_PLL_RST_ACTIVE_LOW)
> +			meson_parm_write(clk->map, &pll->rst, 0);
> +		else
> +			meson_parm_write(clk->map, &pll->rst, 1);
> +	}
>  
>  	/* Enable the pll */
>  	meson_parm_write(clk->map, &pll->en, 1);
>  
>  	/* Take the pll out reset */
> -	if (MESON_PARM_APPLICABLE(&pll->rst))
> -		meson_parm_write(clk->map, &pll->rst, 0);
> +	if (MESON_PARM_APPLICABLE(&pll->rst)) {
> +		if (pll->flags & CLK_MESON_PLL_RST_ACTIVE_LOW)
> +			meson_parm_write(clk->map, &pll->rst, 1);
> +		else
> +			meson_parm_write(clk->map, &pll->rst, 0);
> +	}
>  
>  	/*
>  	 * Compared with the previous SoCs, self-adaption current module
> diff --git a/drivers/clk/meson/clk-pll.h b/drivers/clk/meson/clk-pll.h
> index 97b7c70376a3..1be7e6e77631 100644
> --- a/drivers/clk/meson/clk-pll.h
> +++ b/drivers/clk/meson/clk-pll.h
> @@ -31,6 +31,8 @@ struct pll_mult_range {
>  #define CLK_MESON_PLL_NOINIT_ENABLED	BIT(1)
>  /* l_detect signal is active-high */
>  #define CLK_MESON_PLL_L_DETECT_ACTIVE_HIGH	BIT(2)
> +/* rst signal is active-low (Power-on reset) */
> +#define CLK_MESON_PLL_RST_ACTIVE_LOW	BIT(3)
>  
>  struct meson_clk_pll_data {
>  	struct parm en;

-- 
Jerome


^ permalink raw reply

* Re: [PATCH 05/10] clk: amlogic: PLL l_detect signal supports active-high configuration
From: Jerome Brunet @ 2026-05-14 15:13 UTC (permalink / raw)
  To: Jian Hu via B4 Relay
  Cc: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Neil Armstrong, Xianwei Zhao, Kevin Hilman,
	Martin Blumenstingl, jian.hu, linux-kernel, linux-clk, devicetree,
	linux-amlogic, linux-arm-kernel
In-Reply-To: <20260511-b4-a9_clk-v1-5-41cb4071b7c9@amlogic.com>

On lun. 11 mai 2026 at 20:47, Jian Hu via B4 Relay <devnull+jian.hu.amlogic.com@kernel.org> wrote:

> From: Jian Hu <jian.hu@amlogic.com>
>
> l_detect controls the enable/disable of the PLL lock-detect module.
>
> For A9, the l_detect signal is active-high:
> 0 -> Disable lock-detect module;
> 1 -> Enable lock-detect module.
>
> Here, a flag CLK_MESON_PLL_L_DETECT_ACTIVE_HIGH is added to handle cases
> like A9, where the signal is active-high.
>
> Signed-off-by: Jian Hu <jian.hu@amlogic.com>
> ---
>  drivers/clk/meson/clk-pll.c | 9 +++++++--
>  drivers/clk/meson/clk-pll.h | 2 ++
>  2 files changed, 9 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/clk/meson/clk-pll.c b/drivers/clk/meson/clk-pll.c
> index 1ea6579a760f..5a0bd75f85a9 100644
> --- a/drivers/clk/meson/clk-pll.c
> +++ b/drivers/clk/meson/clk-pll.c
> @@ -388,8 +388,13 @@ static int meson_clk_pll_enable(struct clk_hw *hw)
>  	}
>  
>  	if (MESON_PARM_APPLICABLE(&pll->l_detect)) {
> -		meson_parm_write(clk->map, &pll->l_detect, 1);
> -		meson_parm_write(clk->map, &pll->l_detect, 0);
> +		if (pll->flags & CLK_MESON_PLL_L_DETECT_ACTIVE_HIGH) {
> +			meson_parm_write(clk->map, &pll->l_detect, 0);
> +			meson_parm_write(clk->map, &pll->l_detect, 1);
> +		} else {
> +			meson_parm_write(clk->map, &pll->l_detect, 1);
> +			meson_parm_write(clk->map, &pll->l_detect, 0);
> +		}

I'm not a fan of this code duplication.
Use the introduced CLK_MESON_PLL_L_DETECT_ACTIVE_HIGH to compute the
first value, then flip the bit.

>  	}
>  
>  	if (meson_clk_pll_wait_lock(hw))
> diff --git a/drivers/clk/meson/clk-pll.h b/drivers/clk/meson/clk-pll.h
> index 949157fb7bf5..97b7c70376a3 100644
> --- a/drivers/clk/meson/clk-pll.h
> +++ b/drivers/clk/meson/clk-pll.h
> @@ -29,6 +29,8 @@ struct pll_mult_range {
>  
>  #define CLK_MESON_PLL_ROUND_CLOSEST	BIT(0)
>  #define CLK_MESON_PLL_NOINIT_ENABLED	BIT(1)
> +/* l_detect signal is active-high */
> +#define CLK_MESON_PLL_L_DETECT_ACTIVE_HIGH	BIT(2)
>  
>  struct meson_clk_pll_data {
>  	struct parm en;

-- 
Jerome


^ permalink raw reply

* [PATCH 1/4] firmware: psci: switch SYSTEM_OFF to sys-off handler API
From: Diogo Ivo @ 2026-05-14 14:47 UTC (permalink / raw)
  To: Mark Rutland, Lorenzo Pieralisi, Lee Jones, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Thierry Reding,
	Jonathan Hunter
  Cc: linux-arm-kernel, linux-kernel, devicetree, linux-tegra,
	Diogo Ivo
In-Reply-To: <20260514-smaug-poweroff-v1-0-30f9a4688966@tecnico.ulisboa.pt>

Replace the legacy pm_power_off hook with the generic sys-off
handler infrastructure.

Convert psci_sys_poweroff() to the sys-off callback prototype and
register it through register_sys_off_handler() with firmware
priority. This removes the direct dependency on pm_power_off and
drops the now-unused <linux/pm.h> include.

This aligns the PSCI poweroff path with the modern system-off
framework used by other firmware and platform drivers.

Signed-off-by: Diogo Ivo <diogo.ivo@tecnico.ulisboa.pt>
---
 drivers/firmware/psci/psci.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/firmware/psci/psci.c b/drivers/firmware/psci/psci.c
index 38ca190d4a22..d6e9721d11e5 100644
--- a/drivers/firmware/psci/psci.c
+++ b/drivers/firmware/psci/psci.c
@@ -13,7 +13,6 @@
 #include <linux/errno.h>
 #include <linux/linkage.h>
 #include <linux/of.h>
-#include <linux/pm.h>
 #include <linux/printk.h>
 #include <linux/psci.h>
 #include <linux/reboot.h>
@@ -329,9 +328,11 @@ static struct notifier_block psci_sys_reset_nb = {
 	.priority = 129,
 };
 
-static void psci_sys_poweroff(void)
+static int psci_sys_poweroff(struct sys_off_data *data)
 {
 	invoke_psci_fn(PSCI_0_2_FN_SYSTEM_OFF, 0, 0, 0);
+
+	return NOTIFY_DONE;
 }
 
 #ifdef CONFIG_HIBERNATION
@@ -671,7 +672,8 @@ static void __init psci_0_2_set_functions(void)
 
 	register_restart_handler(&psci_sys_reset_nb);
 
-	pm_power_off = psci_sys_poweroff;
+	register_sys_off_handler(SYS_OFF_MODE_POWER_OFF, SYS_OFF_PRIO_FIRMWARE,
+				 psci_sys_poweroff, NULL);
 }
 
 /*

-- 
2.54.0



^ permalink raw reply related


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