Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2] arm64: panic from init_IRQ if IRQ handler stacks cannot be allocated
From: Osama Abdelkader @ 2026-03-26 22:57 UTC (permalink / raw)
  To: Catalin Marinas, Will Deacon, Ard Biesheuvel, Ryo Takakura,
	Breno Leitao, Mark Rutland, Osama Abdelkader, linux-arm-kernel,
	linux-kernel

init_irq_stacks() and init_irq_scs() may fail when arch_alloc_vmap_stack
or scs_alloc return NULL. Return -ENOMEM from both and call panic() once
from init_IRQ(), covering per-CPU IRQ stacks and shadow IRQ stacks
consistently.

Signed-off-by: Osama Abdelkader <osama.abdelkader@gmail.com>
---
v2:
- Add return -ENOMEM from both init_irq_stacks() and init_irq_scs()
- Call panic() once from init_IRQ() if either init_irq_stacks() or
  init_irq_scs() returns -ENOMEM
---
 arch/arm64/kernel/irq.c | 29 ++++++++++++++++++++---------
 1 file changed, 20 insertions(+), 9 deletions(-)

diff --git a/arch/arm64/kernel/irq.c b/arch/arm64/kernel/irq.c
index 15dedb385b9e..9fafd826002b 100644
--- a/arch/arm64/kernel/irq.c
+++ b/arch/arm64/kernel/irq.c
@@ -10,6 +10,7 @@
  * Copyright (C) 2012 ARM Ltd.
  */
 
+#include <linux/errno.h>
 #include <linux/hardirq.h>
 #include <linux/init.h>
 #include <linux/irq.h>
@@ -32,34 +33,43 @@ DEFINE_PER_CPU(struct nmi_ctx, nmi_contexts);
 
 DEFINE_PER_CPU(unsigned long *, irq_stack_ptr);
 
-
 DECLARE_PER_CPU(unsigned long *, irq_shadow_call_stack_ptr);
 
 #ifdef CONFIG_SHADOW_CALL_STACK
 DEFINE_PER_CPU(unsigned long *, irq_shadow_call_stack_ptr);
 #endif
 
-static void init_irq_scs(void)
+static int __init init_irq_scs(void)
 {
 	int cpu;
+	void *s;
 
 	if (!scs_is_enabled())
-		return;
+		return 0;
+
+	for_each_possible_cpu(cpu) {
+		s = scs_alloc(early_cpu_to_node(cpu));
+		if (!s)
+			return -ENOMEM;
+		per_cpu(irq_shadow_call_stack_ptr, cpu) = s;
+	}
 
-	for_each_possible_cpu(cpu)
-		per_cpu(irq_shadow_call_stack_ptr, cpu) =
-			scs_alloc(early_cpu_to_node(cpu));
+	return 0;
 }
 
-static void __init init_irq_stacks(void)
+static int __init init_irq_stacks(void)
 {
 	int cpu;
 	unsigned long *p;
 
 	for_each_possible_cpu(cpu) {
 		p = arch_alloc_vmap_stack(IRQ_STACK_SIZE, early_cpu_to_node(cpu));
+		if (!p)
+			return -ENOMEM;
 		per_cpu(irq_stack_ptr, cpu) = p;
 	}
+
+	return 0;
 }
 
 #ifdef CONFIG_SOFTIRQ_ON_OWN_STACK
@@ -109,8 +119,9 @@ int __init set_handle_fiq(void (*handle_fiq)(struct pt_regs *))
 
 void __init init_IRQ(void)
 {
-	init_irq_stacks();
-	init_irq_scs();
+	if (init_irq_stacks() || init_irq_scs())
+		panic("Failed to allocate IRQ stack resources\n");
+
 	irqchip_init();
 
 	if (system_uses_irq_prio_masking()) {
-- 
2.43.0



^ permalink raw reply related

* Re: [PATCH] arm64: panic if IRQ shadow call stack allocation fails
From: Osama Abdelkader @ 2026-03-26 23:02 UTC (permalink / raw)
  To: Breno Leitao
  Cc: Catalin Marinas, Will Deacon, Mark Rutland, Ard Biesheuvel,
	Ryo Takakura, linux-arm-kernel, linux-kernel
In-Reply-To: <acOhjkLqf2gsM-Sf@gmail.com>

On Wed, Mar 25, 2026 at 01:54:32AM -0700, Breno Leitao wrote:
> On Tue, Mar 24, 2026 at 05:15:41PM +0100, Osama Abdelkader wrote:
> > scs_alloc() can return NULL when vmalloc fails. init_irq_scs() previously
> > stored that NULL in per-cpu irq_shadow_call_stack_ptr, which IRQ entry
> > would then use under CONFIG_SHADOW_CALL_STACK. Match other SCS setup paths
> > (e.g. SDEI) by failing explicitly instead of continuing with a NULL
> > pointer.
> 
> Right,  _init_sdei_scs() doesn't not assign the per cpu pointer with
> NULL, but, at the same time it doesn't panic. SDEI propagates -ENOMEM
> back up the call chain and even frees already allocated stacks via
> free_sdei_scs(). Should it panic as well?
>

Thanks, I changed it to return -ENOMEM in v2 to address will's review.
 
> > Mark init_irq_scs() __init since it is only called from init_IRQ().
> > 
> > Signed-off-by: Osama Abdelkader <osama.abdelkader@gmail.com>
> > ---
> >  arch/arm64/kernel/irq.c | 14 +++++++++-----
> >  1 file changed, 9 insertions(+), 5 deletions(-)
> > 
> > diff --git a/arch/arm64/kernel/irq.c b/arch/arm64/kernel/irq.c
> > index 15dedb385b9e..b32ed7ef8e00 100644
> > --- a/arch/arm64/kernel/irq.c
> > +++ b/arch/arm64/kernel/irq.c
> > @@ -14,6 +14,7 @@
> >  #include <linux/init.h>
> >  #include <linux/irq.h>
> >  #include <linux/irqchip.h>
> > +#include <linux/kernel.h>
> 
> Why do you need kernel.h in here? I initially thought it was
> for panic(), but, later I found panic() is already in use in this file.
> 
> Isn't kernel.h being included transitively?

Right, I removed it in v2, thanks.

> >  #include <linux/kprobes.h>
> >  #include <linux/memory.h>
> >  #include <linux/scs.h>
> > @@ -32,23 +33,26 @@ DEFINE_PER_CPU(struct nmi_ctx, nmi_contexts);
> >  
> >  DEFINE_PER_CPU(unsigned long *, irq_stack_ptr);
> >  
> > -
> >  DECLARE_PER_CPU(unsigned long *, irq_shadow_call_stack_ptr);
> >  
> >  #ifdef CONFIG_SHADOW_CALL_STACK
> >  DEFINE_PER_CPU(unsigned long *, irq_shadow_call_stack_ptr);
> >  #endif
> >  
> > -static void init_irq_scs(void)
> > +static void __init init_irq_scs(void)
> >  {
> >  	int cpu;
> > +	void *s;
> >  
> >  	if (!scs_is_enabled())
> >  		return;
> >  
> > -	for_each_possible_cpu(cpu)
> > -		per_cpu(irq_shadow_call_stack_ptr, cpu) =
> > -			scs_alloc(early_cpu_to_node(cpu));
> > +	for_each_possible_cpu(cpu) {
> > +		s = scs_alloc(early_cpu_to_node(cpu));
> > +		if (!s)
> > +			panic("irq: Failed to allocate shadow call stack\n");
> > +		per_cpu(irq_shadow_call_stack_ptr, cpu) = s;
> > +	}
> >  }
> 
> Reading RISC-V code, it seems it has the same problem. Is it worth fixing also?
> 
>  static void init_irq_scs(void)
>   {
>           int cpu;
> 
>           if (!scs_is_enabled())
>                   return;
> 
>           for_each_possible_cpu(cpu)
>                   per_cpu(irq_shadow_call_stack_ptr, cpu) =
>                           scs_alloc(cpu_to_node(cpu));
>   }

Yes, thanks for the check.

> 
> Other than these nits, feel free to add:
> 
> Reviewed-by: Breno Leitao <leitao@debian.org>

Thank you. I sent v2:
[PATCH v2] arm64: panic from init_IRQ if IRQ handler stacks cannot be
 allocated

To cover init_irq_stacks as well.

Best regards,
Osama


^ permalink raw reply

* Re: [PATCH] arm64: panic if IRQ shadow call stack allocation fails
From: Osama Abdelkader @ 2026-03-26 23:03 UTC (permalink / raw)
  To: Will Deacon
  Cc: Catalin Marinas, Mark Rutland, Ard Biesheuvel, Breno Leitao,
	Ryo Takakura, linux-arm-kernel, linux-kernel
In-Reply-To: <acQO16dmw0v6pzu8@willie-the-truck>

On Wed, Mar 25, 2026 at 04:35:35PM +0000, Will Deacon wrote:
> On Tue, Mar 24, 2026 at 05:15:41PM +0100, Osama Abdelkader wrote:
> > diff --git a/arch/arm64/kernel/irq.c b/arch/arm64/kernel/irq.c
> > index 15dedb385b9e..b32ed7ef8e00 100644
> > --- a/arch/arm64/kernel/irq.c
> > +++ b/arch/arm64/kernel/irq.c
> > @@ -14,6 +14,7 @@
> >  #include <linux/init.h>
> >  #include <linux/irq.h>
> >  #include <linux/irqchip.h>
> > +#include <linux/kernel.h>
> >  #include <linux/kprobes.h>
> >  #include <linux/memory.h>
> >  #include <linux/scs.h>
> > @@ -32,23 +33,26 @@ DEFINE_PER_CPU(struct nmi_ctx, nmi_contexts);
> >  
> >  DEFINE_PER_CPU(unsigned long *, irq_stack_ptr);
> >  
> > -
> >  DECLARE_PER_CPU(unsigned long *, irq_shadow_call_stack_ptr);
> >  
> >  #ifdef CONFIG_SHADOW_CALL_STACK
> >  DEFINE_PER_CPU(unsigned long *, irq_shadow_call_stack_ptr);
> >  #endif
> >  
> > -static void init_irq_scs(void)
> > +static void __init init_irq_scs(void)
> >  {
> >  	int cpu;
> > +	void *s;
> >  
> >  	if (!scs_is_enabled())
> >  		return;
> >  
> > -	for_each_possible_cpu(cpu)
> > -		per_cpu(irq_shadow_call_stack_ptr, cpu) =
> > -			scs_alloc(early_cpu_to_node(cpu));
> > +	for_each_possible_cpu(cpu) {
> > +		s = scs_alloc(early_cpu_to_node(cpu));
> > +		if (!s)
> > +			panic("irq: Failed to allocate shadow call stack\n");
> > +		per_cpu(irq_shadow_call_stack_ptr, cpu) = s;
> > +	}
> 
> I don't especially see the point in these panic() messages given that
> presumably all sorts of other things will go wrong if we fail simple
> allocations this early during boot.
> 
> If you really want to check this, then we should at least do the same
> for the IRQ stack itself, otherwise it's all a bit academic. So maybe
> have init_irq_scs() and init_irq_stacks() return -ENOMEM so that
> init_IRQ() can panic?
> 
> Will

Thanks for the review, I just did that in v2:
[PATCH v2] arm64: panic from init_IRQ if IRQ handler stacks cannot be
 allocated

Best regards,
Osama


^ permalink raw reply

* [PATCH v4 1/2] media: dt-bindings: rockchip,rk3568-mipi-csi2: add rk3588 compatible
From: Michael Riesch via B4 Relay @ 2026-03-26 23:10 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Sakari Ailus, Laurent Pinchart, Frank Li,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Heiko Stuebner,
	Kever Yang, Collabora Kernel Team
  Cc: linux-media, devicetree, linux-arm-kernel, linux-rockchip,
	linux-kernel, Michael Riesch
In-Reply-To: <20260305-rk3588-csi2rx-v4-0-81c6bcfefa63@collabora.com>

From: Michael Riesch <michael.riesch@collabora.com>

The RK3588 MIPI CSI-2 receivers are compatible to the ones found in
the RK3568.
Introduce a list of compatible variants and add the RK3588 variant to
it.

Acked-by: Rob Herring (Arm) <robh@kernel.org>
Signed-off-by: Michael Riesch <michael.riesch@collabora.com>
---
 .../devicetree/bindings/media/rockchip,rk3568-mipi-csi2.yaml  | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/media/rockchip,rk3568-mipi-csi2.yaml b/Documentation/devicetree/bindings/media/rockchip,rk3568-mipi-csi2.yaml
index 4ac4a3b6f406..fbcf28e9e1da 100644
--- a/Documentation/devicetree/bindings/media/rockchip,rk3568-mipi-csi2.yaml
+++ b/Documentation/devicetree/bindings/media/rockchip,rk3568-mipi-csi2.yaml
@@ -16,9 +16,14 @@ description:
 
 properties:
   compatible:
-    enum:
-      - fsl,imx93-mipi-csi2
-      - rockchip,rk3568-mipi-csi2
+    oneOf:
+      - enum:
+          - fsl,imx93-mipi-csi2
+          - rockchip,rk3568-mipi-csi2
+      - items:
+          - enum:
+              - rockchip,rk3588-mipi-csi2
+          - const: rockchip,rk3568-mipi-csi2
 
   reg:
     maxItems: 1

-- 
2.39.5




^ permalink raw reply related

* [PATCH v4 2/2] arm64: dts: rockchip: add mipi csi-2 receiver nodes to rk3588
From: Michael Riesch via B4 Relay @ 2026-03-26 23:10 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Sakari Ailus, Laurent Pinchart, Frank Li,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Heiko Stuebner,
	Kever Yang, Collabora Kernel Team
  Cc: linux-media, devicetree, linux-arm-kernel, linux-rockchip,
	linux-kernel, Michael Riesch
In-Reply-To: <20260305-rk3588-csi2rx-v4-0-81c6bcfefa63@collabora.com>

From: Michael Riesch <michael.riesch@collabora.com>

The Rockchip RK3588 features six MIPI CSI-2 receiver units:
 - MIPI0: connected to MIPI DCPHY0 (not supported)
 - MIPI1: connected to MIPI DCPHY1 (not supported)
 - MIPI2: connected to MIPI DPHY0
 - MIPI3: connected to MIPI DPHY0-1 (not supported)
 - MIPI4: connected to MIPI DPHY1
 - MIPI5: connected to MIPI DPHY1-1 (not supported)
As the MIPI DCPHYs as well as the split DPHY mode of the DPHYs
are not yet supported, add only the device tree nodes for the
MIPI2 and MIPI4 units.

Signed-off-by: Michael Riesch <michael.riesch@collabora.com>
---
 arch/arm64/boot/dts/rockchip/rk3588-base.dtsi | 52 +++++++++++++++++++++++++++
 1 file changed, 52 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi
index 7fe9593d8c19..6c593b0255c3 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi
@@ -1430,6 +1430,58 @@ av1d: video-codec@fdc70000 {
 		resets = <&cru SRST_A_AV1>, <&cru SRST_P_AV1>, <&cru SRST_A_AV1_BIU>, <&cru SRST_P_AV1_BIU>;
 	};
 
+	csi2: csi@fdd30000 {
+		compatible = "rockchip,rk3588-mipi-csi2", "rockchip,rk3568-mipi-csi2";
+		reg = <0x0 0xfdd30000 0x0 0x10000>;
+		interrupts = <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH 0>,
+			     <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH 0>;
+		interrupt-names = "err1", "err2";
+		clocks = <&cru PCLK_CSI_HOST_2>;
+		phys = <&csi_dphy0>;
+		power-domains = <&power RK3588_PD_VI>;
+		resets = <&cru SRST_P_CSI_HOST_2>;
+		status = "disabled";
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			csi2_in: port@0 {
+				reg = <0>;
+			};
+
+			csi2_out: port@1 {
+				reg = <1>;
+			};
+		};
+	};
+
+	csi4: csi@fdd50000 {
+		compatible = "rockchip,rk3588-mipi-csi2", "rockchip,rk3568-mipi-csi2";
+		reg = <0x0 0xfdd50000 0x0 0x10000>;
+		interrupts = <GIC_SPI 151 IRQ_TYPE_LEVEL_HIGH 0>,
+			     <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH 0>;
+		interrupt-names = "err1", "err2";
+		clocks = <&cru PCLK_CSI_HOST_4>;
+		phys = <&csi_dphy1>;
+		power-domains = <&power RK3588_PD_VI>;
+		resets = <&cru SRST_P_CSI_HOST_4>;
+		status = "disabled";
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			csi4_in: port@0 {
+				reg = <0>;
+			};
+
+			csi4_out: port@1 {
+				reg = <1>;
+			};
+		};
+	};
+
 	vop: vop@fdd90000 {
 		compatible = "rockchip,rk3588-vop";
 		reg = <0x0 0xfdd90000 0x0 0x4200>, <0x0 0xfdd95000 0x0 0x1000>;

-- 
2.39.5




^ permalink raw reply related

* [PATCH v4 0/2] media: synopsys: csi2rx: add support for rk3588 variant
From: Michael Riesch via B4 Relay @ 2026-03-26 23:09 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Sakari Ailus, Laurent Pinchart, Frank Li,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Heiko Stuebner,
	Kever Yang, Collabora Kernel Team
  Cc: linux-media, devicetree, linux-arm-kernel, linux-rockchip,
	linux-kernel, Michael Riesch

Habidere,

The Rockchip RK3588 features six MIPI CSI-2 receiver units:
 - MIPI0: connected to MIPI DCPHY0
 - MIPI1: connected to MIPI DCPHY1
 - MIPI2: connected to MIPI DPHY0
 - MIPI3: connected to MIPI DPHY0-1 (only with split DPHY0)
 - MIPI4: connected to MIPI DPHY1
 - MIPI5: connected to MIPI DPHY1-1 (only with split DPHY1)

The MIPI DCPHYs (at least the CSI-2 features of them) as well
as the split DPHY mode of the DPHYs are not yet supported by
mainline. However, we can already provide support for the
MIPI2 and MIPI4 units.

When support for the split DPHY mode is introduced, the DPHY
nodes should have the property
    #phy-cells = <1>;
and the MIPI CSI-2 receiver nodes should have the property
    phys = <&csi_dphy{0,1} {0,1}>;
in case the split mode is desired. Since this is a board
specific hardware design, the properties need to be changed
in the board device tree (or any overlays).

As reasonable default, however, we can define, e.g., 
    #phy-cells = <0>;
and
    phys = <&csi_dphy{0,1}>;
in the SoC device tree include.
This series introduces initial support for this default
configuration.

Looking forward to your comments!

Signed-off-by: Michael Riesch <michael.riesch@collabora.com>
---
Changes in v4:
- rebased onto media-commiters/next again (as Frank's patches
  are now there)
- changed "oneOf entries to enum in dt binding (Rob)
- Link to v3: https://lore.kernel.org/r/20260305-rk3588-csi2rx-v3-0-754473981f39@collabora.com

Changes in v3:
- rebased onto Sakari's cleanup branch (as Frank's patches were
  merged) (Sakari)
- added Rob's Acked-by
- Link to v2: https://lore.kernel.org/r/20260305-rk3588-csi2rx-v2-0-79d01b615486@collabora.com

Changes in v2:
- use fallback compatible instead of separate compatible (Krzysztof)
- dropped patch 2 and 4 (as a consequence thereof)
- Link to v1: https://lore.kernel.org/r/20260305-rk3588-csi2rx-v1-0-0cd8d2bf28c0@collabora.com

---
Michael Riesch (2):
      media: dt-bindings: rockchip,rk3568-mipi-csi2: add rk3588 compatible
      arm64: dts: rockchip: add mipi csi-2 receiver nodes to rk3588

 .../bindings/media/rockchip,rk3568-mipi-csi2.yaml  | 11 +++--
 arch/arm64/boot/dts/rockchip/rk3588-base.dtsi      | 52 ++++++++++++++++++++++
 2 files changed, 60 insertions(+), 3 deletions(-)
---
base-commit: 4fbeef21f5387234111b5d52924e77757626faa5
change-id: 20260305-rk3588-csi2rx-a11f7c15a40a

Best regards,
-- 
Michael Riesch <michael.riesch@collabora.com>




^ permalink raw reply

* Re: [PATCH v1 0/2] perf build: Remove libunwind support
From: Ian Rogers @ 2026-03-26 23:14 UTC (permalink / raw)
  To: Namhyung Kim
  Cc: 9erthalion6, acme, adrian.hunter, alex, alexander.shishkin,
	andrew.jones, aou, atrajeev, blakejones, ctshao, dapeng1.mi,
	howardchu95, james.clark, john.g.garry, jolsa, leo.yan,
	libunwind-devel, linux-arm-kernel, linux-kernel, linux-perf-users,
	linux-riscv, mingo, palmer, peterz, pjw, shimin.guo, tglozar,
	tmricht, will, amadio, yuzhuo
In-Reply-To: <acW4Z2KJbyPZM1SG@google.com>

On Thu, Mar 26, 2026 at 3:51 PM Namhyung Kim <namhyung@kernel.org> wrote:
>
> On Sat, Mar 21, 2026 at 04:42:18PM -0700, Ian Rogers wrote:
> > libunwind support exists for "--call-graph dwarf", however, libunwind
> > support has been opt-in rather than opt-out since Linux v6.13 as libdw
> > is preferred - commit 13e17c9ff49119aa ("perf build: Make libunwind
> > opt-in rather than opt-out"). A problem with the libdw support was
> > that it was slow, an issue fixed in Linux v7.0 in commit 6b2658b3f36a
> > ("perf unwind-libdw: Don't discard loaded ELF/DWARF after every
> > unwind"). As such libunwind support is now unnecessary.
> >
> > The patch series:
> > https://lore.kernel.org/lkml/20260305221927.3237145-1-irogers@google.com/
> > looked to make the libunwind support in perf similar to the libdw
> > support, allow cross-architecture unwinding, etc. This was motivated
> > by the perf regs conventions being altered by the addition of x86 APX
> > support:
> > https://lore.kernel.org/lkml/20260209072047.2180332-1-dapeng1.mi@linux.intel.com/
> > It is necessary to translate the library's notion of registers to the
> > perf register convention so that the stack unwinding state can be
> > initialized. On this series it was stated that removing libunwind
> > support from perf should be an option, rather than updating support:
> > https://lore.kernel.org/lkml/abxs-2rozL1tBEO1@google.com/
> > This was also what motivated making libunwind opt-in rather than
> > opt-out.
> >
> > Given that 7 minor releases have happened with libunwind "deprecated"
> > by making it opt-in, let's remove the libunwind support. There doesn't
> > appear to be any disagreement to this on the mailing list.
>
> I'm not sure if we want to remove it now.  I think we need more time to
> verify libdw unwinding is stable and fast enough.  Also maybe we can
> add build- or run-time warning when people try to use libunwind.

I've had issues with old versions of libdw, but presumably the
distributions won't update perf without libdw. Given we're waiting
should we land the cleanup in:
https://lore.kernel.org/lkml/20260305221927.3237145-1-irogers@google.com/
We have test coverage.

Thanks,
Ian

> Thanks,
> Namhyung
>
> >
> > Ian Rogers (2):
> >   perf build: Remove libunwind support
> >   tools build: Remove libunwind feature tests
> >
> >  tools/build/feature/Makefile                  |  31 -
> >  tools/build/feature/test-libunwind-aarch64.c  |  27 -
> >  tools/build/feature/test-libunwind-arm.c      |  28 -
> >  .../test-libunwind-debug-frame-aarch64.c      |  17 -
> >  .../feature/test-libunwind-debug-frame-arm.c  |  17 -
> >  .../feature/test-libunwind-debug-frame.c      |  17 -
> >  tools/build/feature/test-libunwind-x86.c      |  28 -
> >  tools/build/feature/test-libunwind-x86_64.c   |  28 -
> >  tools/build/feature/test-libunwind.c          |  28 -
> >  tools/perf/Documentation/perf-check.txt       |   1 -
> >  tools/perf/Documentation/perf-config.txt      |   4 +-
> >  tools/perf/Documentation/perf-record.txt      |   2 +-
> >  tools/perf/Makefile.config                    | 163 +---
> >  tools/perf/Makefile.perf                      |   3 -
> >  tools/perf/arch/arm/util/Build                |   1 -
> >  tools/perf/arch/arm/util/unwind-libunwind.c   |  50 --
> >  tools/perf/arch/arm64/util/Build              |   1 -
> >  tools/perf/arch/arm64/util/unwind-libunwind.c |  17 -
> >  tools/perf/arch/loongarch/util/Build          |   1 -
> >  .../arch/loongarch/util/unwind-libunwind.c    |  82 --
> >  tools/perf/arch/mips/util/Build               |   1 -
> >  tools/perf/arch/mips/util/unwind-libunwind.c  |  22 -
> >  tools/perf/arch/powerpc/util/Build            |   1 -
> >  .../perf/arch/powerpc/util/unwind-libunwind.c |  92 --
> >  tools/perf/arch/x86/util/Build                |   1 -
> >  tools/perf/arch/x86/util/unwind-libunwind.c   | 115 ---
> >  tools/perf/builtin-check.c                    |   1 -
> >  tools/perf/builtin-report.c                   |   4 +-
> >  tools/perf/tests/make                         |   2 -
> >  tools/perf/util/Build                         |   5 -
> >  tools/perf/util/callchain.c                   |   2 +-
> >  tools/perf/util/dso.h                         |   6 -
> >  tools/perf/util/libunwind/arm64.c             |  40 -
> >  tools/perf/util/libunwind/x86_32.c            |  41 -
> >  tools/perf/util/maps.c                        |  47 +-
> >  tools/perf/util/maps.h                        |   6 -
> >  tools/perf/util/thread.c                      |  40 +-
> >  tools/perf/util/thread.h                      |   1 -
> >  tools/perf/util/unwind-libunwind-local.c      | 832 ------------------
> >  tools/perf/util/unwind-libunwind.c            |  92 --
> >  tools/perf/util/unwind.h                      |  41 +-
> >  41 files changed, 19 insertions(+), 1919 deletions(-)
> >  delete mode 100644 tools/build/feature/test-libunwind-aarch64.c
> >  delete mode 100644 tools/build/feature/test-libunwind-arm.c
> >  delete mode 100644 tools/build/feature/test-libunwind-debug-frame-aarch64.c
> >  delete mode 100644 tools/build/feature/test-libunwind-debug-frame-arm.c
> >  delete mode 100644 tools/build/feature/test-libunwind-debug-frame.c
> >  delete mode 100644 tools/build/feature/test-libunwind-x86.c
> >  delete mode 100644 tools/build/feature/test-libunwind-x86_64.c
> >  delete mode 100644 tools/build/feature/test-libunwind.c
> >  delete mode 100644 tools/perf/arch/arm/util/unwind-libunwind.c
> >  delete mode 100644 tools/perf/arch/arm64/util/unwind-libunwind.c
> >  delete mode 100644 tools/perf/arch/loongarch/util/unwind-libunwind.c
> >  delete mode 100644 tools/perf/arch/mips/util/unwind-libunwind.c
> >  delete mode 100644 tools/perf/arch/powerpc/util/unwind-libunwind.c
> >  delete mode 100644 tools/perf/arch/x86/util/unwind-libunwind.c
> >  delete mode 100644 tools/perf/util/libunwind/arm64.c
> >  delete mode 100644 tools/perf/util/libunwind/x86_32.c
> >  delete mode 100644 tools/perf/util/unwind-libunwind-local.c
> >  delete mode 100644 tools/perf/util/unwind-libunwind.c
> >
> > --
> > 2.53.0.959.g497ff81fa9-goog
> >


^ permalink raw reply

* Re: [PATCH v4 3/7] pinctrl: extract pinctrl_generic_to_map() from pinctrl_generic_pins_function_dt_node_to_map()
From: Conor Dooley @ 2026-03-27  0:06 UTC (permalink / raw)
  To: Frank Li
  Cc: Peter Rosin, Linus Walleij, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Rafał Miłecki, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, linux-kernel, linux-gpio,
	devicetree, imx, linux-arm-kernel, Haibo Chen
In-Reply-To: <acWNOhnBvA5l9NW3@lizhi-Precision-Tower-5810>

[-- Attachment #1: Type: text/plain, Size: 5910 bytes --]

On Thu, Mar 26, 2026 at 03:47:06PM -0400, Frank Li wrote:
> On Thu, Mar 26, 2026 at 06:55:01PM +0000, Conor Dooley wrote:
> > On Thu, Mar 26, 2026 at 06:52:12PM +0000, Conor Dooley wrote:
> > > On Wed, Mar 25, 2026 at 07:04:12PM -0400, Frank Li wrote:
> > >
> > > > diff --git a/drivers/pinctrl/pinctrl-generic.c b/drivers/pinctrl/pinctrl-generic.c
> > > > index efb39c6a670331775855efdc8566102b5c6202ef..20a216ae63e91b69985ea4cfcd0b57103c6ca950 100644
> > > > --- a/drivers/pinctrl/pinctrl-generic.c
> > > > +++ b/drivers/pinctrl/pinctrl-generic.c
> > > > @@ -17,29 +17,18 @@
> > > >  #include "pinctrl-utils.h"
> > > >  #include "pinmux.h"
> > > >
> > > > -static int pinctrl_generic_pins_function_dt_subnode_to_map(struct pinctrl_dev *pctldev,
> > >
> > > > +int
> > > > +pinctrl_generic_to_map(struct pinctrl_dev *pctldev, struct device_node *parent,
> > >
> > > Can you drop this stylistic change please? The
> >
> > Whoops, cut myself off. To be clear, what I am asking for is to keep the
> > "int" etc on the same line as the function name. This function is new,
> > but you did it for the existing function too and the comparison is here.
> >
> > >
> > > > +		       struct device_node *np, struct pinctrl_map **maps,
> > > > +		       unsigned int *num_maps, unsigned int *num_reserved_maps,
> > > > +		       const char **group_names, unsigned int ngroups,
> > > > +		       const char **functions, unsigned int *pins)
> > > >  {
> > > >  	struct device *dev = pctldev->dev;
> > > > -	const char **functions;
> > > > +	int npins, ret, reserve = 1;
> > > > +	unsigned int num_configs;
> > > >  	const char *group_name;
> > > >  	unsigned long *configs;
> > > > -	unsigned int num_configs, pin, *pins;
> > > > -	int npins, ret, reserve = 1;
> > > > -
> > > > -	npins = of_property_count_u32_elems(np, "pins");
> > > > -
> > > > -	if (npins < 1) {
> > > > -		dev_err(dev, "invalid pinctrl group %pOFn.%pOFn %d\n",
> > > > -			parent, np, npins);
> > > > -		return npins;
> > > > -	}
> > > >
> > > >  	group_name = devm_kasprintf(dev, GFP_KERNEL, "%pOFn.%pOFn", parent, np);
> > > >  	if (!group_name)
> > > > @@ -51,22 +40,6 @@ static int pinctrl_generic_pins_function_dt_subnode_to_map(struct pinctrl_dev *p
> > > >  	if (!pins)
> > > >  		return -ENOMEM;
> > >
> > > This looks suspect. You've left the pins allocation behind:
> > > 	pins = devm_kcalloc(dev, npins, sizeof(*pins), GFP_KERNEL);
> > > 	if (!pins)
> > > 		return -ENOMEM;
> > > but pinctrl_generic_pins_function_dt_subnode_to_map() has already
> > > populated this array before calling the function.
> 
> what's means?

It means you broke my driver by not removing this allocation from
pinctrl_generic_to_map().

> 
> pinctrl_generic_pins_function_dt_subnode_to_map()
> {
> 	pins = devm_kcalloc(dev, npins, sizeof(*pins), GFP_KERNEL);
> 	...
> 	pinctrl_generic_to_map();
> }
> 
> pinctrl_generic_pins_function_dt_subnode_to_map() have not use this array.

I have no idea what this statement means.

> 
> Frank
> > >
> > > Also, this should probably be
> > > Suggested-by: Conor Dooley <conor.dooley@microchip.com>
> > >
> > > Cheers,
> > > Conor.
> > >
> > > >
> > > > -	functions = devm_kcalloc(dev, npins, sizeof(*functions), GFP_KERNEL);
> > > > -	if (!functions)
> > > > -		return -ENOMEM;
> > > > -
> > > > -	for (int i = 0; i < npins; i++) {
> > > > -		ret = of_property_read_u32_index(np, "pins", i, &pin);
> > > > -		if (ret)
> > > > -			return ret;
> > > > -
> > > > -		pins[i] = pin;
> > > > -
> > > > -		ret = of_property_read_string(np, "function", &functions[i]);
> > > > -		if (ret)
> > > > -			return ret;
> > > > -	}
> > > > -
> > > >  	ret = pinctrl_utils_reserve_map(pctldev, maps, num_reserved_maps, num_maps, reserve);
> > > >  	if (ret)
> > > >  		return ret;
> > > > @@ -103,6 +76,54 @@ static int pinctrl_generic_pins_function_dt_subnode_to_map(struct pinctrl_dev *p
> > > >  	return 0;
> > > >  };
> > > >
> > > > +static int
> > > > +pinctrl_generic_pins_function_dt_subnode_to_map(struct pinctrl_dev *pctldev,
> > > > +						struct device_node *parent,
> > > > +						struct device_node *np,
> > > > +						struct pinctrl_map **maps,
> > > > +						unsigned int *num_maps,
> > > > +						unsigned int *num_reserved_maps,
> > > > +						const char **group_names,
> > > > +						unsigned int ngroups)
> > > > +{
> > > > +	struct device *dev = pctldev->dev;
> > > > +	unsigned int pin, *pins;
> > > > +	const char **functions;
> > > > +	int npins, ret;
> > > > +
> > > > +	npins = of_property_count_u32_elems(np, "pins");
> > > > +
> > > > +	if (npins < 1) {
> > > > +		dev_err(dev, "invalid pinctrl group %pOFn.%pOFn %d\n",
> > > > +			parent, np, npins);
> > > > +		return npins;
> > > > +	}
> > > > +
> > > > +	pins = devm_kcalloc(dev, npins, sizeof(*pins), GFP_KERNEL);
> > > > +	if (!pins)
> > > > +		return -ENOMEM;
> > > > +
> > > > +	functions = devm_kcalloc(dev, npins, sizeof(*functions), GFP_KERNEL);
> > > > +	if (!functions)
> > > > +		return -ENOMEM;
> > > > +
> > > > +	for (int i = 0; i < npins; i++) {
> > > > +		ret = of_property_read_u32_index(np, "pins", i, &pin);
> > > > +		if (ret)
> > > > +			return ret;
> > > > +
> > > > +		pins[i] = pin;
> > > > +
> > > > +		ret = of_property_read_string(np, "function", &functions[i]);
> > > > +		if (ret)
> > > > +			return ret;
> > > > +	}
> > > > +
> > > > +	return pinctrl_generic_to_map(pctldev, parent, np, maps, num_maps,
> > > > +				      num_reserved_maps, group_names, ngroups,
> > > > +				      functions, pins);
> > > > +}
> > > > +
> > > >  /*
> > > >   * For platforms that do not define groups or functions in the driver, but
> > > >   * instead use the devicetree to describe them. This function will, unlike
> > > >
> > > > --
> > > > 2.43.0
> > > >
> >
> >
> 
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply

* Re: [PATCH v4 3/7] pinctrl: extract pinctrl_generic_to_map() from pinctrl_generic_pins_function_dt_node_to_map()
From: Conor Dooley @ 2026-03-27  0:09 UTC (permalink / raw)
  To: Frank Li
  Cc: Peter Rosin, Linus Walleij, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Rafał Miłecki, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, linux-kernel, linux-gpio,
	devicetree, imx, linux-arm-kernel, Haibo Chen
In-Reply-To: <20260325-pinctrl-mux-v4-3-043c2c82e623@nxp.com>

[-- Attachment #1: Type: text/plain, Size: 6834 bytes --]

On Wed, Mar 25, 2026 at 07:04:12PM -0400, Frank Li wrote:
> Refactor pinctrl_generic_pins_function_dt_subnode_to_map() by separating DT
> parsing logic from map creation. Introduce a new helper
> pinctrl_generic_to_map() to handle mapping to kernel data structures, while
> keeping DT property parsing in the subnode function.
> 
> Improve code structure and enables easier reuse for platforms using
> different DT properties (e.g. pinmux) without modifying the
> dt_node_to_map-style callback API. Avoid unnecessary coupling to
> pinctrl_generic_pins_function_dt_node_to_map(), which provides
> functionality not needed when the phandle target is unambiguous.
> 
> Maximize code reuse and provide a cleaner extension point for future
> pinctrl drivers.
> 
> Signed-off-by: Frank Li <Frank.Li@nxp.com>
> ---
> change in v4
> - new patch
> ---
>  drivers/pinctrl/pinconf.h         | 18 ++++++++
>  drivers/pinctrl/pinctrl-generic.c | 91 ++++++++++++++++++++++++---------------
>  2 files changed, 74 insertions(+), 35 deletions(-)
> 
> diff --git a/drivers/pinctrl/pinconf.h b/drivers/pinctrl/pinconf.h
> index 2880adef476e68950ffdd540ea42cdee6a16ec27..ffdabddb9660324ed8886a2e8dcacff7e1c6c529 100644
> --- a/drivers/pinctrl/pinconf.h
> +++ b/drivers/pinctrl/pinconf.h
> @@ -166,6 +166,13 @@ int pinctrl_generic_pins_function_dt_node_to_map(struct pinctrl_dev *pctldev,
>  						 struct device_node *np,
>  						 struct pinctrl_map **maps,
>  						 unsigned int *num_maps);
> +
> +int
> +pinctrl_generic_to_map(struct pinctrl_dev *pctldev, struct device_node *parent,
> +		       struct device_node *np, struct pinctrl_map **maps,
> +		       unsigned int *num_maps, unsigned int *num_reserved_maps,
> +		       const char **group_name, unsigned int ngroups,
> +		       const char **functions, unsigned int *pins);
>  #else
>  static inline int
>  pinctrl_generic_pins_function_dt_node_to_map(struct pinctrl_dev *pctldev,
> @@ -175,4 +182,15 @@ pinctrl_generic_pins_function_dt_node_to_map(struct pinctrl_dev *pctldev,
>  {
>  	return -ENOTSUPP;
>  }
> +
> +static inline int
> +pinctrl_generic_to_map(struct pinctrl_dev *pctldev, struct device_node *parent,
> +		       struct device_node *np, struct pinctrl_map **maps,
> +		       unsigned int *num_maps, unsigned int *num_reserved_maps,
> +		       const char **group_name, unsigned int ngroups,
> +		       const char **functions, unsigned int *pins,
> +		       void *function_data)
> +{
> +	return -ENOTSUPP;
> +}
>  #endif
> diff --git a/drivers/pinctrl/pinctrl-generic.c b/drivers/pinctrl/pinctrl-generic.c
> index efb39c6a670331775855efdc8566102b5c6202ef..20a216ae63e91b69985ea4cfcd0b57103c6ca950 100644
> --- a/drivers/pinctrl/pinctrl-generic.c
> +++ b/drivers/pinctrl/pinctrl-generic.c
> @@ -17,29 +17,18 @@
>  #include "pinctrl-utils.h"
>  #include "pinmux.h"
>  
> -static int pinctrl_generic_pins_function_dt_subnode_to_map(struct pinctrl_dev *pctldev,
> -							   struct device_node *parent,
> -							   struct device_node *np,
> -							   struct pinctrl_map **maps,
> -							   unsigned int *num_maps,
> -							   unsigned int *num_reserved_maps,
> -							   const char **group_names,
> -							   unsigned int ngroups)
> +int
> +pinctrl_generic_to_map(struct pinctrl_dev *pctldev, struct device_node *parent,
> +		       struct device_node *np, struct pinctrl_map **maps,
> +		       unsigned int *num_maps, unsigned int *num_reserved_maps,
> +		       const char **group_names, unsigned int ngroups,
> +		       const char **functions, unsigned int *pins)

npins needs to be an argument to this function also, otherwise
pinctrl_generic_add_group() uses it uninitialised...

>  {
>  	struct device *dev = pctldev->dev;
> -	const char **functions;
> +	int npins, ret, reserve = 1;

...because you're declaring it here when it's something set by the dt
parsing code in pinctrl_generic_pins_function_dt_subnode_to_map()...

> +	unsigned int num_configs;
>  	const char *group_name;
>  	unsigned long *configs;
> -	unsigned int num_configs, pin, *pins;
> -	int npins, ret, reserve = 1;
> -
> -	npins = of_property_count_u32_elems(np, "pins");
> -
> -	if (npins < 1) {
> -		dev_err(dev, "invalid pinctrl group %pOFn.%pOFn %d\n",
> -			parent, np, npins);
> -		return npins;
> -	}
>  
>  	group_name = devm_kasprintf(dev, GFP_KERNEL, "%pOFn.%pOFn", parent, np);
>  	if (!group_name)
> @@ -51,22 +40,6 @@ static int pinctrl_generic_pins_function_dt_subnode_to_map(struct pinctrl_dev *p
>  	if (!pins)
>  		return -ENOMEM;
>  
> -	functions = devm_kcalloc(dev, npins, sizeof(*functions), GFP_KERNEL);
> -	if (!functions)
> -		return -ENOMEM;
> -
> -	for (int i = 0; i < npins; i++) {
> -		ret = of_property_read_u32_index(np, "pins", i, &pin);
> -		if (ret)
> -			return ret;
> -
> -		pins[i] = pin;
> -
> -		ret = of_property_read_string(np, "function", &functions[i]);
> -		if (ret)
> -			return ret;
> -	}
> -
>  	ret = pinctrl_utils_reserve_map(pctldev, maps, num_reserved_maps, num_maps, reserve);
>  	if (ret)
>  		return ret;
> @@ -103,6 +76,54 @@ static int pinctrl_generic_pins_function_dt_subnode_to_map(struct pinctrl_dev *p
>  	return 0;
>  };
>  
> +static int
> +pinctrl_generic_pins_function_dt_subnode_to_map(struct pinctrl_dev *pctldev,
> +						struct device_node *parent,
> +						struct device_node *np,
> +						struct pinctrl_map **maps,
> +						unsigned int *num_maps,
> +						unsigned int *num_reserved_maps,
> +						const char **group_names,
> +						unsigned int ngroups)
> +{
> +	struct device *dev = pctldev->dev;
> +	unsigned int pin, *pins;
> +	const char **functions;
> +	int npins, ret;
> +
> +	npins = of_property_count_u32_elems(np, "pins");

...down here.

> +
> +	if (npins < 1) {
> +		dev_err(dev, "invalid pinctrl group %pOFn.%pOFn %d\n",
> +			parent, np, npins);
> +		return npins;
> +	}
> +
> +	pins = devm_kcalloc(dev, npins, sizeof(*pins), GFP_KERNEL);
> +	if (!pins)
> +		return -ENOMEM;
> +
> +	functions = devm_kcalloc(dev, npins, sizeof(*functions), GFP_KERNEL);
> +	if (!functions)
> +		return -ENOMEM;
> +
> +	for (int i = 0; i < npins; i++) {
> +		ret = of_property_read_u32_index(np, "pins", i, &pin);
> +		if (ret)
> +			return ret;
> +
> +		pins[i] = pin;
> +
> +		ret = of_property_read_string(np, "function", &functions[i]);
> +		if (ret)
> +			return ret;
> +	}
> +
> +	return pinctrl_generic_to_map(pctldev, parent, np, maps, num_maps,
> +				      num_reserved_maps, group_names, ngroups,
> +				      functions, pins);
> +}
> +
>  /*
>   * For platforms that do not define groups or functions in the driver, but
>   * instead use the devicetree to describe them. This function will, unlike
> 
> -- 
> 2.43.0
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply

* [PATCH v2] soc: fsl: qe: panic on ioremap() failure in qe_reset()
From: Wang Jun @ 2026-03-27  0:12 UTC (permalink / raw)
  To: Qiang Zhao, Christophe Leroy, linuxppc-dev, linux-arm-kernel
  Cc: linux-kernel, gszhai, 25125332, 25125283, 23120469, Wang Jun,
	stable
In-Reply-To: <780c1ba3-6639-478e-896f-e35ec059b58c@kernel.org>

When ioremap() fails in qe_reset(), the global pointer qe_immr remains
NULL, leading to a subsequent NULL pointer dereference when the pointer
is accessed. Since this happens early in the boot process, a failure to
map a few bytes of I/O memory indicates a fatal error from which the
system cannot recover.

Follow the same pattern as qe_sdma_init() and panic immediately when
ioremap() fails. This avoids a silent NULL pointer dereference later
and makes the error explicit.

Fixes: 986585385131 ("[POWERPC] Add QUICC Engine (QE) infrastructure")
Cc: stable@vger.kernel.org
Signed-off-by: Wang Jun <1742789905@qq.com>
---
 drivers/soc/fsl/qe/qe.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/soc/fsl/qe/qe.c b/drivers/soc/fsl/qe/qe.c
index 70b6eddb867b..9f6223043ee3 100644
--- a/drivers/soc/fsl/qe/qe.c
+++ b/drivers/soc/fsl/qe/qe.c
@@ -86,8 +86,12 @@ static phys_addr_t get_qe_base(void)
 
 void qe_reset(void)
 {
-	if (qe_immr == NULL)
+	if (qe_immr == NULL) {
 		qe_immr = ioremap(get_qe_base(), QE_IMMAP_SIZE);
+		if (qe_immr == NULL) {
+			panic("QE:ioremap failed!");
+		}
+	}
 
 	qe_snums_init();
 
-- 
2.43.0



^ permalink raw reply related

* [PATCH v3 0/2] Rockchip DRM use-after-free & null-ptr-deref fixes
From: Cristian Ciocaltea @ 2026-03-27  0:55 UTC (permalink / raw)
  To: Sandy Huang, Heiko Stübner, Andy Yan, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
	Dmitry Baryshkov, Dmitry Baryshkov, Andrzej Hajda, Neil Armstrong,
	Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec
  Cc: kernel, dri-devel, linux-arm-kernel, linux-rockchip, linux-kernel

The first three patches in the series are fixes for use-after-free &
null-ptr-deref related issues found in dw_dp and inno-hdmi Rockchip DRM
drivers.

The following three patches provide a few minor improvements to dw_dp
and dw_hdmi_qp, while the remaining two address use-after-free and
memory allocation in DW DP core library.

Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
---
Changes in v3:
- Dropped patches 1..6,8 already applied by Heiko
- Reworked remaining patch "drm/bridge: synopsys: dw-dp: Unregister AUX
  channel on bridge detach" into:
  * drm/bridge: synopsys: dw-dp: Support unregistering the AUX channel
  * drm/rockchip: dw_dp: Release core resources
- Link to v2: https://lore.kernel.org/r/20260310-drm-rk-fixes-v2-0-645ecfb43f49@collabora.com

Changes in v2:
- Fixed conflicts while rebasing onto latest drm-misc-next
- Added two more patches:
  * drm/bridge: synopsys: dw-dp: Unregister AUX channel on bridge detach
  * drm/bridge: synopsys: dw-dp: Drop useless memory allocation
- Link to v1: https://lore.kernel.org/r/20260122-drm-rk-fixes-v1-0-3942f185750e@collabora.com

---
Cristian Ciocaltea (2):
      drm/bridge: synopsys: dw-dp: Support unregistering the AUX channel
      drm/rockchip: dw_dp: Release core resources

 drivers/gpu/drm/bridge/synopsys/dw-dp.c   |  6 ++++++
 drivers/gpu/drm/rockchip/dw_dp-rockchip.c | 20 +++++++++++++++++---
 include/drm/bridge/dw_dp.h                |  1 +
 3 files changed, 24 insertions(+), 3 deletions(-)
---
base-commit: 46c31e1604d121221167cb09380de8c7d53290b9
change-id: 20260122-drm-rk-fixes-a7622c71553e



^ permalink raw reply

* [PATCH v3 2/2] drm/rockchip: dw_dp: Release core resources
From: Cristian Ciocaltea @ 2026-03-27  0:55 UTC (permalink / raw)
  To: Sandy Huang, Heiko Stübner, Andy Yan, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
	Dmitry Baryshkov, Dmitry Baryshkov, Andrzej Hajda, Neil Armstrong,
	Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec
  Cc: kernel, dri-devel, linux-arm-kernel, linux-rockchip, linux-kernel
In-Reply-To: <20260327-drm-rk-fixes-v3-0-fd2e6900c08c@collabora.com>

Core resources such as the DisplayPort AUX channel get initialized and
registered during dw_dp_bind(), but are never unregistered, which may
lead to memory leaks and/or use-after-free:

[  224.661371] BUG: KASAN: slab-use-after-free in device_is_dependent+0xe0/0x2b0
[  224.662015] Read of size 8 at addr ffff00011aee8550 by task modprobe/658
[  224.662612]
[  224.662752] CPU: 7 UID: 0 PID: 658 Comm: modprobe Not tainted 7.0.0-rc2-next-20260305 #14 PREEMPT
[  224.662759] Hardware name: Radxa ROCK 5B (DT)
[  224.662762] Call trace:
[  224.662764]  show_stack+0x20/0x38 (C)
[  224.662772]  dump_stack_lvl+0x6c/0x98
[  224.662777]  print_report+0x160/0x4b8
[  224.662783]  kasan_report+0xb4/0xe0
[  224.662790]  __asan_report_load8_noabort+0x20/0x30
[  224.662796]  device_is_dependent+0xe0/0x2b0
[  224.662802]  device_is_dependent+0x108/0x2b0
[  224.662808]  device_link_add+0x1f8/0x10b0
[  224.662813]  devm_of_phy_get_by_index+0x120/0x200
[  224.662819]  dw_dp_bind+0x34c/0xb10 [dw_dp]
[  224.662830]  dw_dp_rockchip_bind+0x194/0x250 [rockchipdrm]
[  224.662864]  component_bind_all+0x3a8/0x720
[  224.662869]  rockchip_drm_bind+0x120/0x390 [rockchipdrm]
[  224.662899]  try_to_bring_up_aggregate_device+0x76c/0x838
[  224.662904]  component_master_add_with_match+0x1f4/0x230
[  224.662909]  rockchip_drm_platform_probe+0x420/0x538 [rockchipdrm]
[  224.662939]  platform_probe+0xe8/0x168
[  224.662945]  really_probe+0x340/0x828
[  224.662950]  __driver_probe_device+0x2e0/0x350
[  224.662954]  driver_probe_device+0x80/0x140
[  224.662959]  __driver_attach+0x398/0x460
[  224.662964]  bus_for_each_dev+0xe0/0x198
[  224.662968]  driver_attach+0x50/0x68
[  224.662972]  bus_add_driver+0x2a0/0x4c0
[  224.662977]  driver_register+0x294/0x360
[  224.662982]  __platform_driver_register+0x7c/0x98
[  224.662987]  rockchip_drm_init+0xc4/0xff8 [rockchipdrm]

Since a previous commit exported dw_dp_unbind() function in DW DP core
library to take care of the necessary cleanup, use this in the
component's unbind() callback, as well as in its bind() error path.

Fixes: d68ba7bac955 ("drm/rockchip: Add RK3588 DPTX output support")
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
---
 drivers/gpu/drm/rockchip/dw_dp-rockchip.c | 20 +++++++++++++++++---
 1 file changed, 17 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/dw_dp-rockchip.c b/drivers/gpu/drm/rockchip/dw_dp-rockchip.c
index 22c0911f1896..8cba90d2dd56 100644
--- a/drivers/gpu/drm/rockchip/dw_dp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_dp-rockchip.c
@@ -108,14 +108,28 @@ static int dw_dp_rockchip_bind(struct device *dev, struct device *master, void *
 
 	connector = drm_bridge_connector_init(drm_dev, encoder);
 	if (IS_ERR(connector))
-		return dev_err_probe(dev, PTR_ERR(connector),
-				     "Failed to init bridge connector");
+		ret = dev_err_probe(dev, PTR_ERR(connector),
+				    "Failed to init bridge connector");
+	else
+		ret = drm_connector_attach_encoder(connector, encoder);
 
-	return drm_connector_attach_encoder(connector, encoder);
+	if (ret)
+		dw_dp_unbind(dp->base);
+
+	return ret;
+}
+
+static void dw_dp_rockchip_unbind(struct device *dev, struct device *master,
+				  void *data)
+{
+	struct rockchip_dw_dp *dp = dev_get_drvdata(dev);
+
+	dw_dp_unbind(dp->base);
 }
 
 static const struct component_ops dw_dp_rockchip_component_ops = {
 	.bind = dw_dp_rockchip_bind,
+	.unbind = dw_dp_rockchip_unbind,
 };
 
 static int dw_dp_probe(struct platform_device *pdev)

-- 
2.52.0



^ permalink raw reply related

* [PATCH v3 1/2] drm/bridge: synopsys: dw-dp: Support unregistering the AUX channel
From: Cristian Ciocaltea @ 2026-03-27  0:55 UTC (permalink / raw)
  To: Sandy Huang, Heiko Stübner, Andy Yan, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
	Dmitry Baryshkov, Dmitry Baryshkov, Andrzej Hajda, Neil Armstrong,
	Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec
  Cc: kernel, dri-devel, linux-arm-kernel, linux-rockchip, linux-kernel
In-Reply-To: <20260327-drm-rk-fixes-v3-0-fd2e6900c08c@collabora.com>

The DisplayPort AUX channel gets initialized and registered during
dw_dp_bind(), but it is never unregistered, which may lead to resource
leaks and/or use-after-free.

Add the missing dw_dp_unbind() function to allow the users of the
library to handle the required cleanup, i.e. unregister the AUX adapter.

Fixes: 86eecc3a9c2e ("drm/bridge: synopsys: Add DW DPTX Controller support library")
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
---
 drivers/gpu/drm/bridge/synopsys/dw-dp.c | 6 ++++++
 include/drm/bridge/dw_dp.h              | 1 +
 2 files changed, 7 insertions(+)

diff --git a/drivers/gpu/drm/bridge/synopsys/dw-dp.c b/drivers/gpu/drm/bridge/synopsys/dw-dp.c
index 3f4530c117c7..6211ba6ba7bd 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-dp.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-dp.c
@@ -2093,6 +2093,12 @@ struct dw_dp *dw_dp_bind(struct device *dev, struct drm_encoder *encoder,
 }
 EXPORT_SYMBOL_GPL(dw_dp_bind);
 
+void dw_dp_unbind(struct dw_dp *dp)
+{
+	drm_dp_aux_unregister(&dp->aux);
+}
+EXPORT_SYMBOL_GPL(dw_dp_unbind);
+
 MODULE_AUTHOR("Andy Yan <andyshrk@163.com>");
 MODULE_DESCRIPTION("DW DP Core Library");
 MODULE_LICENSE("GPL");
diff --git a/include/drm/bridge/dw_dp.h b/include/drm/bridge/dw_dp.h
index 25363541e69d..22105c3e8e4d 100644
--- a/include/drm/bridge/dw_dp.h
+++ b/include/drm/bridge/dw_dp.h
@@ -24,4 +24,5 @@ struct dw_dp_plat_data {
 
 struct dw_dp *dw_dp_bind(struct device *dev, struct drm_encoder *encoder,
 			 const struct dw_dp_plat_data *plat_data);
+void dw_dp_unbind(struct dw_dp *dp);
 #endif /* __DW_DP__ */

-- 
2.52.0



^ permalink raw reply related

* Re: [PATCH v2 7/8] drm/bridge: synopsys: dw-dp: Unregister AUX channel on bridge detach
From: Cristian Ciocaltea @ 2026-03-27  1:08 UTC (permalink / raw)
  To: Heiko Stuebner, Sandy Huang, Andy Yan, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
	Dmitry Baryshkov, Dmitry Baryshkov, Andrzej Hajda, Neil Armstrong,
	Robert Foss, Laurent Pinchart, Jonas Karlman, Jernej Skrabec
  Cc: kernel, dri-devel, linux-arm-kernel, linux-rockchip, linux-kernel
In-Reply-To: <2053748.usQuhbGJ8B@phil>

Hello Heiko,

On 3/26/26 9:28 PM, Heiko Stuebner wrote:
> Am Montag, 9. März 2026, 23:44:35 Mitteleuropäische Normalzeit schrieb Cristian Ciocaltea:
>> The DisplayPort AUX channel gets initialized and registered during
>> dw_dp_bind(), but it is never unregistered, which may lead to resource
>> leaks and/or use-after-free:
>>
>> [  224.661371] BUG: KASAN: slab-use-after-free in device_is_dependent+0xe0/0x2b0
>> [  224.662015] Read of size 8 at addr ffff00011aee8550 by task modprobe/658
>> ...
>> [  224.662796]  device_is_dependent+0xe0/0x2b0
>> [  224.662802]  device_is_dependent+0x108/0x2b0
>> [  224.662808]  device_link_add+0x1f8/0x10b0
>> [  224.662813]  devm_of_phy_get_by_index+0x120/0x200
>> [  224.662819]  dw_dp_bind+0x34c/0xb10 [dw_dp]
>> [  224.662830]  dw_dp_rockchip_bind+0x194/0x250 [rockchipdrm]
>> [  224.662864]  component_bind_all+0x3a8/0x720
>> [  224.662869]  rockchip_drm_bind+0x120/0x390 [rockchipdrm]
>> [  224.662899]  try_to_bring_up_aggregate_device+0x76c/0x838
>> [  224.662904]  component_master_add_with_match+0x1f4/0x230
>> [  224.662909]  rockchip_drm_platform_probe+0x420/0x538 [rockchipdrm]
>> [  224.662939]  platform_probe+0xe8/0x168
>> [  224.662945]  really_probe+0x340/0x828
>> [  224.662950]  __driver_probe_device+0x2e0/0x350
>> [  224.662954]  driver_probe_device+0x80/0x140
>> [  224.662959]  __driver_attach+0x398/0x460
>> [  224.662964]  bus_for_each_dev+0xe0/0x198
>> [  224.662968]  driver_attach+0x50/0x68
>> [  224.662972]  bus_add_driver+0x2a0/0x4c0
>> [  224.662977]  driver_register+0x294/0x360
>> [  224.662982]  __platform_driver_register+0x7c/0x98
>> [  224.662987]  rockchip_drm_init+0xc4/0xff8 [rockchipdrm]
>> ...
>>
>> Unregister the AUX adapter on bridge detach.
> 
> that sounds sort of asymmetrical though. drm_bridge_funcs has attach and
> detach callbacks and the component-framework also has bind and unbind
> callbacks.
> 
> This might cause confusion later on I guess, especially as I don't know
> if there could be a bridge attach, after the detach that unregisters the
> aux adapter.
> 
> Looking at the AnalogixDP for example, it does the the register and
> unregister in the bind/unbind callbacks of the core driver.
> 
> So I guess the in my eyes cleaner way would be to introduce a
> dw_dp_unbind() function and put the aux unregister there?
> 
> At least that way, everything would be at the same "level".

You are right.  As a matter of fact exporting the *_unbind() in the library was
my first thought, but for some reason I went with the "auto" approach.

I've just handled this in v3 [1].

Thanks for reviewing and picking the rest of the patches!

Regards,
Cristian

[1] https://lore.kernel.org/all/20260327-drm-rk-fixes-v3-0-fd2e6900c08c@collabora.com/



^ permalink raw reply

* Re: [PATCH net-next v15 0/3] Add support for Nuvoton MA35D1 GMAC
From: patchwork-bot+netdevbpf @ 2026-03-27  1:20 UTC (permalink / raw)
  To: Joey Lu
  Cc: andrew+netdev, davem, edumazet, kuba, pabeni, robh, krzk+dt,
	conor+dt, mcoquelin.stm32, richardcochran, alexandre.torgue,
	joabreu, ychuang3, schung, yclu4, peppe.cavallaro,
	linux-arm-kernel, netdev, devicetree, linux-kernel, openbmc,
	linux-stm32
In-Reply-To: <20260323101756.81849-1-a0987203069@gmail.com>

Hello:

This series was applied to netdev/net-next.git (main)
by Jakub Kicinski <kuba@kernel.org>:

On Mon, 23 Mar 2026 18:17:53 +0800 you wrote:
> This patch series is submitted to add GMAC support for Nuvoton MA35D1
> SoC platform. This work involves implementing a GMAC driver glue layer
> based on Synopsys DWMAC driver framework to leverage MA35D1's dual GMAC
> interface capabilities.
> 
> Overview:
>   1. Added a GMAC driver glue layer for MA35D1 SoC, providing support for
>   the platform's two GMAC interfaces.
>   2. Added device tree settings, with specific configurations for our
>   development boards:
>     a. SOM board: Configured for two RGMII interfaces.
>     b. IoT board: Configured with one RGMII and one RMII interface.
>   3. Added dt-bindings for the GMAC interfaces.
> 
> [...]

Here is the summary with links:
  - [net-next,v15,1/3] dt-bindings: net: nuvoton: Add schema for Nuvoton MA35 family GMAC
    https://git.kernel.org/netdev/net-next/c/8454478ef9ab
  - [net-next,v15,2/3] arm64: dts: nuvoton: Add Ethernet nodes
    (no matching commit)
  - [net-next,v15,3/3] net: stmmac: dwmac-nuvoton: Add dwmac glue for Nuvoton MA35 family
    https://git.kernel.org/netdev/net-next/c/4d7c557f58ef

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




^ permalink raw reply

* Re: [PATCH 1/2] arm64/entry: Fix involuntary preemption exception masking
From: Jinjie Ruan @ 2026-03-27  1:27 UTC (permalink / raw)
  To: Mark Rutland, Thomas Gleixner
  Cc: vladimir.murzin, peterz, catalin.marinas, linux-kernel, luto,
	will, linux-arm-kernel
In-Reply-To: <acV2552t5X4OlNYi@J2N7QTR9R3>



On 2026/3/27 2:11, Mark Rutland wrote:
> On Wed, Mar 25, 2026 at 04:46:01PM +0100, Thomas Gleixner wrote:
>> On Wed, Mar 25 2026 at 11:03, Mark Rutland wrote:
>>> On Sun, Mar 22, 2026 at 12:25:06AM +0100, Thomas Gleixner wrote:
>>> I *think* what would work for us is we could split some of the exit
>>> handling (including involuntary preemption) into a "prepare" step, as we
>>> have for return to userspace. That way, arm64 could handle exiting
>>> something like:
>>>
>>> 	local_irq_disable();
>>> 	irqentry_exit_prepare(); // new, all generic logic
>>> 	local_daif_mask();
>>> 	arm64_exit_to_kernel_mode() {
>>> 		...
>>> 		irqentry_exit(); // ideally irqentry_exit_to_kernel_mode().
>>> 		...
>>> 	}
>>>
>>> ... and other architectures can use a combined exit_to_kernel_mode() (or
>>> whatever we call that), which does both, e.g.
>>>
>>> 	// either noinstr, __always_inline, or a macro
>>> 	void irqentry_prepare_and_exit(void)
>>
>> That's a bad idea as that would require to do a full kernel rename of
>> all existing irqentry_exit() users.
>>
>>> 	{
>>> 		irqentry_exit_prepare();
>>> 		irqentry_exit();
>>> 	}
>>
>> Aside of the naming that should work.
> 
> Thanks for confirming!
> 
> I've pushed a (very early, WIP) draft to
> 
>   https://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git/log/?h=arm64/entry/rework

The patch also looks good to me. Looking forward to seeing this move
forward.

> 
> ... which is missing commit messages, comments, etc, but seems to work.
> 
> I'll see about getting that tested, cleaned up, and on-list.
> 
> Mark.
> 


^ permalink raw reply

* Re: [PATCH net-next 0/5] net: stmmac: dwmac-socfpga: Cleanup .fix_mac_speed
From: patchwork-bot+netdevbpf @ 2026-03-27  1:32 UTC (permalink / raw)
  To: Maxime Chevallier
  Cc: andrew, kuba, davem, edumazet, pabeni, horms, mcoquelin.stm32,
	alexandre.torgue, linux, thomas.petazzoni, alexis.lothore,
	rohan.g.thomas, mun.yew.tham, netdev, linux-kernel,
	linux-arm-kernel, linux-stm32
In-Reply-To: <20260324092102.687082-1-maxime.chevallier@bootlin.com>

Hello:

This series was applied to netdev/net-next.git (main)
by Jakub Kicinski <kuba@kernel.org>:

On Tue, 24 Mar 2026 10:20:55 +0100 you wrote:
> Hi everyone,
> 
> This small series does a bit of cleanup in the dwmad-socfpga glue
> driver, especially around the .fix_mac_speed() operation.
> 
> It's mostly about re-using existing helpers from the glue driver, as
> well as reorganizing the code to make the local private structures a
> little bit smaller.
> 
> [...]

Here is the summary with links:
  - [net-next,1/5] net: stmmac: dwmac-socfpga: Move internal helpers
    https://git.kernel.org/netdev/net-next/c/845a04411118
  - [net-next,2/5] net: stmmac: dwmac-socfpga: Use the socfpga_sgmii_config() helper
    https://git.kernel.org/netdev/net-next/c/a7be7cc12442
  - [net-next,3/5] net: stmmac: dwmac-socfpga: Use the correct type for interface modes
    https://git.kernel.org/netdev/net-next/c/9b04ecdfb876
  - [net-next,4/5] net: stmmac: dwmac-socfpga: get the phy_mode with the dedicated helper
    https://git.kernel.org/netdev/net-next/c/adf1536f79a5
  - [net-next,5/5] net: stmmac: dwmac-sofcpga: Drop the struct device reference
    https://git.kernel.org/netdev/net-next/c/9bd1af853750

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




^ permalink raw reply

* Re: [PATCH net-next v2 4/4] net: phy: Introduce Airoha AN8801/R Gigabit Ethernet PHY driver
From: Jakub Kicinski @ 2026-03-27  1:43 UTC (permalink / raw)
  To: Louis-Alexis Eyraud
  Cc: Andrew Lunn, Andrew Lunn, David S. Miller, Eric Dumazet,
	Paolo Abeni, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	AngeloGioacchino Del Regno, Heiner Kallweit, Russell King,
	kevin-kw.huang, macpaul.lin, matthias.bgg, kernel, netdev,
	devicetree, linux-arm-kernel, linux-mediatek, linux-kernel
In-Reply-To: <3688a285-7f98-4afa-80ad-697094cd7b97@lunn.ch>

On Thu, 26 Mar 2026 13:47:43 +0100 Andrew Lunn wrote:
> > +	if (phydev->link && prev_speed != phydev->speed) {
> > +		val = phydev->speed == SPEED_1000 ?
> > +		      AN8801_BPBUS_LINK_MODE_1000 : 0;
> > +
> > +		return an8801_buckpbus_reg_rmw(phydev,
> > +					       AN8801_BPBUS_REG_LINK_MODE,
> > +					       AN8801_BPBUS_LINK_MODE_1000,
> > +					       val);
> > +	};  
> 
> This is unusual. What is it doing? Please add a comment.

Also - nit spurious ; after if () {}


^ permalink raw reply

* [PATCH 6.1.y 2/3] net: phy: allow MDIO bus PM ops to start/stop state machine for phylink-controlled PHY
From: Rajani Kantha @ 2026-03-27  1:52 UTC (permalink / raw)
  To: gregkh, stable, vladimir.oltean
  Cc: patches, linux-kernel, andrew, hkallweit1, linux, davem, edumazet,
	kuba, pabeni, matthias.bgg, f.fainelli, netdev, linux-arm-kernel,
	linux-mediatek, wei.fang

From: Vladimir Oltean <vladimir.oltean@nxp.com>

[ Upstream commit fc75ea20ffb452652f0d4033f38fe88d7cfdae35 ]

DSA has 2 kinds of drivers:

1. Those who call dsa_switch_suspend() and dsa_switch_resume() from
   their device PM ops: qca8k-8xxx, bcm_sf2, microchip ksz
2. Those who don't: all others. The above methods should be optional.

For type 1, dsa_switch_suspend() calls dsa_user_suspend() -> phylink_stop(),
and dsa_switch_resume() calls dsa_user_resume() -> phylink_start().
These seem good candidates for setting mac_managed_pm = true because
that is essentially its definition [1], but that does not seem to be the
biggest problem for now, and is not what this change focuses on.

Talking strictly about the 2nd category of DSA drivers here (which
do not have MAC managed PM, meaning that for their attached PHYs,
mdio_bus_phy_suspend() and mdio_bus_phy_resume() should run in full),
I have noticed that the following warning from mdio_bus_phy_resume() is
triggered:

	WARN_ON(phydev->state != PHY_HALTED && phydev->state != PHY_READY &&
		phydev->state != PHY_UP);

because the PHY state machine is running.

It's running as a result of a previous dsa_user_open() -> ... ->
phylink_start() -> phy_start() having been initiated by the user.

The previous mdio_bus_phy_suspend() was supposed to have called
phy_stop_machine(), but it didn't. So this is why the PHY is in state
PHY_NOLINK by the time mdio_bus_phy_resume() runs.

mdio_bus_phy_suspend() did not call phy_stop_machine() because for
phylink, the phydev->adjust_link function pointer is NULL. This seems a
technicality introduced by commit fddd91016d16 ("phylib: fix PAL state
machine restart on resume"). That commit was written before phylink
existed, and was intended to avoid crashing with consumer drivers which
don't use the PHY state machine - phylink always does, when using a PHY.
But phylink itself has historically not been developed with
suspend/resume in mind, and apparently not tested too much in that
scenario, allowing this bug to exist unnoticed for so long. Plus, prior
to the WARN_ON(), it would have likely been invisible.

This issue is not in fact restricted to type 2 DSA drivers (according to
the above ad-hoc classification), but can be extrapolated to any MAC
driver with phylink and MDIO-bus-managed PHY PM ops. DSA is just where
the issue was reported. Assuming mac_managed_pm is set correctly, a
quick search indicates the following other drivers might be affected:

$ grep -Zlr PHYLINK_NETDEV drivers/ | xargs -0 grep -L mac_managed_pm
drivers/net/ethernet/atheros/ag71xx.c
drivers/net/ethernet/microchip/sparx5/sparx5_main.c
drivers/net/ethernet/microchip/lan966x/lan966x_main.c
drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c
drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c
drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
drivers/net/ethernet/freescale/ucc_geth.c
drivers/net/ethernet/freescale/enetc/enetc_pf_common.c
drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
drivers/net/ethernet/marvell/mvneta.c
drivers/net/ethernet/marvell/prestera/prestera_main.c
drivers/net/ethernet/mediatek/mtk_eth_soc.c
drivers/net/ethernet/altera/altera_tse_main.c
drivers/net/ethernet/wangxun/txgbe/txgbe_phy.c
drivers/net/ethernet/meta/fbnic/fbnic_phylink.c
drivers/net/ethernet/tehuti/tn40_phy.c
drivers/net/ethernet/mscc/ocelot_net.c

Make the existing conditions dependent on the PHY device having a
phydev->phy_link_change() implementation equal to the default
phy_link_change() provided by phylib. Otherwise, we implicitly know that
the phydev has the phylink-provided phylink_phy_change() callback, and
when phylink is used, the PHY state machine always needs to be stopped/
started on the suspend/resume path. The code is structured as such that
if phydev->phy_link_change() is absent, it is a matter of time until the
kernel will crash - no need to further complicate the test.

Thus, for the situation where the PM is not managed by the MAC, we will
make the MDIO bus PM ops treat identically the phylink-controlled PHYs
with the phylib-controlled PHYs where an adjust_link() callback is
supplied. In both cases, the MDIO bus PM ops should stop and restart the
PHY state machine.

[1] https://lore.kernel.org/netdev/Z-1tiW9zjcoFkhwc@shell.armlinux.org.uk/

Fixes: 744d23c71af3 ("net: phy: Warn about incorrect mdio_bus_phy_resume() state")
Reported-by: Wei Fang <wei.fang@nxp.com>
Tested-by: Wei Fang <wei.fang@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Link: https://patch.msgid.link/20250407094042.2155633-1-vladimir.oltean@nxp.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Rajani Kantha <681739313@139.com>
---
 drivers/net/phy/phy_device.c | 31 +++++++++++++++++++++++++++++--
 1 file changed, 29 insertions(+), 2 deletions(-)

diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 7d19857a6dc4..fd49616c6608 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -247,6 +247,33 @@ static void phy_link_change(struct phy_device *phydev, bool up)
 		phydev->mii_ts->link_state(phydev->mii_ts, phydev);
 }
 
+/**
+ * phy_uses_state_machine - test whether consumer driver uses PAL state machine
+ * @phydev: the target PHY device structure
+ *
+ * Ultimately, this aims to indirectly determine whether the PHY is attached
+ * to a consumer which uses the state machine by calling phy_start() and
+ * phy_stop().
+ *
+ * When the PHY driver consumer uses phylib, it must have previously called
+ * phy_connect_direct() or one of its derivatives, so that phy_prepare_link()
+ * has set up a hook for monitoring state changes.
+ *
+ * When the PHY driver is used by the MAC driver consumer through phylink (the
+ * only other provider of a phy_link_change() method), using the PHY state
+ * machine is not optional.
+ *
+ * Return: true if consumer calls phy_start() and phy_stop(), false otherwise.
+ */
+static bool phy_uses_state_machine(struct phy_device *phydev)
+{
+	if (phydev->phy_link_change == phy_link_change)
+		return phydev->attached_dev && phydev->adjust_link;
+
+	/* phydev->phy_link_change is implicitly phylink_phy_change() */
+	return true;
+}
+
 static bool mdio_bus_phy_may_suspend(struct phy_device *phydev)
 {
 	struct device_driver *drv = phydev->mdio.dev.driver;
@@ -307,7 +334,7 @@ static __maybe_unused int mdio_bus_phy_suspend(struct device *dev)
 	 * may call phy routines that try to grab the same lock, and that may
 	 * lead to a deadlock.
 	 */
-	if (phydev->attached_dev && phydev->adjust_link)
+	if (phy_uses_state_machine(phydev))
 		phy_stop_machine(phydev);
 
 	if (!mdio_bus_phy_may_suspend(phydev))
@@ -361,7 +388,7 @@ static __maybe_unused int mdio_bus_phy_resume(struct device *dev)
 		}
 	}
 
-	if (phydev->attached_dev && phydev->adjust_link)
+	if (phy_uses_state_machine(phydev))
 		phy_start_machine(phydev);
 
 	return 0;
-- 
2.34.1




^ permalink raw reply related

* [PATCH] ARM: dts: aspeed: g6: Add missing uart nodes
From: Jammy Huang @ 2026-03-27  1:58 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Joel Stanley,
	Andrew Jeffery
  Cc: devicetree, linux-arm-kernel, linux-aspeed, linux-kernel,
	Jammy Huang

Add nodes for uart10/11/12/13.

Signed-off-by: Jammy Huang <jammy_huang@aspeedtech.com>
---
 arch/arm/boot/dts/aspeed/aspeed-g6.dtsi | 56 +++++++++++++++++++++++++++++++++
 1 file changed, 56 insertions(+)

diff --git a/arch/arm/boot/dts/aspeed/aspeed-g6.dtsi b/arch/arm/boot/dts/aspeed/aspeed-g6.dtsi
index 189bc3bbb47..0ffe386fa9d 100644
--- a/arch/arm/boot/dts/aspeed/aspeed-g6.dtsi
+++ b/arch/arm/boot/dts/aspeed/aspeed-g6.dtsi
@@ -835,6 +835,62 @@ uart9: serial@1e790300 {
 				status = "disabled";
 			};
 
+			uart10: serial@1e790400 {
+				compatible = "ns16550a";
+				reg = <0x1e790400 0x20>;
+				reg-shift = <2>;
+				reg-io-width = <4>;
+				interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&syscon ASPEED_CLK_GATE_UART10CLK>;
+				no-loopback-test;
+				pinctrl-names = "default";
+				pinctrl-0 = <&pinctrl_uart10_default>;
+
+				status = "disabled";
+			};
+
+			uart11: serial@1e790500 {
+				compatible = "ns16550a";
+				reg = <0x1e790500 0x20>;
+				reg-shift = <2>;
+				reg-io-width = <4>;
+				interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&syscon ASPEED_CLK_GATE_UART11CLK>;
+				no-loopback-test;
+				pinctrl-names = "default";
+				pinctrl-0 = <&pinctrl_uart11_default>;
+
+				status = "disabled";
+			};
+
+			uart12: serial@1e790600 {
+				compatible = "ns16550a";
+				reg = <0x1e790600 0x20>;
+				reg-shift = <2>;
+				reg-io-width = <4>;
+				interrupts = <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&syscon ASPEED_CLK_GATE_UART12CLK>;
+				no-loopback-test;
+				pinctrl-names = "default";
+				pinctrl-0 = <&pinctrl_uart12g1_default>;
+
+				status = "disabled";
+			};
+
+			uart13: serial@1e790700 {
+				compatible = "ns16550a";
+				reg = <0x1e790700 0x20>;
+				reg-shift = <2>;
+				reg-io-width = <4>;
+				interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&syscon ASPEED_CLK_GATE_UART13CLK>;
+				no-loopback-test;
+				pinctrl-names = "default";
+				pinctrl-0 = <&pinctrl_uart13g1_default>;
+
+				status = "disabled";
+			};
+
 			i2c: bus@1e78a000 {
 				compatible = "simple-bus";
 				#address-cells = <1>;

---
base-commit: 5ee8dbf54602dc340d6235b1d6aa17c0f283f48c
change-id: 20260327-upstream_g6_dts_uart-78a5ce3b2873

Best regards,
-- 
Jammy Huang <jammy_huang@aspeedtech.com>



^ permalink raw reply related

* Re: [PATCH v1 00/10] devfreq: Fix NULL pointer dereference when a governor module is unloaded
From: Yaxiong Tian @ 2026-03-27  2:06 UTC (permalink / raw)
  To: Jie Zhan, cw00.choi, myungjoo.ham, kyungmin.park
  Cc: linux-pm, linux-arm-kernel, linuxarm, jonathan.cameron,
	zhenglifeng1, zhangpengjie2, lihuisong, prime.zeng
In-Reply-To: <1774576755240654.100.seg@mailgw.kylinos.cn>


在 2026/3/26 21:14, Jie Zhan 写道:
>
> On 3/26/2026 8:34 PM, Jie Zhan wrote:
>> When compiled as a kernel module, the governor module can be dynamically
>> inserted or removed.  'devfreq->governor' would become NULL if the governor
>> module is removed when it's in use, and NULL pointer dereference would be
>> triggered.  A similar issue was also reported in [1].
>>
>> To address this issue:
>>
>> Patch 1-5 rework mutex, factor out a common governor setting function, and
>> clean up some unreachable code.
>>
>> Patch 6-8 prevent a governor module in use from being removed (except for
>> force unload) by getting/putting a refcount of the governor's module when
>> switching governors.
>>
>> Patch 9-10 allow 'governor' and 'available_governors' to work normally even
>> when a governor module in use is force unloaded.
>>
>> Note that this series is based on [1] or devfreq-next, otherwise code

Sorry, please ignore the "remember to CC me on the patches." in my 
previous email.

  In my opinion, it would be better to prioritize the FIX first before 
proceeding with the lock mechanism optimizations and other work. This 
would make it easier to backport the patches to lower-version kernels. I 
noticed the patch is already in the devfreq-testing branch. I hope the 
FIX work can be moved forward smoothly to resolve the null pointer and 
other bugs. Thank you!



> sorry, based on [2] or devfreq-next
>> would conflict.
>>
>> [1] https://lore.kernel.org/all/20260319091409.998397-1-tianyaxiong@kylinos.cn/
>> [2] https://lore.kernel.org/all/20251216031153.2242306-1-zhangpengjie2@huawei.com/


^ permalink raw reply

* RE: [PATCH v3 net-next 02/14] dt-bindings: net: dsa: add NETC switch
From: Wei Fang @ 2026-03-27  2:09 UTC (permalink / raw)
  To: Frank Li
  Cc: Claudiu Manoil, Vladimir Oltean, Clark Wang,
	andrew+netdev@lunn.ch, davem@davemloft.net, edumazet@google.com,
	kuba@kernel.org, pabeni@redhat.com, robh@kernel.org,
	krzk+dt@kernel.org, conor+dt@kernel.org, f.fainelli@gmail.com,
	chleroy@kernel.org, horms@kernel.org, linux@armlinux.org.uk,
	andrew@lunn.ch, netdev@vger.kernel.org,
	linux-kernel@vger.kernel.org, devicetree@vger.kernel.org,
	linuxppc-dev@lists.ozlabs.org,
	linux-arm-kernel@lists.infradead.org, imx@lists.linux.dev
In-Reply-To: <acWR0QwRSnupmCvI@lizhi-Precision-Tower-5810>

> On Thu, Mar 26, 2026 at 02:29:05PM +0800, Wei Fang wrote:
> > Add bindings for NETC switch. This switch is a PCIe function of NETC
> > IP, it supports advanced QoS with 8 traffic classes and 4 drop
> > resilience levels, and a full range of  TSN standards capabilities.
> > The switch CPU
> 
> Nit: double space before TSN.

Thanks for catching this, I will fix it.

> 
> > port connects to an internal ENETC port, which is also a PCIe function
> > of NETC IP. So these two ports use a light-weight "pseudo MAC" instead
> > of a back-to-back MAC, because the "pseudo MAC" provides the
> > delineation between switch and ENETC, this translates to lower power
> > (less logic and
> 
> what's means "this translates", do you means "this help reduce power and
> latency."

This sentence is excerpted from the NETC Block Guide. It is equivalent to
"it means".

> 
> > memory) and lower delay (as there is no serialization delay across
> > this link).
> >
> > Signed-off-by: Wei Fang <wei.fang@nxp.com>
> > ---
> >  .../bindings/net/dsa/nxp,netc-switch.yaml     | 130 ++++++++++++++++++
> >  1 file changed, 130 insertions(+)
> >  create mode 100644
> > Documentation/devicetree/bindings/net/dsa/nxp,netc-switch.yaml
> >
> > diff --git
> > a/Documentation/devicetree/bindings/net/dsa/nxp,netc-switch.yaml
> > b/Documentation/devicetree/bindings/net/dsa/nxp,netc-switch.yaml
> > new file mode 100644
> > index 000000000000..e34a4e3504c3
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/net/dsa/nxp,netc-switch.yaml
> > @@ -0,0 +1,130 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) %YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/net/dsa/nxp,netc-switch.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: NETC Switch family
> > +
> > +description:
> 
> Nit use ">" for multi paragraph.

Okay, I suppose I also need to add '>' to the below description of
"dsa,member" property.

> 
> others look good
> 
> Reviewed-by: Frank Li <Frank.Li@nxp.com>
> 
> > +  The NETC presents itself as a multi-function PCIe Root Complex
> > + Integrated  Endpoint (RCiEP) and provides full 802.1Q Ethernet
> > + switch functionality,  advanced QoS with 8 traffic classes and 4
> > + drop resilience levels, and a  full range of TSN standards capabilities.
> > +
> > +  The CPU port of the switch connects to an internal ENETC. The
> > + switch and  the internal ENETC are fully integrated into the NETC
> > + IP, a back-to-back  MAC is not required. Instead, a light-weight
> > + "pseudo MAC" provides the  delineation between the switch and ENETC.
> > + This translates to lower power  (less logic and memory) and lower
> > + delay (as there is no serialization  delay across this link).
> > +
> > +maintainers:
> > +  - Wei Fang <wei.fang@nxp.com>
> > +
> > +properties:
> > +  compatible:
> > +    enum:
> > +      - pci1131,eef2
> > +
> > +  reg:
> > +    maxItems: 1
> > +
> > +  dsa,member:
> > +    description:
> > +      The property indicates DSA cluster and switch index. For NETC switch,
> > +      the valid range of the switch index is 1 ~ 7, the index is reflected
> > +      in the switch tag as an indication of the switch ID where the frame
> > +      originated. The value 0 is reserved for ENETC VEPA switch, whose ID
> > +      is hardwired to zero.
> > +
> > +$ref: dsa.yaml#
> > +
> > +patternProperties:
> > +  "^(ethernet-)?ports$":
> > +    type: object
> > +    additionalProperties: true
> > +    patternProperties:
> > +      "^(ethernet-)?port@[0-9a-f]$":
> > +        type: object
> > +
> > +        $ref: dsa-port.yaml#
> > +
> > +        properties:
> > +          clocks:
> > +            items:
> > +              - description: MAC transmit/receive reference clock.
> > +
> > +          clock-names:
> > +            items:
> > +              - const: ref
> > +
> > +          mdio:
> > +            $ref: /schemas/net/mdio.yaml#
> > +            unevaluatedProperties: false
> > +            description:
> > +              Optional child node for switch port, otherwise use NETC
> EMDIO.
> > +
> > +        unevaluatedProperties: false
> > +
> > +required:
> > +  - compatible
> > +  - reg
> > +  - dsa,member
> > +
> > +allOf:
> > +  - $ref: /schemas/pci/pci-device.yaml
> > +
> > +unevaluatedProperties: false
> > +
> > +examples:
> > +  - |
> > +    pcie {
> > +        #address-cells = <3>;
> > +        #size-cells = <2>;
> > +
> > +        ethernet-switch@0,2 {
> > +            compatible = "pci1131,eef2";
> > +            reg = <0x200 0 0 0 0>;
> > +            dsa,member = <0 1>;
> > +            pinctrl-names = "default";
> > +            pinctrl-0 = <&pinctrl_switch>;
> > +
> > +            ports {
> > +                #address-cells = <1>;
> > +                #size-cells = <0>;
> > +
> > +                port@0 {
> > +                    reg = <0>;
> > +                    phy-handle = <&ethphy0>;
> > +                    phy-mode = "mii";
> > +                };
> > +
> > +                port@1 {
> > +                    reg = <1>;
> > +                    phy-handle = <&ethphy1>;
> > +                    phy-mode = "mii";
> > +                };
> > +
> > +                port@2 {
> > +                    reg = <2>;
> > +                    clocks = <&scmi_clk 103>;
> > +                    clock-names = "ref";
> > +                    phy-handle = <&ethphy2>;
> > +                    phy-mode = "rgmii-id";
> > +                };
> > +
> > +                port@3 {
> > +                    reg = <3>;
> > +                    ethernet = <&enetc3>;
> > +                    phy-mode = "internal";
> > +
> > +                    fixed-link {
> > +                        speed = <2500>;
> > +                        full-duplex;
> > +                        pause;
> > +                    };
> > +                };
> > +            };
> > +        };
> > +    };
> > --
> > 2.34.1
> >


^ permalink raw reply

* Re: [PATCH net] net: ethernet: mtk_ppe: avoid NULL deref when gmac0 is disabled
From: patchwork-bot+netdevbpf @ 2026-03-27  2:10 UTC (permalink / raw)
  To: Sven Eckelmann
  Cc: nbd, lorenzo, andrew+netdev, davem, edumazet, kuba, pabeni,
	matthias.bgg, angelogioacchino.delregno, eladwf, netdev,
	linux-kernel, linux-arm-kernel, linux-mediatek, stable
In-Reply-To: <20260324-wed-crash-gmac0-disabled-v1-1-3bc388aee565@simonwunderlich.de>

Hello:

This patch was applied to netdev/net.git (main)
by Jakub Kicinski <kuba@kernel.org>:

On Tue, 24 Mar 2026 09:36:01 +0100 you wrote:
> If the gmac0 is disabled, the precheck for a valid ingress device will
> cause a NULL pointer deref and crash the system. This happens because
> eth->netdev[0] will be NULL but the code will directly try to access
> netdev_ops.
> 
> Instead of just checking for the first net_device, it must be checked if
> any of the mtk_eth net_devices is matching the netdev_ops of the ingress
> device.
> 
> [...]

Here is the summary with links:
  - [net] net: ethernet: mtk_ppe: avoid NULL deref when gmac0 is disabled
    https://git.kernel.org/netdev/net/c/976ff48c2ac6

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




^ permalink raw reply

* Re: [PATCH v12 2/7] qcom-tgu: Add TGU driver
From: Jie Gan @ 2026-03-27  2:16 UTC (permalink / raw)
  To: Songwei Chai, andersson, alexander.shishkin, mike.leach,
	konrad.dybcio, suzuki.poulose, james.clark, krzk+dt, conor+dt
  Cc: linux-kernel, linux-arm-kernel, linux-arm-msm, coresight,
	devicetree, gregkh
In-Reply-To: <20260317032639.2393221-3-songwei.chai@oss.qualcomm.com>



On 3/17/2026 11:26 AM, Songwei Chai wrote:
> Add driver to support device TGU (Trigger Generation Unit).
> TGU is a Data Engine which can be utilized to sense a plurality of
> signals and create a trigger into the CTI or generate interrupts to
> processors. Add probe/enable/disable functions for tgu.
> 
> Signed-off-by: Songwei Chai <songwei.chai@oss.qualcomm.com>
> ---
>   .../ABI/testing/sysfs-bus-amba-devices-tgu    |   9 +
>   drivers/Makefile                              |   1 +
>   drivers/hwtracing/Kconfig                     |   2 +
>   drivers/hwtracing/qcom/Kconfig                |  18 ++
>   drivers/hwtracing/qcom/Makefile               |   3 +
>   drivers/hwtracing/qcom/tgu.c                  | 183 ++++++++++++++++++
>   drivers/hwtracing/qcom/tgu.h                  |  51 +++++
>   7 files changed, 267 insertions(+)
>   create mode 100644 Documentation/ABI/testing/sysfs-bus-amba-devices-tgu
>   create mode 100644 drivers/hwtracing/qcom/Kconfig
>   create mode 100644 drivers/hwtracing/qcom/Makefile
>   create mode 100644 drivers/hwtracing/qcom/tgu.c
>   create mode 100644 drivers/hwtracing/qcom/tgu.h
> 
> diff --git a/Documentation/ABI/testing/sysfs-bus-amba-devices-tgu b/Documentation/ABI/testing/sysfs-bus-amba-devices-tgu
> new file mode 100644
> index 000000000000..ead237bb7d89
> --- /dev/null
> +++ b/Documentation/ABI/testing/sysfs-bus-amba-devices-tgu
> @@ -0,0 +1,9 @@
> +What:		/sys/bus/amba/devices/<tgu-name>/enable_tgu
> +Date:		March 2026
> +KernelVersion	7.1
> +Contact:	Jinlong Mao <jinlong.mao@oss.qualcomm.com>, Songwei Chai <songwei.chai@oss.qualcomm.com>
> +Description:
> +		(RW) Set/Get the enable/disable status of TGU
> +		Accepts only one of the 2 values -  0 or 1.
> +		0 : disable TGU.
> +		1 : enable TGU.
> diff --git a/drivers/Makefile b/drivers/Makefile
> index 53fbd2e0acdd..82b712a12a26 100644
> --- a/drivers/Makefile
> +++ b/drivers/Makefile
> @@ -177,6 +177,7 @@ obj-$(CONFIG_RAS)		+= ras/
>   obj-$(CONFIG_USB4)		+= thunderbolt/
>   obj-$(CONFIG_CORESIGHT)		+= hwtracing/coresight/
>   obj-y				+= hwtracing/intel_th/
> +obj-y				+= hwtracing/qcom/
>   obj-$(CONFIG_STM)		+= hwtracing/stm/
>   obj-$(CONFIG_HISI_PTT)		+= hwtracing/ptt/
>   obj-y				+= android/
> diff --git a/drivers/hwtracing/Kconfig b/drivers/hwtracing/Kconfig
> index 911ee977103c..8a640218eed8 100644
> --- a/drivers/hwtracing/Kconfig
> +++ b/drivers/hwtracing/Kconfig
> @@ -7,4 +7,6 @@ source "drivers/hwtracing/intel_th/Kconfig"
>   
>   source "drivers/hwtracing/ptt/Kconfig"
>   
> +source "drivers/hwtracing/qcom/Kconfig"
> +
>   endmenu
> diff --git a/drivers/hwtracing/qcom/Kconfig b/drivers/hwtracing/qcom/Kconfig
> new file mode 100644
> index 000000000000..d6f6d4b0f28e
> --- /dev/null
> +++ b/drivers/hwtracing/qcom/Kconfig
> @@ -0,0 +1,18 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +#
> +# QCOM specific hwtracing drivers
> +#
> +menu "Qualcomm specific hwtracing drivers"
> +
> +config QCOM_TGU
> +	tristate "QCOM Trigger Generation Unit driver"
> +	help
> +	  This driver provides support for Trigger Generation Unit that is
> +	  used to detect patterns or sequences on a given set of signals.
> +	  TGU is used to monitor a particular bus within a given region to
> +	  detect illegal transaction sequences or slave responses. It is also
> +	  used to monitor a data stream to detect protocol violations and to
> +	  provide a trigger point for centering data around a specific event
> +	  within the trace data buffer.
> +
> +endmenu
> diff --git a/drivers/hwtracing/qcom/Makefile b/drivers/hwtracing/qcom/Makefile
> new file mode 100644
> index 000000000000..5a0a868c1ea0
> --- /dev/null
> +++ b/drivers/hwtracing/qcom/Makefile
> @@ -0,0 +1,3 @@
> +# SPDX-License-Identifier: GPL-2.0
> +
> +obj-$(CONFIG_QCOM_TGU) += tgu.o
> diff --git a/drivers/hwtracing/qcom/tgu.c b/drivers/hwtracing/qcom/tgu.c
> new file mode 100644
> index 000000000000..58c19f12f3d7
> --- /dev/null
> +++ b/drivers/hwtracing/qcom/tgu.c
> @@ -0,0 +1,183 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
> + */
> +
> +#include <linux/amba/bus.h>
> +#include <linux/device.h>
> +#include <linux/err.h>
> +#include <linux/io.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/pm_runtime.h>
> +
> +#include "tgu.h"
> +
> +static void tgu_write_all_hw_regs(struct tgu_drvdata *drvdata)
> +{
> +	TGU_UNLOCK(drvdata->base);
> +	/* Enable TGU to program the triggers */
> +	writel(1, drvdata->base + TGU_CONTROL);
> +	TGU_LOCK(drvdata->base);
> +}
> +
> +static int tgu_enable(struct device *dev)
> +{
> +	struct tgu_drvdata *drvdata = dev_get_drvdata(dev);
> +
> +	guard(spinlock)(&drvdata->lock);
> +	if (drvdata->enabled)
> +		return -EBUSY;
> +
> +	tgu_write_all_hw_regs(drvdata);
> +	drvdata->enabled = true;
> +
> +	return 0;
> +}
> +
> +static void tgu_do_disable(struct tgu_drvdata *drvdata)
> +{
> +	TGU_UNLOCK(drvdata->base);
> +	writel(0, drvdata->base + TGU_CONTROL);
> +	TGU_LOCK(drvdata->base);
> +
> +	drvdata->enabled = false;
> +}
> +
> +static void tgu_disable(struct device *dev)
> +{
> +	struct tgu_drvdata *drvdata = dev_get_drvdata(dev);
> +
> +	guard(spinlock)(&drvdata->lock);
> +	if (!drvdata->enabled)
> +		return;
> +
> +	tgu_do_disable(drvdata);
> +}
> +
> +static ssize_t enable_tgu_show(struct device *dev,
> +			       struct device_attribute *attr, char *buf)
> +{
> +	struct tgu_drvdata *drvdata = dev_get_drvdata(dev);
> +	bool enabled;
> +
> +	guard(spinlock)(&drvdata->lock);
> +	enabled = drvdata->enabled;
> +
> +	return sysfs_emit(buf, "%d\n", !!enabled);
> +}
> +
> +/* enable_tgu_store - Configure Trace and Gating Unit (TGU) triggers. */
> +static ssize_t enable_tgu_store(struct device *dev,
> +				struct device_attribute *attr,
> +				const char *buf,
> +				size_t size)
> +{
> +	unsigned long val;
> +	int ret;
> +
> +	ret = kstrtoul(buf, 0, &val);
> +	if (ret || val > 1)
> +		return -EINVAL;
> +
> +	if (val) {
> +		ret = pm_runtime_resume_and_get(dev);
> +		if (ret)
> +			return ret;
> +		ret = tgu_enable(dev);
> +		if (ret) {
> +			pm_runtime_put(dev);
> +			return ret;
> +		}
> +	} else {
> +		tgu_disable(dev);
> +		pm_runtime_put(dev);

Sorry I didnt observe this issue with my previous check.

echo 0 to the disabled device will result in the pm_runtime reference 
number goes to negative. We dont need pm_runtime_put(dev) when we try to 
disable a diabled device.

Thanks,
Jie

> +	}
> +
> +	return size;
> +}
> +static DEVICE_ATTR_RW(enable_tgu);
> +
> +static struct attribute *tgu_common_attrs[] = {
> +	&dev_attr_enable_tgu.attr,
> +	NULL,
> +};
> +
> +static const struct attribute_group tgu_common_grp = {
> +	.attrs = tgu_common_attrs,
> +	NULL,
> +};
> +
> +static const struct attribute_group *tgu_attr_groups[] = {
> +	&tgu_common_grp,
> +	NULL,
> +};
> +
> +static int tgu_probe(struct amba_device *adev, const struct amba_id *id)
> +{
> +	struct device *dev = &adev->dev;
> +	struct tgu_drvdata *drvdata;
> +	int ret;
> +
> +	drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
> +	if (!drvdata)
> +		return -ENOMEM;
> +
> +	drvdata->dev = &adev->dev;
> +	dev_set_drvdata(dev, drvdata);
> +
> +	drvdata->base = devm_ioremap_resource(dev, &adev->res);
> +	if (IS_ERR(drvdata->base))
> +		return PTR_ERR(drvdata->base);
> +
> +	spin_lock_init(&drvdata->lock);
> +
> +	ret = sysfs_create_groups(&dev->kobj, tgu_attr_groups);
> +	if (ret) {
> +		dev_err(dev, "failed to create sysfs groups: %d\n", ret);
> +		return ret;
> +	}
> +
> +	drvdata->enabled = false;
> +
> +	pm_runtime_put(&adev->dev);
> +
> +	return 0;
> +}
> +
> +static void tgu_remove(struct amba_device *adev)
> +{
> +	struct device *dev = &adev->dev;
> +
> +	sysfs_remove_groups(&dev->kobj, tgu_attr_groups);
> +
> +	tgu_disable(dev);
> +}
> +
> +static const struct amba_id tgu_ids[] = {
> +	{
> +		.id = 0x000f0e00,
> +		.mask = 0x000fffff,
> +	},
> +	{ 0, 0, NULL },
> +};
> +
> +MODULE_DEVICE_TABLE(amba, tgu_ids);
> +
> +static struct amba_driver tgu_driver = {
> +	.drv = {
> +		.name = "qcom-tgu",
> +		.suppress_bind_attrs = true,
> +	},
> +	.probe = tgu_probe,
> +	.remove = tgu_remove,
> +	.id_table = tgu_ids,
> +};
> +
> +module_amba_driver(tgu_driver);
> +
> +MODULE_AUTHOR("Songwei Chai <songwei.chai@oss.qualcomm.com>");
> +MODULE_AUTHOR("Jinlong Mao <jinlong.mao@oss.qualcomm.com>");
> +MODULE_DESCRIPTION("Qualcomm Trigger Generation Unit driver");
> +MODULE_LICENSE("GPL");
> diff --git a/drivers/hwtracing/qcom/tgu.h b/drivers/hwtracing/qcom/tgu.h
> new file mode 100644
> index 000000000000..dd7533b9d735
> --- /dev/null
> +++ b/drivers/hwtracing/qcom/tgu.h
> @@ -0,0 +1,51 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
> + */
> +
> +#ifndef _QCOM_TGU_H
> +#define _QCOM_TGU_H
> +
> +/* Register addresses */
> +#define TGU_CONTROL		0x0000
> +#define TGU_LAR		0xfb0
> +#define TGU_UNLOCK_OFFSET	0xc5acce55
> +
> +static inline void TGU_LOCK(void __iomem *addr)
> +{
> +	do {
> +		/* Wait for things to settle */
> +		mb();
> +		writel_relaxed(0x0, addr + TGU_LAR);
> +	} while (0);
> +}
> +
> +static inline void TGU_UNLOCK(void __iomem *addr)
> +{
> +	do {
> +		writel_relaxed(TGU_UNLOCK_OFFSET, addr + TGU_LAR);
> +		/* Make sure everyone has seen this */
> +		mb();
> +	} while (0);
> +}
> +
> +/**
> + * struct tgu_drvdata - Data structure for a TGU (Trigger Generator Unit)
> + * @base: Memory-mapped base address of the TGU device
> + * @dev: Pointer to the associated device structure
> + * @lock: Spinlock for handling concurrent access to private data
> + * @enabled: Flag indicating whether the TGU device is enabled
> + *
> + * This structure defines the data associated with a TGU device,
> + * including its base address, device pointers, clock, spinlock for
> + * synchronization, trigger data pointers, maximum limits for various
> + * trigger-related parameters, and enable status.
> + */
> +struct tgu_drvdata {
> +	void __iomem *base;
> +	struct device *dev;
> +	spinlock_t lock;
> +	bool enabled;
> +};
> +
> +#endif



^ permalink raw reply

* Re: [PATCH v12 7/7] qcom-tgu: Add reset node to initialize
From: Jie Gan @ 2026-03-27  2:26 UTC (permalink / raw)
  To: Songwei Chai, andersson, alexander.shishkin, mike.leach,
	konrad.dybcio, suzuki.poulose, james.clark, krzk+dt, conor+dt
  Cc: linux-kernel, linux-arm-kernel, linux-arm-msm, coresight,
	devicetree, gregkh
In-Reply-To: <20260317032639.2393221-8-songwei.chai@oss.qualcomm.com>



On 3/17/2026 11:26 AM, Songwei Chai wrote:
> Add reset node to initialize the value of
> priority/condition_decode/condition_select/timer/counter nodes.
> 
> Signed-off-by: Songwei Chai <songwei.chai@oss.qualcomm.com>
> ---
>   .../ABI/testing/sysfs-bus-amba-devices-tgu    |  7 ++
>   drivers/hwtracing/qcom/tgu.c                  | 77 +++++++++++++++++++
>   2 files changed, 84 insertions(+)
> 
> diff --git a/Documentation/ABI/testing/sysfs-bus-amba-devices-tgu b/Documentation/ABI/testing/sysfs-bus-amba-devices-tgu
> index 5370882333bc..1dcb8fb71cd9 100644
> --- a/Documentation/ABI/testing/sysfs-bus-amba-devices-tgu
> +++ b/Documentation/ABI/testing/sysfs-bus-amba-devices-tgu
> @@ -42,3 +42,10 @@ KernelVersion	7.1
>   Contact:	Jinlong Mao <jinlong.mao@oss.qualcomm.com>, Songwei Chai <songwei.chai@oss.qualcomm.com>
>   Description:
>   		(RW) Set/Get the counter value with specific step for TGU.
> +
> +What:		/sys/bus/amba/devices/<tgu-name>/reset_tgu
> +Date:		March 2026
> +KernelVersion	7.1
> +Contact:	Jinlong Mao <jinlong.mao@oss.qualcomm.com>, Songwei Chai <songwei.chai@oss.qualcomm.com>
> +Description:
> +		(Write) Write 1 to reset the dataset for TGU.
> diff --git a/drivers/hwtracing/qcom/tgu.c b/drivers/hwtracing/qcom/tgu.c
> index 4539415571f6..e28e6d27cf56 100644
> --- a/drivers/hwtracing/qcom/tgu.c
> +++ b/drivers/hwtracing/qcom/tgu.c
> @@ -410,8 +410,85 @@ static ssize_t enable_tgu_store(struct device *dev,
>   }
>   static DEVICE_ATTR_RW(enable_tgu);
>   
> +/* reset_tgu_store - Reset Trace and Gating Unit (TGU) configuration. */
> +static ssize_t reset_tgu_store(struct device *dev,
> +			       struct device_attribute *attr, const char *buf,
> +			       size_t size)
> +{
> +	struct tgu_drvdata *drvdata = dev_get_drvdata(dev);
> +	struct value_table *vt = drvdata->value_table;
> +	u32 *cond_decode = drvdata->value_table->condition_decode;
> +	bool need_pm_put = false;
> +	unsigned long value;
> +	int i, j, ret;
> +
> +	if (kstrtoul(buf, 0, &value) || value != 1)
> +		return -EINVAL;
> +
> +	spin_lock(&drvdata->lock);
> +	if (!drvdata->enabled) {
> +		spin_unlock(&drvdata->lock);
> +		ret = pm_runtime_resume_and_get(drvdata->dev);
> +		if (ret)
> +			return ret;
> +		need_pm_put = true;
> +		spin_lock(&drvdata->lock);
> +	}
> +
> +	tgu_do_disable(drvdata);

need_pm_put flag is not set when reset a enabled device. I think we also 
need do pm_runtime_put after we did tgu_do_disable for an enabled device 
because we have pm_runtime_resume_and_get while enabling it.

Thanks,
Jie

> +
> +	if (vt->priority) {
> +		size_t size = MAX_PRIORITY * drvdata->num_step *
> +				drvdata->num_reg * sizeof(unsigned int);
> +		memset(vt->priority, 0, size);
> +	}
> +
> +	if (vt->condition_decode) {
> +		size_t size = drvdata->num_condition_decode *
> +			      drvdata->num_step * sizeof(unsigned int);
> +		memset(vt->condition_decode, 0, size);
> +	}
> +
> +	/* Initialize all condition registers to NOT(value=0x1000000) */
> +	for (i = 0; i < drvdata->num_step; i++) {
> +		for (j = 0; j < drvdata->num_condition_decode; j++) {
> +			cond_decode[calculate_array_location(drvdata, i,
> +			TGU_CONDITION_DECODE, j)] = 0x1000000;
> +		}
> +	}
> +
> +	if (vt->condition_select) {
> +		size_t size = drvdata->num_condition_select *
> +			      drvdata->num_step * sizeof(unsigned int);
> +		memset(vt->condition_select, 0, size);
> +	}
> +
> +	if (vt->timer) {
> +		size_t size = (drvdata->num_step) * (drvdata->num_timer) *
> +				sizeof(unsigned int);
> +		memset(vt->timer, 0, size);
> +	}
> +
> +	if (vt->counter) {
> +		size_t size = (drvdata->num_step) * (drvdata->num_counter) *
> +			      sizeof(unsigned int);
> +		memset(vt->counter, 0, size);
> +	}
> +
> +	spin_unlock(&drvdata->lock);
> +
> +	dev_dbg(dev, "Qualcomm-TGU reset complete\n");
> +
> +	if (need_pm_put)
> +		pm_runtime_put(drvdata->dev);
> +
> +	return size;
> +}
> +static DEVICE_ATTR_WO(reset_tgu);
> +
>   static struct attribute *tgu_common_attrs[] = {
>   	&dev_attr_enable_tgu.attr,
> +	&dev_attr_reset_tgu.attr,
>   	NULL,
>   };
>   



^ permalink raw reply


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